ALSA: hda - Fix missing EAPD for Acer 4930G
[linux-2.6-block.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
9ad0e496 31#include <sound/jack.h>
1da177e4
LT
32#include "hda_codec.h"
33#include "hda_local.h"
680cd536 34#include "hda_beep.h"
1da177e4 35
ccc656ce
KY
36#define ALC880_FRONT_EVENT 0x01
37#define ALC880_DCVOL_EVENT 0x02
38#define ALC880_HP_EVENT 0x04
39#define ALC880_MIC_EVENT 0x08
1da177e4
LT
40
41/* ALC880 board config type */
42enum {
1da177e4
LT
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
dfc0ff62 48 ALC880_Z71V,
b6482d48 49 ALC880_6ST,
16ded525
TI
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
df694daa 55 ALC880_ASUS_DIG2,
2cf9f0fc 56 ALC880_FUJITSU,
16ded525 57 ALC880_UNIWILL_DIG,
ccc656ce
KY
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
df694daa
KY
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
ae6b813a 62 ALC880_LG,
d681518a 63 ALC880_LG_LW,
df99cd33 64 ALC880_MEDION_RIM,
e9edcee0
TI
65#ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67#endif
df694daa 68 ALC880_AUTO,
16ded525
TI
69 ALC880_MODEL_LAST /* last tag */
70};
71
72/* ALC260 models */
73enum {
74 ALC260_BASIC,
75 ALC260_HP,
3f878308 76 ALC260_HP_DC7600,
df694daa
KY
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
0bfc90e9 79 ALC260_ACER,
bc9f98a9
KY
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
cc959489 82 ALC260_FAVORIT100,
7cf51e48
JW
83#ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85#endif
df694daa 86 ALC260_AUTO,
16ded525 87 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
88};
89
df694daa
KY
90/* ALC262 models */
91enum {
92 ALC262_BASIC,
ccc656ce
KY
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
834be88d 95 ALC262_FUJITSU,
9c7f852e 96 ALC262_HP_BPC,
cd7509a4
KY
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
66d2a9d6 99 ALC262_HP_TC_T5735,
8c427226 100 ALC262_HP_RP5700,
304dcaac 101 ALC262_BENQ_ED8,
272a527c 102 ALC262_SONY_ASSAMD,
83c34218 103 ALC262_BENQ_T31,
f651b50b 104 ALC262_ULTRA,
0e31daf7 105 ALC262_LENOVO_3000,
e8f9ae2a 106 ALC262_NEC,
4e555fe5 107 ALC262_TOSHIBA_S06,
9f99a638 108 ALC262_TOSHIBA_RX1,
ba340e82 109 ALC262_TYAN,
df694daa
KY
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
112};
113
a361d84b
KY
114/* ALC268 models */
115enum {
eb5a6621 116 ALC267_QUANTA_IL1,
a361d84b 117 ALC268_3ST,
d1a991a6 118 ALC268_TOSHIBA,
d273809e 119 ALC268_ACER,
c238b4f4 120 ALC268_ACER_DMIC,
8ef355da 121 ALC268_ACER_ASPIRE_ONE,
3866f0b0 122 ALC268_DELL,
f12462c5 123 ALC268_ZEPTO,
86c53bd2
JW
124#ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126#endif
a361d84b
KY
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
129};
130
f6a92248
KY
131/* ALC269 models */
132enum {
133 ALC269_BASIC,
60db6b53 134 ALC269_QUANTA_FL1,
84898e87
KY
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
26f5df26 139 ALC269_FUJITSU,
64154835 140 ALC269_LIFEBOOK,
fe3eb0a7 141 ALC271_ACER,
f6a92248
KY
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
144};
145
df694daa
KY
146/* ALC861 models */
147enum {
148 ALC861_3ST,
9c7f852e 149 ALC660_3ST,
df694daa
KY
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
22309c3e 152 ALC861_UNIWILL_M31,
a53d1aec 153 ALC861_TOSHIBA,
7cdbff94 154 ALC861_ASUS,
56bb0cab 155 ALC861_ASUS_LAPTOP,
df694daa
KY
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
158};
159
f32610ed
JS
160/* ALC861-VD models */
161enum {
162 ALC660VD_3ST,
6963f84c 163 ALC660VD_3ST_DIG,
13c94744 164 ALC660VD_ASUS_V1S,
f32610ed
JS
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
bdd148a3 168 ALC861VD_LENOVO,
272a527c 169 ALC861VD_DALLAS,
d1a991a6 170 ALC861VD_HP,
f32610ed
JS
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
173};
174
bc9f98a9
KY
175/* ALC662 models */
176enum {
177 ALC662_3ST_2ch_DIG,
178 ALC662_3ST_6ch_DIG,
179 ALC662_3ST_6ch,
180 ALC662_5ST_DIG,
181 ALC662_LENOVO_101E,
291702f0 182 ALC662_ASUS_EEEPC_P701,
8c427226 183 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
f1d4e28b
KY
188 ALC662_ECS,
189 ALC663_ASUS_MODE1,
190 ALC662_ASUS_MODE2,
191 ALC663_ASUS_MODE3,
192 ALC663_ASUS_MODE4,
193 ALC663_ASUS_MODE5,
194 ALC663_ASUS_MODE6,
ebb83eeb
KY
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
622e84cd
KY
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
9541ba1d 199 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
202};
203
df694daa
KY
204/* ALC882 models */
205enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
4b146cb0 208 ALC882_ARIMA,
bdd148a3 209 ALC882_W2JC,
272a527c
KY
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
914759b7 212 ALC882_ASUS_A7M,
9102cd1c 213 ALC885_MACPRO,
76e6f5a9 214 ALC885_MBA21,
87350ad0 215 ALC885_MBP3,
41d5545d 216 ALC885_MB5,
e458b1fa 217 ALC885_MACMINI3,
c54728d8 218 ALC885_IMAC24,
4b7e1803 219 ALC885_IMAC91,
9c7f852e
TI
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
ccc656ce
KY
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
64a8be74 226 ALC883_TARGA_8ch_DIG,
bab282b9 227 ALC883_ACER,
2880a867 228 ALC883_ACER_ASPIRE,
5b2d1eca 229 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 230 ALC888_ACER_ASPIRE_6530G,
3b315d70 231 ALC888_ACER_ASPIRE_8930G,
fc86f954 232 ALC888_ACER_ASPIRE_7730G,
c07584c8 233 ALC883_MEDION,
7ad7b218 234 ALC883_MEDION_WIM2160,
b373bdeb 235 ALC883_LAPTOP_EAPD,
bc9f98a9 236 ALC883_LENOVO_101E_2ch,
272a527c 237 ALC883_LENOVO_NB0763,
189609ae 238 ALC888_LENOVO_MS7195_DIG,
e2757d5e 239 ALC888_LENOVO_SKY,
ea1fb29a 240 ALC883_HAIER_W66,
4723c022 241 ALC888_3ST_HP,
5795b9e6 242 ALC888_6ST_DELL,
a8848bd6 243 ALC883_MITAC,
a65cc60f 244 ALC883_CLEVO_M540R,
0c4cc443 245 ALC883_CLEVO_M720,
fb97dc67 246 ALC883_FUJITSU_PI2515,
ef8ef5fb 247 ALC888_FUJITSU_XA3530,
17bba1b7 248 ALC883_3ST_6ch_INTEL,
87a8c370
JK
249 ALC889A_INTEL,
250 ALC889_INTEL,
e2757d5e
KY
251 ALC888_ASUS_M90V,
252 ALC888_ASUS_EEE1601,
eb4c41d3 253 ALC889A_MB31,
3ab90935 254 ALC1200_ASUS_P5Q,
3e1647c5 255 ALC883_SONY_VAIO_TT,
4953550a
TI
256 ALC882_AUTO,
257 ALC882_MODEL_LAST,
9c7f852e
TI
258};
259
d4a86d81
TI
260/* ALC680 models */
261enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
265};
266
df694daa
KY
267/* for GPIO Poll */
268#define GPIO_MASK 0x03
269
4a79ba34
TI
270/* extra amp-initialization sequence types */
271enum {
272 ALC_INIT_NONE,
273 ALC_INIT_DEFAULT,
274 ALC_INIT_GPIO1,
275 ALC_INIT_GPIO2,
276 ALC_INIT_GPIO3,
277};
278
6c819492
TI
279struct alc_mic_route {
280 hda_nid_t pin;
281 unsigned char mux_idx;
282 unsigned char amix_idx;
283};
284
9ad0e496
KY
285struct alc_jack {
286 hda_nid_t nid;
287 int type;
288 struct snd_jack *jack;
289};
290
6c819492
TI
291#define MUX_IDX_UNDEF ((unsigned char)-1)
292
da00c244
KY
293struct alc_customize_define {
294 unsigned int sku_cfg;
295 unsigned char port_connectivity;
296 unsigned char check_sum;
297 unsigned char customization;
298 unsigned char external_amp;
299 unsigned int enable_pcbeep:1;
300 unsigned int platform_type:1;
301 unsigned int swap:1;
302 unsigned int override:1;
90622917 303 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
da00c244
KY
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
90622917
DH
1467/* Could be any non-zero and even value. When used as fixup, tells
1468 * the driver to ignore any present sku defines.
1469 */
1470#define ALC_FIXUP_SKU_IGNORE (2)
1471
da00c244
KY
1472static int alc_auto_parse_customize_define(struct hda_codec *codec)
1473{
1474 unsigned int ass, tmp, i;
7fb56223 1475 unsigned nid = 0;
da00c244
KY
1476 struct alc_spec *spec = codec->spec;
1477
b6cbe517
TI
1478 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1479
90622917
DH
1480 if (spec->cdefine.fixup) {
1481 ass = spec->cdefine.sku_cfg;
1482 if (ass == ALC_FIXUP_SKU_IGNORE)
1483 return -1;
1484 goto do_sku;
1485 }
1486
da00c244 1487 ass = codec->subsystem_id & 0xffff;
b6cbe517 1488 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1489 goto do_sku;
1490
1491 nid = 0x1d;
1492 if (codec->vendor_id == 0x10ec0260)
1493 nid = 0x17;
1494 ass = snd_hda_codec_get_pincfg(codec, nid);
1495
1496 if (!(ass & 1)) {
1497 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1498 codec->chip_name, ass);
1499 return -1;
1500 }
1501
1502 /* check sum */
1503 tmp = 0;
1504 for (i = 1; i < 16; i++) {
1505 if ((ass >> i) & 1)
1506 tmp++;
1507 }
1508 if (((ass >> 16) & 0xf) != tmp)
1509 return -1;
1510
1511 spec->cdefine.port_connectivity = ass >> 30;
1512 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1513 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1514 spec->cdefine.customization = ass >> 8;
1515do_sku:
1516 spec->cdefine.sku_cfg = ass;
1517 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1518 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1519 spec->cdefine.swap = (ass & 0x2) >> 1;
1520 spec->cdefine.override = ass & 0x1;
1521
1522 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1523 nid, spec->cdefine.sku_cfg);
1524 snd_printd("SKU: port_connectivity=0x%x\n",
1525 spec->cdefine.port_connectivity);
1526 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1527 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1528 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1529 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1530 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1531 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1532 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1533
1534 return 0;
1535}
1536
4a79ba34
TI
1537/* check subsystem ID and set up device-specific initialization;
1538 * return 1 if initialized, 0 if invalid SSID
1539 */
1540/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1541 * 31 ~ 16 : Manufacture ID
1542 * 15 ~ 8 : SKU ID
1543 * 7 ~ 0 : Assembly ID
1544 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1545 */
1546static int alc_subsystem_id(struct hda_codec *codec,
1547 hda_nid_t porta, hda_nid_t porte,
6227cdce 1548 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1549{
1550 unsigned int ass, tmp, i;
1551 unsigned nid;
1552 struct alc_spec *spec = codec->spec;
1553
90622917
DH
1554 if (spec->cdefine.fixup) {
1555 ass = spec->cdefine.sku_cfg;
1556 if (ass == ALC_FIXUP_SKU_IGNORE)
1557 return 0;
1558 goto do_sku;
1559 }
1560
4a79ba34
TI
1561 ass = codec->subsystem_id & 0xffff;
1562 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1563 goto do_sku;
1564
1565 /* invalid SSID, check the special NID pin defcfg instead */
1566 /*
def319f9 1567 * 31~30 : port connectivity
4a79ba34
TI
1568 * 29~21 : reserve
1569 * 20 : PCBEEP input
1570 * 19~16 : Check sum (15:1)
1571 * 15~1 : Custom
1572 * 0 : override
1573 */
1574 nid = 0x1d;
1575 if (codec->vendor_id == 0x10ec0260)
1576 nid = 0x17;
1577 ass = snd_hda_codec_get_pincfg(codec, nid);
1578 snd_printd("realtek: No valid SSID, "
1579 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1580 ass, nid);
6227cdce 1581 if (!(ass & 1))
4a79ba34
TI
1582 return 0;
1583 if ((ass >> 30) != 1) /* no physical connection */
1584 return 0;
1585
1586 /* check sum */
1587 tmp = 0;
1588 for (i = 1; i < 16; i++) {
1589 if ((ass >> i) & 1)
1590 tmp++;
1591 }
1592 if (((ass >> 16) & 0xf) != tmp)
1593 return 0;
1594do_sku:
1595 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1596 ass & 0xffff, codec->vendor_id);
1597 /*
1598 * 0 : override
1599 * 1 : Swap Jack
1600 * 2 : 0 --> Desktop, 1 --> Laptop
1601 * 3~5 : External Amplifier control
1602 * 7~6 : Reserved
1603 */
1604 tmp = (ass & 0x38) >> 3; /* external Amp control */
1605 switch (tmp) {
1606 case 1:
1607 spec->init_amp = ALC_INIT_GPIO1;
1608 break;
1609 case 3:
1610 spec->init_amp = ALC_INIT_GPIO2;
1611 break;
1612 case 7:
1613 spec->init_amp = ALC_INIT_GPIO3;
1614 break;
1615 case 5:
5a8cfb4e 1616 default:
4a79ba34 1617 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1618 break;
1619 }
ea1fb29a 1620
8c427226 1621 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1622 * when the external headphone out jack is plugged"
1623 */
8c427226 1624 if (!(ass & 0x8000))
4a79ba34 1625 return 1;
c9b58006
KY
1626 /*
1627 * 10~8 : Jack location
1628 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1629 * 14~13: Resvered
1630 * 15 : 1 --> enable the function "Mute internal speaker
1631 * when the external headphone out jack is plugged"
1632 */
c9b58006 1633 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1634 hda_nid_t nid;
c9b58006
KY
1635 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1636 if (tmp == 0)
01d4825d 1637 nid = porta;
c9b58006 1638 else if (tmp == 1)
01d4825d 1639 nid = porte;
c9b58006 1640 else if (tmp == 2)
01d4825d 1641 nid = portd;
6227cdce
KY
1642 else if (tmp == 3)
1643 nid = porti;
c9b58006 1644 else
4a79ba34 1645 return 1;
01d4825d
TI
1646 for (i = 0; i < spec->autocfg.line_outs; i++)
1647 if (spec->autocfg.line_out_pins[i] == nid)
1648 return 1;
1649 spec->autocfg.hp_pins[0] = nid;
c9b58006
KY
1650 }
1651
4a79ba34 1652 alc_init_auto_hp(codec);
6c819492 1653 alc_init_auto_mic(codec);
4a79ba34
TI
1654 return 1;
1655}
ea1fb29a 1656
4a79ba34 1657static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1658 hda_nid_t porta, hda_nid_t porte,
1659 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1660{
6227cdce 1661 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1662 struct alc_spec *spec = codec->spec;
1663 snd_printd("realtek: "
1664 "Enable default setup for auto mode as fallback\n");
1665 spec->init_amp = ALC_INIT_DEFAULT;
1666 alc_init_auto_hp(codec);
6c819492 1667 alc_init_auto_mic(codec);
4a79ba34 1668 }
bc9f98a9
KY
1669}
1670
f95474ec 1671/*
f8f25ba3 1672 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1673 */
1674
1675struct alc_pincfg {
1676 hda_nid_t nid;
1677 u32 val;
1678};
1679
e1eb5f10
TB
1680struct alc_model_fixup {
1681 const int id;
1682 const char *name;
1683};
1684
f8f25ba3 1685struct alc_fixup {
90622917 1686 unsigned int sku;
f8f25ba3
TI
1687 const struct alc_pincfg *pins;
1688 const struct hda_verb *verbs;
9d57883f
TI
1689 void (*func)(struct hda_codec *codec, const struct alc_fixup *fix,
1690 int pre_init);
f8f25ba3
TI
1691};
1692
e1eb5f10
TB
1693static void __alc_pick_fixup(struct hda_codec *codec,
1694 const struct alc_fixup *fix,
1695 const char *modelname,
1696 int pre_init)
f95474ec
TI
1697{
1698 const struct alc_pincfg *cfg;
90622917 1699 struct alc_spec *spec;
f95474ec 1700
f8f25ba3 1701 cfg = fix->pins;
90622917
DH
1702 if (pre_init && fix->sku) {
1703#ifdef CONFIG_SND_DEBUG_VERBOSE
1704 snd_printdd(KERN_INFO "hda_codec: %s: Apply sku override for %s\n",
e1eb5f10 1705 codec->chip_name, modelname);
90622917
DH
1706#endif
1707 spec = codec->spec;
1708 spec->cdefine.sku_cfg = fix->sku;
1709 spec->cdefine.fixup = 1;
1710 }
7fa90e87
TI
1711 if (pre_init && cfg) {
1712#ifdef CONFIG_SND_DEBUG_VERBOSE
1713 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
e1eb5f10 1714 codec->chip_name, modelname);
7fa90e87 1715#endif
f8f25ba3
TI
1716 for (; cfg->nid; cfg++)
1717 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1718 }
7fa90e87
TI
1719 if (!pre_init && fix->verbs) {
1720#ifdef CONFIG_SND_DEBUG_VERBOSE
1721 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
e1eb5f10 1722 codec->chip_name, modelname);
7fa90e87 1723#endif
f8f25ba3 1724 add_verb(codec->spec, fix->verbs);
7fa90e87 1725 }
9d57883f
TI
1726 if (fix->func) {
1727#ifdef CONFIG_SND_DEBUG_VERBOSE
1728 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-func for %s\n",
e1eb5f10 1729 codec->chip_name, modelname);
9d57883f
TI
1730#endif
1731 fix->func(codec, fix, pre_init);
1732 }
f95474ec
TI
1733}
1734
e1eb5f10
TB
1735static void alc_pick_fixup(struct hda_codec *codec,
1736 const struct snd_pci_quirk *quirk,
1737 const struct alc_fixup *fix,
1738 int pre_init)
1739{
1740 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1741 if (quirk) {
1742 fix += quirk->value;
1743#ifdef CONFIG_SND_DEBUG_VERBOSE
1744 __alc_pick_fixup(codec, fix, quirk->name, pre_init);
1745#else
1746 __alc_pick_fixup(codec, fix, NULL, pre_init);
1747#endif
1748 }
1749}
1750
1751static void alc_pick_fixup_model(struct hda_codec *codec,
1752 const struct alc_model_fixup *models,
1753 const struct snd_pci_quirk *quirk,
1754 const struct alc_fixup *fix,
1755 int pre_init)
1756{
1757 if (codec->modelname && models) {
1758 while (models->name) {
1759 if (!strcmp(codec->modelname, models->name)) {
1760 fix += models->id;
1761 break;
1762 }
1763 models++;
1764 }
1765 __alc_pick_fixup(codec, fix, codec->modelname, pre_init);
1766 } else {
1767 alc_pick_fixup(codec, quirk, fix, pre_init);
1768 }
1769}
1770
274693f3
KY
1771static int alc_read_coef_idx(struct hda_codec *codec,
1772 unsigned int coef_idx)
1773{
1774 unsigned int val;
1775 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1776 coef_idx);
1777 val = snd_hda_codec_read(codec, 0x20, 0,
1778 AC_VERB_GET_PROC_COEF, 0);
1779 return val;
1780}
1781
977ddd6b
KY
1782static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
1783 unsigned int coef_val)
1784{
1785 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1786 coef_idx);
1787 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
1788 coef_val);
1789}
1790
757899ac
TI
1791/* set right pin controls for digital I/O */
1792static void alc_auto_init_digital(struct hda_codec *codec)
1793{
1794 struct alc_spec *spec = codec->spec;
1795 int i;
1796 hda_nid_t pin;
1797
1798 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1799 pin = spec->autocfg.dig_out_pins[i];
1800 if (pin) {
1801 snd_hda_codec_write(codec, pin, 0,
1802 AC_VERB_SET_PIN_WIDGET_CONTROL,
1803 PIN_OUT);
1804 }
1805 }
1806 pin = spec->autocfg.dig_in_pin;
1807 if (pin)
1808 snd_hda_codec_write(codec, pin, 0,
1809 AC_VERB_SET_PIN_WIDGET_CONTROL,
1810 PIN_IN);
1811}
1812
1813/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1814static void alc_auto_parse_digital(struct hda_codec *codec)
1815{
1816 struct alc_spec *spec = codec->spec;
1817 int i, err;
1818 hda_nid_t dig_nid;
1819
1820 /* support multiple SPDIFs; the secondary is set up as a slave */
1821 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1822 err = snd_hda_get_connections(codec,
1823 spec->autocfg.dig_out_pins[i],
1824 &dig_nid, 1);
1825 if (err < 0)
1826 continue;
1827 if (!i) {
1828 spec->multiout.dig_out_nid = dig_nid;
1829 spec->dig_out_type = spec->autocfg.dig_out_type[0];
1830 } else {
1831 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1832 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1833 break;
1834 spec->slave_dig_outs[i - 1] = dig_nid;
1835 }
1836 }
1837
1838 if (spec->autocfg.dig_in_pin) {
01fdf180
TI
1839 dig_nid = codec->start_nid;
1840 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
1841 unsigned int wcaps = get_wcaps(codec, dig_nid);
1842 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
1843 continue;
1844 if (!(wcaps & AC_WCAP_DIGITAL))
1845 continue;
1846 if (!(wcaps & AC_WCAP_CONN_LIST))
1847 continue;
1848 err = get_connection_index(codec, dig_nid,
1849 spec->autocfg.dig_in_pin);
1850 if (err >= 0) {
1851 spec->dig_in_nid = dig_nid;
1852 break;
1853 }
1854 }
757899ac
TI
1855 }
1856}
1857
ef8ef5fb
VP
1858/*
1859 * ALC888
1860 */
1861
1862/*
1863 * 2ch mode
1864 */
1865static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1866/* Mic-in jack as mic in */
1867 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1868 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1869/* Line-in jack as Line in */
1870 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1871 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1872/* Line-Out as Front */
1873 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1874 { } /* end */
1875};
1876
1877/*
1878 * 4ch mode
1879 */
1880static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1881/* Mic-in jack as mic in */
1882 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1883 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1884/* Line-in jack as Surround */
1885 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1886 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1887/* Line-Out as Front */
1888 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1889 { } /* end */
1890};
1891
1892/*
1893 * 6ch mode
1894 */
1895static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1896/* Mic-in jack as CLFE */
1897 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1898 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1899/* Line-in jack as Surround */
1900 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1901 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1902/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1903 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1904 { } /* end */
1905};
1906
1907/*
1908 * 8ch mode
1909 */
1910static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1911/* Mic-in jack as CLFE */
1912 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1913 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1914/* Line-in jack as Surround */
1915 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1916 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1917/* Line-Out as Side */
1918 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1919 { } /* end */
1920};
1921
1922static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1923 { 2, alc888_4ST_ch2_intel_init },
1924 { 4, alc888_4ST_ch4_intel_init },
1925 { 6, alc888_4ST_ch6_intel_init },
1926 { 8, alc888_4ST_ch8_intel_init },
1927};
1928
1929/*
1930 * ALC888 Fujitsu Siemens Amillo xa3530
1931 */
1932
1933static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1934/* Front Mic: set to PIN_IN (empty by default) */
1935 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1936/* Connect Internal HP to Front */
1937 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1938 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1939 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1940/* Connect Bass HP to Front */
1941 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1942 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1943 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1944/* Connect Line-Out side jack (SPDIF) to Side */
1945 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1946 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1947 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1948/* Connect Mic jack to CLFE */
1949 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1950 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1951 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1952/* Connect Line-in jack to Surround */
1953 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1954 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1955 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1956/* Connect HP out jack to Front */
1957 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1958 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1959 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1960/* Enable unsolicited event for HP jack and Line-out jack */
1961 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1962 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1963 {}
1964};
1965
a9fd4f3f 1966static void alc_automute_amp(struct hda_codec *codec)
ef8ef5fb 1967{
bb35febd 1968 alc_automute_speaker(codec, 0);
ef8ef5fb
VP
1969}
1970
a9fd4f3f
TI
1971static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1972 unsigned int res)
ef8ef5fb 1973{
a9fd4f3f
TI
1974 if (codec->vendor_id == 0x10ec0880)
1975 res >>= 28;
1976 else
1977 res >>= 26;
1978 if (res == ALC880_HP_EVENT)
1979 alc_automute_amp(codec);
ef8ef5fb
VP
1980}
1981
4f5d1706 1982static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
1983{
1984 struct alc_spec *spec = codec->spec;
1985
1986 spec->autocfg.hp_pins[0] = 0x15;
1987 spec->autocfg.speaker_pins[0] = 0x14;
1988 spec->autocfg.speaker_pins[1] = 0x16;
1989 spec->autocfg.speaker_pins[2] = 0x17;
1990 spec->autocfg.speaker_pins[3] = 0x19;
1991 spec->autocfg.speaker_pins[4] = 0x1a;
6732bd0d
WF
1992}
1993
1994static void alc889_intel_init_hook(struct hda_codec *codec)
1995{
1996 alc889_coef_init(codec);
4f5d1706 1997 alc_automute_amp(codec);
6732bd0d
WF
1998}
1999
4f5d1706 2000static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
2001{
2002 struct alc_spec *spec = codec->spec;
2003
2004 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2005 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2006 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2007 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
a9fd4f3f 2008}
ef8ef5fb 2009
5b2d1eca
VP
2010/*
2011 * ALC888 Acer Aspire 4930G model
2012 */
2013
2014static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2015/* Front Mic: set to PIN_IN (empty by default) */
2016 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2017/* Unselect Front Mic by default in input mixer 3 */
2018 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 2019/* Enable unsolicited event for HP jack */
5b2d1eca
VP
2020 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2021/* Connect Internal HP to front */
2022 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2023 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2024 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2025/* Connect HP out to front */
2026 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2027 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2028 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
e2e93296 2029 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
5b2d1eca
VP
2030 { }
2031};
2032
d2fd4b09
TV
2033/*
2034 * ALC888 Acer Aspire 6530G model
2035 */
2036
2037static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
2038/* Route to built-in subwoofer as well as speakers */
2039 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2040 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2041 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2042 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
2043/* Bias voltage on for external mic port */
2044 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
2045/* Front Mic: set to PIN_IN (empty by default) */
2046 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2047/* Unselect Front Mic by default in input mixer 3 */
2048 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
2049/* Enable unsolicited event for HP jack */
2050 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2051/* Enable speaker output */
2052 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2053 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 2054 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2055/* Enable headphone output */
2056 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2057 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2058 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 2059 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2060 { }
2061};
2062
d9477207
DK
2063/*
2064 *ALC888 Acer Aspire 7730G model
2065 */
2066
2067static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2068/* Bias voltage on for external mic port */
2069 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2070/* Front Mic: set to PIN_IN (empty by default) */
2071 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2072/* Unselect Front Mic by default in input mixer 3 */
2073 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2074/* Enable unsolicited event for HP jack */
2075 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2076/* Enable speaker output */
2077 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2078 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2079 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2080/* Enable headphone output */
2081 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2082 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2083 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2084 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2085/*Enable internal subwoofer */
2086 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2087 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2088 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2089 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2090 { }
2091};
2092
3b315d70 2093/*
018df418 2094 * ALC889 Acer Aspire 8930G model
3b315d70
HM
2095 */
2096
018df418 2097static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
2098/* Front Mic: set to PIN_IN (empty by default) */
2099 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2100/* Unselect Front Mic by default in input mixer 3 */
2101 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2102/* Enable unsolicited event for HP jack */
2103 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2104/* Connect Internal Front to Front */
2105 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2106 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2107 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2108/* Connect Internal Rear to Rear */
2109 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2110 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2111 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2112/* Connect Internal CLFE to CLFE */
2113 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2114 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2115 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2116/* Connect HP out to Front */
018df418 2117 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
2118 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2119 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2120/* Enable all DACs */
2121/* DAC DISABLE/MUTE 1? */
2122/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2123 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2124 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2125/* DAC DISABLE/MUTE 2? */
2126/* some bit here disables the other DACs. Init=0x4900 */
2127 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2128 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
2129/* DMIC fix
2130 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2131 * which makes the stereo useless. However, either the mic or the ALC889
2132 * makes the signal become a difference/sum signal instead of standard
2133 * stereo, which is annoying. So instead we flip this bit which makes the
2134 * codec replicate the sum signal to both channels, turning it into a
2135 * normal mono mic.
2136 */
2137/* DMIC_CONTROL? Init value = 0x0001 */
2138 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2139 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
2140 { }
2141};
2142
ef8ef5fb 2143static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
2144 /* Front mic only available on one ADC */
2145 {
2146 .num_items = 4,
2147 .items = {
2148 { "Mic", 0x0 },
2149 { "Line", 0x2 },
2150 { "CD", 0x4 },
2151 { "Front Mic", 0xb },
2152 },
2153 },
2154 {
2155 .num_items = 3,
2156 .items = {
2157 { "Mic", 0x0 },
2158 { "Line", 0x2 },
2159 { "CD", 0x4 },
2160 },
2161 }
2162};
2163
d2fd4b09
TV
2164static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2165 /* Interal mic only available on one ADC */
2166 {
684a8842 2167 .num_items = 5,
d2fd4b09 2168 .items = {
8607f7c4 2169 { "Mic", 0x0 },
684a8842 2170 { "Line In", 0x2 },
d2fd4b09 2171 { "CD", 0x4 },
684a8842 2172 { "Input Mix", 0xa },
28c4edb7 2173 { "Internal Mic", 0xb },
d2fd4b09
TV
2174 },
2175 },
2176 {
684a8842 2177 .num_items = 4,
d2fd4b09 2178 .items = {
8607f7c4 2179 { "Mic", 0x0 },
684a8842 2180 { "Line In", 0x2 },
d2fd4b09 2181 { "CD", 0x4 },
684a8842 2182 { "Input Mix", 0xa },
d2fd4b09
TV
2183 },
2184 }
2185};
2186
018df418
HM
2187static struct hda_input_mux alc889_capture_sources[3] = {
2188 /* Digital mic only available on first "ADC" */
2189 {
2190 .num_items = 5,
2191 .items = {
2192 { "Mic", 0x0 },
2193 { "Line", 0x2 },
2194 { "CD", 0x4 },
2195 { "Front Mic", 0xb },
2196 { "Input Mix", 0xa },
2197 },
2198 },
2199 {
2200 .num_items = 4,
2201 .items = {
2202 { "Mic", 0x0 },
2203 { "Line", 0x2 },
2204 { "CD", 0x4 },
2205 { "Input Mix", 0xa },
2206 },
2207 },
2208 {
2209 .num_items = 4,
2210 .items = {
2211 { "Mic", 0x0 },
2212 { "Line", 0x2 },
2213 { "CD", 0x4 },
2214 { "Input Mix", 0xa },
2215 },
2216 }
2217};
2218
ef8ef5fb 2219static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
2220 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2221 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2222 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2223 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2224 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2225 HDA_OUTPUT),
2226 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2227 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2228 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2229 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2230 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2231 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2232 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2233 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2234 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2235 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2236 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
5b2d1eca 2237 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
2238 { } /* end */
2239};
2240
556eea9a
HM
2241static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2242 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2243 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2244 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2245 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2246 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2247 HDA_OUTPUT),
2248 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2249 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2250 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2251 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2252 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2253 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2254 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
556eea9a
HM
2255 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2256 { } /* end */
2257};
2258
2259
4f5d1706 2260static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2261{
a9fd4f3f 2262 struct alc_spec *spec = codec->spec;
5b2d1eca 2263
a9fd4f3f
TI
2264 spec->autocfg.hp_pins[0] = 0x15;
2265 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2266 spec->autocfg.speaker_pins[1] = 0x16;
2267 spec->autocfg.speaker_pins[2] = 0x17;
5b2d1eca
VP
2268}
2269
4f5d1706 2270static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2271{
2272 struct alc_spec *spec = codec->spec;
2273
2274 spec->autocfg.hp_pins[0] = 0x15;
2275 spec->autocfg.speaker_pins[0] = 0x14;
2276 spec->autocfg.speaker_pins[1] = 0x16;
2277 spec->autocfg.speaker_pins[2] = 0x17;
320d5920
EL
2278}
2279
d9477207
DK
2280static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2281{
2282 struct alc_spec *spec = codec->spec;
2283
2284 spec->autocfg.hp_pins[0] = 0x15;
2285 spec->autocfg.speaker_pins[0] = 0x14;
2286 spec->autocfg.speaker_pins[1] = 0x16;
2287 spec->autocfg.speaker_pins[2] = 0x17;
2288}
2289
4f5d1706 2290static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2291{
2292 struct alc_spec *spec = codec->spec;
2293
2294 spec->autocfg.hp_pins[0] = 0x15;
2295 spec->autocfg.speaker_pins[0] = 0x14;
2296 spec->autocfg.speaker_pins[1] = 0x16;
2297 spec->autocfg.speaker_pins[2] = 0x1b;
3b315d70
HM
2298}
2299
1da177e4 2300/*
e9edcee0
TI
2301 * ALC880 3-stack model
2302 *
2303 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2304 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2305 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2306 */
2307
e9edcee0
TI
2308static hda_nid_t alc880_dac_nids[4] = {
2309 /* front, rear, clfe, rear_surr */
2310 0x02, 0x05, 0x04, 0x03
2311};
2312
2313static hda_nid_t alc880_adc_nids[3] = {
2314 /* ADC0-2 */
2315 0x07, 0x08, 0x09,
2316};
2317
2318/* The datasheet says the node 0x07 is connected from inputs,
2319 * but it shows zero connection in the real implementation on some devices.
df694daa 2320 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2321 */
e9edcee0
TI
2322static hda_nid_t alc880_adc_nids_alt[2] = {
2323 /* ADC1-2 */
2324 0x08, 0x09,
2325};
2326
2327#define ALC880_DIGOUT_NID 0x06
2328#define ALC880_DIGIN_NID 0x0a
2329
2330static struct hda_input_mux alc880_capture_source = {
2331 .num_items = 4,
2332 .items = {
2333 { "Mic", 0x0 },
2334 { "Front Mic", 0x3 },
2335 { "Line", 0x2 },
2336 { "CD", 0x4 },
2337 },
2338};
2339
2340/* channel source setting (2/6 channel selection for 3-stack) */
2341/* 2ch mode */
2342static struct hda_verb alc880_threestack_ch2_init[] = {
2343 /* set line-in to input, mute it */
2344 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2345 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2346 /* set mic-in to input vref 80%, mute it */
2347 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2348 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2349 { } /* end */
2350};
2351
2352/* 6ch mode */
2353static struct hda_verb alc880_threestack_ch6_init[] = {
2354 /* set line-in to output, unmute it */
2355 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2356 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2357 /* set mic-in to output, unmute it */
2358 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2359 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2360 { } /* end */
2361};
2362
d2a6d7dc 2363static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2364 { 2, alc880_threestack_ch2_init },
2365 { 6, alc880_threestack_ch6_init },
2366};
2367
c8b6bf9b 2368static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2369 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2370 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2371 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2372 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2373 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2374 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2375 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2376 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2377 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2378 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2379 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2380 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2381 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2382 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2383 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2384 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2385 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2386 {
2387 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2388 .name = "Channel Mode",
df694daa
KY
2389 .info = alc_ch_mode_info,
2390 .get = alc_ch_mode_get,
2391 .put = alc_ch_mode_put,
e9edcee0
TI
2392 },
2393 { } /* end */
2394};
2395
2396/* capture mixer elements */
f9e336f6
TI
2397static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2398 struct snd_ctl_elem_info *uinfo)
2399{
2400 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2401 struct alc_spec *spec = codec->spec;
2402 int err;
1da177e4 2403
5a9e02e9 2404 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2405 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2406 HDA_INPUT);
2407 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2408 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2409 return err;
2410}
2411
2412static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2413 unsigned int size, unsigned int __user *tlv)
2414{
2415 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2416 struct alc_spec *spec = codec->spec;
2417 int err;
1da177e4 2418
5a9e02e9 2419 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2420 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2421 HDA_INPUT);
2422 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2423 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2424 return err;
2425}
2426
2427typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2428 struct snd_ctl_elem_value *ucontrol);
2429
2430static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2431 struct snd_ctl_elem_value *ucontrol,
2432 getput_call_t func)
2433{
2434 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2435 struct alc_spec *spec = codec->spec;
2436 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2437 int err;
2438
5a9e02e9 2439 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2440 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2441 3, 0, HDA_INPUT);
2442 err = func(kcontrol, ucontrol);
5a9e02e9 2443 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2444 return err;
2445}
2446
2447static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2448 struct snd_ctl_elem_value *ucontrol)
2449{
2450 return alc_cap_getput_caller(kcontrol, ucontrol,
2451 snd_hda_mixer_amp_volume_get);
2452}
2453
2454static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2455 struct snd_ctl_elem_value *ucontrol)
2456{
2457 return alc_cap_getput_caller(kcontrol, ucontrol,
2458 snd_hda_mixer_amp_volume_put);
2459}
2460
2461/* capture mixer elements */
2462#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2463
2464static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2465 struct snd_ctl_elem_value *ucontrol)
2466{
2467 return alc_cap_getput_caller(kcontrol, ucontrol,
2468 snd_hda_mixer_amp_switch_get);
2469}
2470
2471static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2472 struct snd_ctl_elem_value *ucontrol)
2473{
2474 return alc_cap_getput_caller(kcontrol, ucontrol,
2475 snd_hda_mixer_amp_switch_put);
2476}
2477
a23b688f 2478#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2479 { \
2480 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2481 .name = "Capture Switch", \
2482 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2483 .count = num, \
2484 .info = alc_cap_sw_info, \
2485 .get = alc_cap_sw_get, \
2486 .put = alc_cap_sw_put, \
2487 }, \
2488 { \
2489 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2490 .name = "Capture Volume", \
2491 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2492 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2493 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2494 .count = num, \
2495 .info = alc_cap_vol_info, \
2496 .get = alc_cap_vol_get, \
2497 .put = alc_cap_vol_put, \
2498 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2499 }
2500
2501#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2502 { \
2503 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2504 /* .name = "Capture Source", */ \
2505 .name = "Input Source", \
2506 .count = num, \
2507 .info = alc_mux_enum_info, \
2508 .get = alc_mux_enum_get, \
2509 .put = alc_mux_enum_put, \
a23b688f
TI
2510 }
2511
2512#define DEFINE_CAPMIX(num) \
2513static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2514 _DEFINE_CAPMIX(num), \
2515 _DEFINE_CAPSRC(num), \
2516 { } /* end */ \
2517}
2518
2519#define DEFINE_CAPMIX_NOSRC(num) \
2520static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2521 _DEFINE_CAPMIX(num), \
2522 { } /* end */ \
f9e336f6
TI
2523}
2524
2525/* up to three ADCs */
2526DEFINE_CAPMIX(1);
2527DEFINE_CAPMIX(2);
2528DEFINE_CAPMIX(3);
a23b688f
TI
2529DEFINE_CAPMIX_NOSRC(1);
2530DEFINE_CAPMIX_NOSRC(2);
2531DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2532
2533/*
2534 * ALC880 5-stack model
2535 *
9c7f852e
TI
2536 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2537 * Side = 0x02 (0xd)
e9edcee0
TI
2538 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2539 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2540 */
2541
2542/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 2543static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2544 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2545 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2546 { } /* end */
2547};
2548
e9edcee0
TI
2549/* channel source setting (6/8 channel selection for 5-stack) */
2550/* 6ch mode */
2551static struct hda_verb alc880_fivestack_ch6_init[] = {
2552 /* set line-in to input, mute it */
2553 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2554 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2555 { } /* end */
2556};
2557
e9edcee0
TI
2558/* 8ch mode */
2559static struct hda_verb alc880_fivestack_ch8_init[] = {
2560 /* set line-in to output, unmute it */
2561 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2562 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2563 { } /* end */
2564};
2565
d2a6d7dc 2566static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2567 { 6, alc880_fivestack_ch6_init },
2568 { 8, alc880_fivestack_ch8_init },
2569};
2570
2571
2572/*
2573 * ALC880 6-stack model
2574 *
9c7f852e
TI
2575 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2576 * Side = 0x05 (0x0f)
e9edcee0
TI
2577 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2578 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2579 */
2580
2581static hda_nid_t alc880_6st_dac_nids[4] = {
2582 /* front, rear, clfe, rear_surr */
2583 0x02, 0x03, 0x04, 0x05
f12ab1e0 2584};
e9edcee0
TI
2585
2586static struct hda_input_mux alc880_6stack_capture_source = {
2587 .num_items = 4,
2588 .items = {
2589 { "Mic", 0x0 },
2590 { "Front Mic", 0x1 },
2591 { "Line", 0x2 },
2592 { "CD", 0x4 },
2593 },
2594};
2595
2596/* fixed 8-channels */
d2a6d7dc 2597static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2598 { 8, NULL },
2599};
2600
c8b6bf9b 2601static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2602 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2603 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2604 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2605 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2606 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2607 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2608 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2609 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2610 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2611 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2612 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2613 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2614 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2615 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2616 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2617 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2618 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2619 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2620 {
2621 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2622 .name = "Channel Mode",
df694daa
KY
2623 .info = alc_ch_mode_info,
2624 .get = alc_ch_mode_get,
2625 .put = alc_ch_mode_put,
16ded525
TI
2626 },
2627 { } /* end */
2628};
2629
e9edcee0
TI
2630
2631/*
2632 * ALC880 W810 model
2633 *
2634 * W810 has rear IO for:
2635 * Front (DAC 02)
2636 * Surround (DAC 03)
2637 * Center/LFE (DAC 04)
2638 * Digital out (06)
2639 *
2640 * The system also has a pair of internal speakers, and a headphone jack.
2641 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2642 *
e9edcee0
TI
2643 * There is a variable resistor to control the speaker or headphone
2644 * volume. This is a hardware-only device without a software API.
2645 *
2646 * Plugging headphones in will disable the internal speakers. This is
2647 * implemented in hardware, not via the driver using jack sense. In
2648 * a similar fashion, plugging into the rear socket marked "front" will
2649 * disable both the speakers and headphones.
2650 *
2651 * For input, there's a microphone jack, and an "audio in" jack.
2652 * These may not do anything useful with this driver yet, because I
2653 * haven't setup any initialization verbs for these yet...
2654 */
2655
2656static hda_nid_t alc880_w810_dac_nids[3] = {
2657 /* front, rear/surround, clfe */
2658 0x02, 0x03, 0x04
16ded525
TI
2659};
2660
e9edcee0 2661/* fixed 6 channels */
d2a6d7dc 2662static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2663 { 6, NULL }
2664};
2665
2666/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 2667static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2668 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2669 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2670 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2671 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2672 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2673 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2674 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2675 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2676 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2677 { } /* end */
2678};
2679
2680
2681/*
2682 * Z710V model
2683 *
2684 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2685 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2686 * Line = 0x1a
e9edcee0
TI
2687 */
2688
2689static hda_nid_t alc880_z71v_dac_nids[1] = {
2690 0x02
2691};
2692#define ALC880_Z71V_HP_DAC 0x03
2693
2694/* fixed 2 channels */
d2a6d7dc 2695static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2696 { 2, NULL }
2697};
2698
c8b6bf9b 2699static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2700 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2701 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2702 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2703 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2704 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2705 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2708 { } /* end */
2709};
2710
e9edcee0 2711
e9edcee0
TI
2712/*
2713 * ALC880 F1734 model
2714 *
2715 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2716 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2717 */
2718
2719static hda_nid_t alc880_f1734_dac_nids[1] = {
2720 0x03
2721};
2722#define ALC880_F1734_HP_DAC 0x02
2723
c8b6bf9b 2724static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2725 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2726 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2727 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2728 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2729 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2730 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2731 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2732 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2733 { } /* end */
2734};
2735
937b4160
TI
2736static struct hda_input_mux alc880_f1734_capture_source = {
2737 .num_items = 2,
2738 .items = {
2739 { "Mic", 0x1 },
2740 { "CD", 0x4 },
2741 },
2742};
2743
e9edcee0 2744
e9edcee0
TI
2745/*
2746 * ALC880 ASUS model
2747 *
2748 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2749 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2750 * Mic = 0x18, Line = 0x1a
2751 */
2752
2753#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2754#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2755
c8b6bf9b 2756static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2757 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2758 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2759 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2760 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2761 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2762 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2763 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2764 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2765 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2766 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2767 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2768 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2769 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2770 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2771 {
2772 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2773 .name = "Channel Mode",
df694daa
KY
2774 .info = alc_ch_mode_info,
2775 .get = alc_ch_mode_get,
2776 .put = alc_ch_mode_put,
16ded525
TI
2777 },
2778 { } /* end */
2779};
e9edcee0 2780
e9edcee0
TI
2781/*
2782 * ALC880 ASUS W1V model
2783 *
2784 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2785 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2786 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2787 */
2788
2789/* additional mixers to alc880_asus_mixer */
c8b6bf9b 2790static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
2791 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2792 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2793 { } /* end */
2794};
2795
df694daa
KY
2796/* TCL S700 */
2797static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2798 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2799 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2800 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2801 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2802 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2803 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2804 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2805 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2806 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2807 { } /* end */
2808};
2809
ccc656ce
KY
2810/* Uniwill */
2811static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2812 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2813 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2814 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2815 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2816 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2817 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2818 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2819 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2820 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2821 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2822 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2823 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2824 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2825 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2826 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2827 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2828 {
2829 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2830 .name = "Channel Mode",
2831 .info = alc_ch_mode_info,
2832 .get = alc_ch_mode_get,
2833 .put = alc_ch_mode_put,
2834 },
2835 { } /* end */
2836};
2837
2cf9f0fc
TD
2838static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2839 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2840 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2841 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2842 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2843 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2844 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8607f7c4
DH
2845 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2846 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
2847 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2848 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2cf9f0fc
TD
2849 { } /* end */
2850};
2851
ccc656ce 2852static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2853 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2854 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2855 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2856 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2857 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2858 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2859 { } /* end */
2860};
2861
2134ea4f
TI
2862/*
2863 * virtual master controls
2864 */
2865
2866/*
2867 * slave controls for virtual master
2868 */
2869static const char *alc_slave_vols[] = {
2870 "Front Playback Volume",
2871 "Surround Playback Volume",
2872 "Center Playback Volume",
2873 "LFE Playback Volume",
2874 "Side Playback Volume",
2875 "Headphone Playback Volume",
2876 "Speaker Playback Volume",
2877 "Mono Playback Volume",
2134ea4f 2878 "Line-Out Playback Volume",
26f5df26 2879 "PCM Playback Volume",
2134ea4f
TI
2880 NULL,
2881};
2882
2883static const char *alc_slave_sws[] = {
2884 "Front Playback Switch",
2885 "Surround Playback Switch",
2886 "Center Playback Switch",
2887 "LFE Playback Switch",
2888 "Side Playback Switch",
2889 "Headphone Playback Switch",
2890 "Speaker Playback Switch",
2891 "Mono Playback Switch",
edb54a55 2892 "IEC958 Playback Switch",
23033b2b
TI
2893 "Line-Out Playback Switch",
2894 "PCM Playback Switch",
2134ea4f
TI
2895 NULL,
2896};
2897
1da177e4 2898/*
e9edcee0 2899 * build control elements
1da177e4 2900 */
603c4019 2901
5b0cb1d8
JK
2902#define NID_MAPPING (-1)
2903
2904#define SUBDEV_SPEAKER_ (0 << 6)
2905#define SUBDEV_HP_ (1 << 6)
2906#define SUBDEV_LINE_ (2 << 6)
2907#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2908#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2909#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2910
603c4019
TI
2911static void alc_free_kctls(struct hda_codec *codec);
2912
67d634c0 2913#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2914/* additional beep mixers; the actual parameters are overwritten at build */
2915static struct snd_kcontrol_new alc_beep_mixer[] = {
2916 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 2917 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
2918 { } /* end */
2919};
67d634c0 2920#endif
45bdd1c1 2921
1da177e4
LT
2922static int alc_build_controls(struct hda_codec *codec)
2923{
2924 struct alc_spec *spec = codec->spec;
2f44f847 2925 struct snd_kcontrol *kctl = NULL;
5b0cb1d8
JK
2926 struct snd_kcontrol_new *knew;
2927 int i, j, err;
2928 unsigned int u;
2929 hda_nid_t nid;
1da177e4
LT
2930
2931 for (i = 0; i < spec->num_mixers; i++) {
2932 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2933 if (err < 0)
2934 return err;
2935 }
f9e336f6
TI
2936 if (spec->cap_mixer) {
2937 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2938 if (err < 0)
2939 return err;
2940 }
1da177e4 2941 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2942 err = snd_hda_create_spdif_out_ctls(codec,
2943 spec->multiout.dig_out_nid);
1da177e4
LT
2944 if (err < 0)
2945 return err;
e64f14f4
TI
2946 if (!spec->no_analog) {
2947 err = snd_hda_create_spdif_share_sw(codec,
2948 &spec->multiout);
2949 if (err < 0)
2950 return err;
2951 spec->multiout.share_spdif = 1;
2952 }
1da177e4
LT
2953 }
2954 if (spec->dig_in_nid) {
2955 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2956 if (err < 0)
2957 return err;
2958 }
2134ea4f 2959
67d634c0 2960#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2961 /* create beep controls if needed */
2962 if (spec->beep_amp) {
2963 struct snd_kcontrol_new *knew;
2964 for (knew = alc_beep_mixer; knew->name; knew++) {
2965 struct snd_kcontrol *kctl;
2966 kctl = snd_ctl_new1(knew, codec);
2967 if (!kctl)
2968 return -ENOMEM;
2969 kctl->private_value = spec->beep_amp;
5e26dfd0 2970 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
2971 if (err < 0)
2972 return err;
2973 }
2974 }
67d634c0 2975#endif
45bdd1c1 2976
2134ea4f 2977 /* if we have no master control, let's create it */
e64f14f4
TI
2978 if (!spec->no_analog &&
2979 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2980 unsigned int vmaster_tlv[4];
2134ea4f 2981 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2982 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2983 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2984 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2985 if (err < 0)
2986 return err;
2987 }
e64f14f4
TI
2988 if (!spec->no_analog &&
2989 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2990 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2991 NULL, alc_slave_sws);
2992 if (err < 0)
2993 return err;
2994 }
2995
5b0cb1d8 2996 /* assign Capture Source enums to NID */
fbe618f2
TI
2997 if (spec->capsrc_nids || spec->adc_nids) {
2998 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2999 if (!kctl)
3000 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3001 for (i = 0; kctl && i < kctl->count; i++) {
3002 hda_nid_t *nids = spec->capsrc_nids;
3003 if (!nids)
3004 nids = spec->adc_nids;
3005 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3006 if (err < 0)
3007 return err;
3008 }
5b0cb1d8
JK
3009 }
3010 if (spec->cap_mixer) {
3011 const char *kname = kctl ? kctl->id.name : NULL;
3012 for (knew = spec->cap_mixer; knew->name; knew++) {
3013 if (kname && strcmp(knew->name, kname) == 0)
3014 continue;
3015 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3016 for (i = 0; kctl && i < kctl->count; i++) {
3017 err = snd_hda_add_nid(codec, kctl, i,
3018 spec->adc_nids[i]);
3019 if (err < 0)
3020 return err;
3021 }
3022 }
3023 }
3024
3025 /* other nid->control mapping */
3026 for (i = 0; i < spec->num_mixers; i++) {
3027 for (knew = spec->mixers[i]; knew->name; knew++) {
3028 if (knew->iface != NID_MAPPING)
3029 continue;
3030 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3031 if (kctl == NULL)
3032 continue;
3033 u = knew->subdevice;
3034 for (j = 0; j < 4; j++, u >>= 8) {
3035 nid = u & 0x3f;
3036 if (nid == 0)
3037 continue;
3038 switch (u & 0xc0) {
3039 case SUBDEV_SPEAKER_:
3040 nid = spec->autocfg.speaker_pins[nid];
3041 break;
3042 case SUBDEV_LINE_:
3043 nid = spec->autocfg.line_out_pins[nid];
3044 break;
3045 case SUBDEV_HP_:
3046 nid = spec->autocfg.hp_pins[nid];
3047 break;
3048 default:
3049 continue;
3050 }
3051 err = snd_hda_add_nid(codec, kctl, 0, nid);
3052 if (err < 0)
3053 return err;
3054 }
3055 u = knew->private_value;
3056 for (j = 0; j < 4; j++, u >>= 8) {
3057 nid = u & 0xff;
3058 if (nid == 0)
3059 continue;
3060 err = snd_hda_add_nid(codec, kctl, 0, nid);
3061 if (err < 0)
3062 return err;
3063 }
3064 }
3065 }
bae84e70
TI
3066
3067 alc_free_kctls(codec); /* no longer needed */
3068
1da177e4
LT
3069 return 0;
3070}
3071
e9edcee0 3072
1da177e4
LT
3073/*
3074 * initialize the codec volumes, etc
3075 */
3076
e9edcee0
TI
3077/*
3078 * generic initialization of ADC, input mixers and output mixers
3079 */
3080static struct hda_verb alc880_volume_init_verbs[] = {
3081 /*
3082 * Unmute ADC0-2 and set the default input to mic-in
3083 */
71fe7b82 3084 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3085 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3086 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3087 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3088 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3089 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 3090
e9edcee0
TI
3091 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3092 * mixer widget
9c7f852e
TI
3093 * Note: PASD motherboards uses the Line In 2 as the input for front
3094 * panel mic (mic 2)
1da177e4 3095 */
e9edcee0 3096 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
3097 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3098 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3100 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3101 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3102 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3103 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 3104
e9edcee0
TI
3105 /*
3106 * Set up output mixers (0x0c - 0x0f)
1da177e4 3107 */
e9edcee0
TI
3108 /* set vol=0 to output mixers */
3109 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3110 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3111 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3112 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3113 /* set up input amps for analog loopback */
3114 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
3115 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3116 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3117 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3118 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3119 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3120 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3121 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3122 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
3123
3124 { }
3125};
3126
e9edcee0
TI
3127/*
3128 * 3-stack pin configuration:
3129 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3130 */
3131static struct hda_verb alc880_pin_3stack_init_verbs[] = {
3132 /*
3133 * preset connection lists of input pins
3134 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3135 */
3136 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3137 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3138 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3139
3140 /*
3141 * Set pin mode and muting
3142 */
3143 /* set front pin widgets 0x14 for output */
05acb863 3144 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3145 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3146 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3147 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3148 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3149 /* Mic2 (as headphone out) for HP output */
3150 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3151 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3152 /* Line In pin widget for input */
05acb863 3153 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3154 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3155 /* Line2 (as front mic) pin widget for input and vref at 80% */
3156 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3157 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3158 /* CD pin widget for input */
05acb863 3159 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3160
e9edcee0
TI
3161 { }
3162};
1da177e4 3163
e9edcee0
TI
3164/*
3165 * 5-stack pin configuration:
3166 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3167 * line-in/side = 0x1a, f-mic = 0x1b
3168 */
3169static struct hda_verb alc880_pin_5stack_init_verbs[] = {
3170 /*
3171 * preset connection lists of input pins
3172 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 3173 */
e9edcee0
TI
3174 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3175 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 3176
e9edcee0
TI
3177 /*
3178 * Set pin mode and muting
1da177e4 3179 */
e9edcee0
TI
3180 /* set pin widgets 0x14-0x17 for output */
3181 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3182 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3183 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3184 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3185 /* unmute pins for output (no gain on this amp) */
3186 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3187 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3188 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3189 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3190
3191 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3192 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3193 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3194 /* Mic2 (as headphone out) for HP output */
3195 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3196 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3197 /* Line In pin widget for input */
3198 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3199 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3200 /* Line2 (as front mic) pin widget for input and vref at 80% */
3201 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3202 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3203 /* CD pin widget for input */
3204 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3205
3206 { }
3207};
3208
e9edcee0
TI
3209/*
3210 * W810 pin configuration:
3211 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3212 */
3213static struct hda_verb alc880_pin_w810_init_verbs[] = {
3214 /* hphone/speaker input selector: front DAC */
3215 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 3216
05acb863 3217 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3218 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3219 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3220 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3221 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3222 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3223
e9edcee0 3224 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 3225 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3226
1da177e4
LT
3227 { }
3228};
3229
e9edcee0
TI
3230/*
3231 * Z71V pin configuration:
3232 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3233 */
3234static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 3235 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3236 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3237 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3238 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 3239
16ded525 3240 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3241 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 3242 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3243 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
3244
3245 { }
3246};
3247
e9edcee0
TI
3248/*
3249 * 6-stack pin configuration:
9c7f852e
TI
3250 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3251 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
3252 */
3253static struct hda_verb alc880_pin_6stack_init_verbs[] = {
3254 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3255
16ded525 3256 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3257 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3258 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3259 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3260 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3261 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3262 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3263 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3264
16ded525 3265 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3266 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3267 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3268 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3269 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3270 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3271 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3272 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3273 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3274
e9edcee0
TI
3275 { }
3276};
3277
ccc656ce
KY
3278/*
3279 * Uniwill pin configuration:
3280 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3281 * line = 0x1a
3282 */
3283static struct hda_verb alc880_uniwill_init_verbs[] = {
3284 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3285
3286 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3287 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3288 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3289 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3290 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3291 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3292 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3293 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3294 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3295 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3296 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3297 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3298 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3299 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3300
3301 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3302 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3303 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3304 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3305 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3306 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3307 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3308 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3309 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3310
3311 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3312 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3313
3314 { }
3315};
3316
3317/*
3318* Uniwill P53
ea1fb29a 3319* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
3320 */
3321static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3322 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3323
3324 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3325 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3326 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3327 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3328 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3329 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3330 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3331 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3332 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3333 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3334 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3335 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3336
3337 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3338 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3339 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3340 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3341 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3342 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3343
3344 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3345 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3346
3347 { }
3348};
3349
2cf9f0fc
TD
3350static struct hda_verb alc880_beep_init_verbs[] = {
3351 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3352 { }
3353};
3354
458a4fab 3355/* auto-toggle front mic */
eeb43387 3356static void alc88x_simple_mic_automute(struct hda_codec *codec)
458a4fab
TI
3357{
3358 unsigned int present;
3359 unsigned char bits;
ccc656ce 3360
864f92be 3361 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3362 bits = present ? HDA_AMP_MUTE : 0;
3363 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3364}
3365
4f5d1706 3366static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3367{
a9fd4f3f
TI
3368 struct alc_spec *spec = codec->spec;
3369
3370 spec->autocfg.hp_pins[0] = 0x14;
3371 spec->autocfg.speaker_pins[0] = 0x15;
3372 spec->autocfg.speaker_pins[0] = 0x16;
4f5d1706
TI
3373}
3374
3375static void alc880_uniwill_init_hook(struct hda_codec *codec)
3376{
a9fd4f3f 3377 alc_automute_amp(codec);
eeb43387 3378 alc88x_simple_mic_automute(codec);
ccc656ce
KY
3379}
3380
3381static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3382 unsigned int res)
3383{
3384 /* Looks like the unsol event is incompatible with the standard
3385 * definition. 4bit tag is placed at 28 bit!
3386 */
458a4fab 3387 switch (res >> 28) {
458a4fab 3388 case ALC880_MIC_EVENT:
eeb43387 3389 alc88x_simple_mic_automute(codec);
458a4fab 3390 break;
a9fd4f3f
TI
3391 default:
3392 alc_automute_amp_unsol_event(codec, res);
3393 break;
458a4fab 3394 }
ccc656ce
KY
3395}
3396
4f5d1706 3397static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3398{
a9fd4f3f 3399 struct alc_spec *spec = codec->spec;
ccc656ce 3400
a9fd4f3f
TI
3401 spec->autocfg.hp_pins[0] = 0x14;
3402 spec->autocfg.speaker_pins[0] = 0x15;
ccc656ce
KY
3403}
3404
3405static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3406{
3407 unsigned int present;
ea1fb29a 3408
ccc656ce 3409 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3410 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3411 present &= HDA_AMP_VOLMASK;
3412 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3413 HDA_AMP_VOLMASK, present);
3414 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3415 HDA_AMP_VOLMASK, present);
ccc656ce 3416}
47fd830a 3417
ccc656ce
KY
3418static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3419 unsigned int res)
3420{
3421 /* Looks like the unsol event is incompatible with the standard
3422 * definition. 4bit tag is placed at 28 bit!
3423 */
f12ab1e0 3424 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3425 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
3426 else
3427 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
3428}
3429
e9edcee0
TI
3430/*
3431 * F1734 pin configuration:
3432 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3433 */
3434static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3435 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3436 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3437 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3438 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3439 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3440
e9edcee0 3441 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3442 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3443 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3444 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3445
e9edcee0
TI
3446 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3447 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3448 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3449 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3450 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3451 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3452 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3453 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3454 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3455
937b4160
TI
3456 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3457 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3458
dfc0ff62
TI
3459 { }
3460};
3461
e9edcee0
TI
3462/*
3463 * ASUS pin configuration:
3464 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3465 */
3466static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3467 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3468 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3469 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3470 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3471
3472 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3473 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3474 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3475 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3476 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3477 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3478 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3479 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3480
3481 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3482 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3483 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3484 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3485 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3486 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3487 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3488 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3489 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3490
e9edcee0
TI
3491 { }
3492};
16ded525 3493
e9edcee0 3494/* Enable GPIO mask and set output */
bc9f98a9
KY
3495#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3496#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3497#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3498
3499/* Clevo m520g init */
3500static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3501 /* headphone output */
3502 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3503 /* line-out */
3504 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3505 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3506 /* Line-in */
3507 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3508 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3509 /* CD */
3510 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3511 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3512 /* Mic1 (rear panel) */
3513 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3514 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3515 /* Mic2 (front panel) */
3516 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3517 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3518 /* headphone */
3519 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3520 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3521 /* change to EAPD mode */
3522 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3523 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3524
3525 { }
16ded525
TI
3526};
3527
df694daa 3528static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3529 /* change to EAPD mode */
3530 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3531 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3532
df694daa
KY
3533 /* Headphone output */
3534 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3535 /* Front output*/
3536 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3537 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3538
3539 /* Line In pin widget for input */
3540 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3541 /* CD pin widget for input */
3542 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3543 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3544 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3545
3546 /* change to EAPD mode */
3547 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3548 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3549
3550 { }
3551};
16ded525 3552
e9edcee0 3553/*
ae6b813a
TI
3554 * LG m1 express dual
3555 *
3556 * Pin assignment:
3557 * Rear Line-In/Out (blue): 0x14
3558 * Build-in Mic-In: 0x15
3559 * Speaker-out: 0x17
3560 * HP-Out (green): 0x1b
3561 * Mic-In/Out (red): 0x19
3562 * SPDIF-Out: 0x1e
3563 */
3564
3565/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3566static hda_nid_t alc880_lg_dac_nids[3] = {
3567 0x05, 0x02, 0x03
3568};
3569
3570/* seems analog CD is not working */
3571static struct hda_input_mux alc880_lg_capture_source = {
3572 .num_items = 3,
3573 .items = {
3574 { "Mic", 0x1 },
3575 { "Line", 0x5 },
3576 { "Internal Mic", 0x6 },
3577 },
3578};
3579
3580/* 2,4,6 channel modes */
3581static struct hda_verb alc880_lg_ch2_init[] = {
3582 /* set line-in and mic-in to input */
3583 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3584 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3585 { }
3586};
3587
3588static struct hda_verb alc880_lg_ch4_init[] = {
3589 /* set line-in to out and mic-in to input */
3590 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3591 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3592 { }
3593};
3594
3595static struct hda_verb alc880_lg_ch6_init[] = {
3596 /* set line-in and mic-in to output */
3597 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3598 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3599 { }
3600};
3601
3602static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3603 { 2, alc880_lg_ch2_init },
3604 { 4, alc880_lg_ch4_init },
3605 { 6, alc880_lg_ch6_init },
3606};
3607
3608static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3609 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3610 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3611 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3612 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3613 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3614 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3615 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3616 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3617 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3618 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3619 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3620 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3621 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3622 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3623 {
3624 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3625 .name = "Channel Mode",
3626 .info = alc_ch_mode_info,
3627 .get = alc_ch_mode_get,
3628 .put = alc_ch_mode_put,
3629 },
3630 { } /* end */
3631};
3632
3633static struct hda_verb alc880_lg_init_verbs[] = {
3634 /* set capture source to mic-in */
3635 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3636 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3637 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3638 /* mute all amp mixer inputs */
3639 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3640 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3641 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3642 /* line-in to input */
3643 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3644 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3645 /* built-in mic */
3646 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3647 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3648 /* speaker-out */
3649 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3650 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3651 /* mic-in to input */
3652 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3653 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3654 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3655 /* HP-out */
3656 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3657 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3658 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3659 /* jack sense */
a9fd4f3f 3660 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3661 { }
3662};
3663
3664/* toggle speaker-output according to the hp-jack state */
4f5d1706 3665static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3666{
a9fd4f3f 3667 struct alc_spec *spec = codec->spec;
ae6b813a 3668
a9fd4f3f
TI
3669 spec->autocfg.hp_pins[0] = 0x1b;
3670 spec->autocfg.speaker_pins[0] = 0x17;
ae6b813a
TI
3671}
3672
d681518a
TI
3673/*
3674 * LG LW20
3675 *
3676 * Pin assignment:
3677 * Speaker-out: 0x14
3678 * Mic-In: 0x18
e4f41da9
CM
3679 * Built-in Mic-In: 0x19
3680 * Line-In: 0x1b
3681 * HP-Out: 0x1a
d681518a
TI
3682 * SPDIF-Out: 0x1e
3683 */
3684
d681518a 3685static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3686 .num_items = 3,
d681518a
TI
3687 .items = {
3688 { "Mic", 0x0 },
3689 { "Internal Mic", 0x1 },
e4f41da9 3690 { "Line In", 0x2 },
d681518a
TI
3691 },
3692};
3693
0a8c5da3
CM
3694#define alc880_lg_lw_modes alc880_threestack_modes
3695
d681518a 3696static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3697 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3698 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3699 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3700 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3701 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3702 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3703 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3704 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3705 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3706 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3708 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3709 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3710 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3711 {
3712 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3713 .name = "Channel Mode",
3714 .info = alc_ch_mode_info,
3715 .get = alc_ch_mode_get,
3716 .put = alc_ch_mode_put,
3717 },
d681518a
TI
3718 { } /* end */
3719};
3720
3721static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3722 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3723 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3724 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3725
d681518a
TI
3726 /* set capture source to mic-in */
3727 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3728 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3729 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3730 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3731 /* speaker-out */
3732 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3733 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3734 /* HP-out */
d681518a
TI
3735 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3736 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3737 /* mic-in to input */
3738 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3739 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3740 /* built-in mic */
3741 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3742 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3743 /* jack sense */
a9fd4f3f 3744 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3745 { }
3746};
3747
3748/* toggle speaker-output according to the hp-jack state */
4f5d1706 3749static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3750{
a9fd4f3f 3751 struct alc_spec *spec = codec->spec;
d681518a 3752
a9fd4f3f
TI
3753 spec->autocfg.hp_pins[0] = 0x1b;
3754 spec->autocfg.speaker_pins[0] = 0x14;
d681518a
TI
3755}
3756
df99cd33
TI
3757static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3758 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3759 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3760 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3761 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3762 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3763 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3764 { } /* end */
3765};
3766
3767static struct hda_input_mux alc880_medion_rim_capture_source = {
3768 .num_items = 2,
3769 .items = {
3770 { "Mic", 0x0 },
3771 { "Internal Mic", 0x1 },
3772 },
3773};
3774
3775static struct hda_verb alc880_medion_rim_init_verbs[] = {
3776 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3777
3778 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3779 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3780
3781 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3782 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3783 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3784 /* Mic2 (as headphone out) for HP output */
3785 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3786 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3787 /* Internal Speaker */
3788 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3789 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3790
3791 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3792 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3793
3794 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3795 { }
3796};
3797
3798/* toggle speaker-output according to the hp-jack state */
3799static void alc880_medion_rim_automute(struct hda_codec *codec)
3800{
a9fd4f3f
TI
3801 struct alc_spec *spec = codec->spec;
3802 alc_automute_amp(codec);
3803 /* toggle EAPD */
3804 if (spec->jack_present)
df99cd33
TI
3805 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3806 else
3807 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3808}
3809
3810static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3811 unsigned int res)
3812{
3813 /* Looks like the unsol event is incompatible with the standard
3814 * definition. 4bit tag is placed at 28 bit!
3815 */
3816 if ((res >> 28) == ALC880_HP_EVENT)
3817 alc880_medion_rim_automute(codec);
3818}
3819
4f5d1706 3820static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
3821{
3822 struct alc_spec *spec = codec->spec;
3823
3824 spec->autocfg.hp_pins[0] = 0x14;
3825 spec->autocfg.speaker_pins[0] = 0x1b;
a9fd4f3f
TI
3826}
3827
cb53c626
TI
3828#ifdef CONFIG_SND_HDA_POWER_SAVE
3829static struct hda_amp_list alc880_loopbacks[] = {
3830 { 0x0b, HDA_INPUT, 0 },
3831 { 0x0b, HDA_INPUT, 1 },
3832 { 0x0b, HDA_INPUT, 2 },
3833 { 0x0b, HDA_INPUT, 3 },
3834 { 0x0b, HDA_INPUT, 4 },
3835 { } /* end */
3836};
3837
3838static struct hda_amp_list alc880_lg_loopbacks[] = {
3839 { 0x0b, HDA_INPUT, 1 },
3840 { 0x0b, HDA_INPUT, 6 },
3841 { 0x0b, HDA_INPUT, 7 },
3842 { } /* end */
3843};
3844#endif
3845
ae6b813a
TI
3846/*
3847 * Common callbacks
e9edcee0
TI
3848 */
3849
1da177e4
LT
3850static int alc_init(struct hda_codec *codec)
3851{
3852 struct alc_spec *spec = codec->spec;
e9edcee0
TI
3853 unsigned int i;
3854
2c3bf9ab 3855 alc_fix_pll(codec);
4a79ba34 3856 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 3857
e9edcee0
TI
3858 for (i = 0; i < spec->num_init_verbs; i++)
3859 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
3860
3861 if (spec->init_hook)
3862 spec->init_hook(codec);
3863
9e5341b9 3864 hda_call_check_power_status(codec, 0x01);
1da177e4
LT
3865 return 0;
3866}
3867
ae6b813a
TI
3868static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3869{
3870 struct alc_spec *spec = codec->spec;
3871
3872 if (spec->unsol_event)
3873 spec->unsol_event(codec, res);
3874}
3875
cb53c626
TI
3876#ifdef CONFIG_SND_HDA_POWER_SAVE
3877static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3878{
3879 struct alc_spec *spec = codec->spec;
3880 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3881}
3882#endif
3883
1da177e4
LT
3884/*
3885 * Analog playback callbacks
3886 */
3887static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3888 struct hda_codec *codec,
c8b6bf9b 3889 struct snd_pcm_substream *substream)
1da177e4
LT
3890{
3891 struct alc_spec *spec = codec->spec;
9a08160b
TI
3892 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3893 hinfo);
1da177e4
LT
3894}
3895
3896static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3897 struct hda_codec *codec,
3898 unsigned int stream_tag,
3899 unsigned int format,
c8b6bf9b 3900 struct snd_pcm_substream *substream)
1da177e4
LT
3901{
3902 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3903 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3904 stream_tag, format, substream);
1da177e4
LT
3905}
3906
3907static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3908 struct hda_codec *codec,
c8b6bf9b 3909 struct snd_pcm_substream *substream)
1da177e4
LT
3910{
3911 struct alc_spec *spec = codec->spec;
3912 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3913}
3914
3915/*
3916 * Digital out
3917 */
3918static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3919 struct hda_codec *codec,
c8b6bf9b 3920 struct snd_pcm_substream *substream)
1da177e4
LT
3921{
3922 struct alc_spec *spec = codec->spec;
3923 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3924}
3925
6b97eb45
TI
3926static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3927 struct hda_codec *codec,
3928 unsigned int stream_tag,
3929 unsigned int format,
3930 struct snd_pcm_substream *substream)
3931{
3932 struct alc_spec *spec = codec->spec;
3933 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3934 stream_tag, format, substream);
3935}
3936
9b5f12e5
TI
3937static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3938 struct hda_codec *codec,
3939 struct snd_pcm_substream *substream)
3940{
3941 struct alc_spec *spec = codec->spec;
3942 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3943}
3944
1da177e4
LT
3945static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3946 struct hda_codec *codec,
c8b6bf9b 3947 struct snd_pcm_substream *substream)
1da177e4
LT
3948{
3949 struct alc_spec *spec = codec->spec;
3950 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3951}
3952
3953/*
3954 * Analog capture
3955 */
6330079f 3956static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3957 struct hda_codec *codec,
3958 unsigned int stream_tag,
3959 unsigned int format,
c8b6bf9b 3960 struct snd_pcm_substream *substream)
1da177e4
LT
3961{
3962 struct alc_spec *spec = codec->spec;
3963
6330079f 3964 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3965 stream_tag, 0, format);
3966 return 0;
3967}
3968
6330079f 3969static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3970 struct hda_codec *codec,
c8b6bf9b 3971 struct snd_pcm_substream *substream)
1da177e4
LT
3972{
3973 struct alc_spec *spec = codec->spec;
3974
888afa15
TI
3975 snd_hda_codec_cleanup_stream(codec,
3976 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3977 return 0;
3978}
3979
840b64c0
TI
3980/* analog capture with dynamic dual-adc changes */
3981static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3982 struct hda_codec *codec,
3983 unsigned int stream_tag,
3984 unsigned int format,
3985 struct snd_pcm_substream *substream)
3986{
3987 struct alc_spec *spec = codec->spec;
3988 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
3989 spec->cur_adc_stream_tag = stream_tag;
3990 spec->cur_adc_format = format;
3991 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
3992 return 0;
3993}
3994
3995static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3996 struct hda_codec *codec,
3997 struct snd_pcm_substream *substream)
3998{
3999 struct alc_spec *spec = codec->spec;
4000 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4001 spec->cur_adc = 0;
4002 return 0;
4003}
4004
4005static struct hda_pcm_stream dualmic_pcm_analog_capture = {
4006 .substreams = 1,
4007 .channels_min = 2,
4008 .channels_max = 2,
4009 .nid = 0, /* fill later */
4010 .ops = {
4011 .prepare = dualmic_capture_pcm_prepare,
4012 .cleanup = dualmic_capture_pcm_cleanup
4013 },
4014};
1da177e4
LT
4015
4016/*
4017 */
4018static struct hda_pcm_stream alc880_pcm_analog_playback = {
4019 .substreams = 1,
4020 .channels_min = 2,
4021 .channels_max = 8,
e9edcee0 4022 /* NID is set in alc_build_pcms */
1da177e4
LT
4023 .ops = {
4024 .open = alc880_playback_pcm_open,
4025 .prepare = alc880_playback_pcm_prepare,
4026 .cleanup = alc880_playback_pcm_cleanup
4027 },
4028};
4029
4030static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
4031 .substreams = 1,
4032 .channels_min = 2,
4033 .channels_max = 2,
4034 /* NID is set in alc_build_pcms */
4035};
4036
4037static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
4038 .substreams = 1,
4039 .channels_min = 2,
4040 .channels_max = 2,
4041 /* NID is set in alc_build_pcms */
4042};
4043
4044static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4045 .substreams = 2, /* can be overridden */
1da177e4
LT
4046 .channels_min = 2,
4047 .channels_max = 2,
e9edcee0 4048 /* NID is set in alc_build_pcms */
1da177e4 4049 .ops = {
6330079f
TI
4050 .prepare = alc880_alt_capture_pcm_prepare,
4051 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
4052 },
4053};
4054
4055static struct hda_pcm_stream alc880_pcm_digital_playback = {
4056 .substreams = 1,
4057 .channels_min = 2,
4058 .channels_max = 2,
4059 /* NID is set in alc_build_pcms */
4060 .ops = {
4061 .open = alc880_dig_playback_pcm_open,
6b97eb45 4062 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
4063 .prepare = alc880_dig_playback_pcm_prepare,
4064 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
4065 },
4066};
4067
4068static struct hda_pcm_stream alc880_pcm_digital_capture = {
4069 .substreams = 1,
4070 .channels_min = 2,
4071 .channels_max = 2,
4072 /* NID is set in alc_build_pcms */
4073};
4074
4c5186ed 4075/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 4076static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
4077 .substreams = 0,
4078 .channels_min = 0,
4079 .channels_max = 0,
4080};
4081
1da177e4
LT
4082static int alc_build_pcms(struct hda_codec *codec)
4083{
4084 struct alc_spec *spec = codec->spec;
4085 struct hda_pcm *info = spec->pcm_rec;
4086 int i;
4087
4088 codec->num_pcms = 1;
4089 codec->pcm_info = info;
4090
e64f14f4
TI
4091 if (spec->no_analog)
4092 goto skip_analog;
4093
812a2cca
TI
4094 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4095 "%s Analog", codec->chip_name);
1da177e4 4096 info->name = spec->stream_name_analog;
274693f3 4097
4a471b7d 4098 if (spec->stream_analog_playback) {
da3cec35
TI
4099 if (snd_BUG_ON(!spec->multiout.dac_nids))
4100 return -EINVAL;
4a471b7d
TI
4101 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4102 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4103 }
4104 if (spec->stream_analog_capture) {
da3cec35
TI
4105 if (snd_BUG_ON(!spec->adc_nids))
4106 return -EINVAL;
4a471b7d
TI
4107 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4108 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4109 }
4110
4111 if (spec->channel_mode) {
4112 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4113 for (i = 0; i < spec->num_channel_mode; i++) {
4114 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4115 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4116 }
1da177e4
LT
4117 }
4118 }
4119
e64f14f4 4120 skip_analog:
e08a007d 4121 /* SPDIF for stream index #1 */
1da177e4 4122 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
4123 snprintf(spec->stream_name_digital,
4124 sizeof(spec->stream_name_digital),
4125 "%s Digital", codec->chip_name);
e08a007d 4126 codec->num_pcms = 2;
b25c9da1 4127 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 4128 info = spec->pcm_rec + 1;
1da177e4 4129 info->name = spec->stream_name_digital;
8c441982
TI
4130 if (spec->dig_out_type)
4131 info->pcm_type = spec->dig_out_type;
4132 else
4133 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
4134 if (spec->multiout.dig_out_nid &&
4135 spec->stream_digital_playback) {
1da177e4
LT
4136 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4137 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4138 }
4a471b7d
TI
4139 if (spec->dig_in_nid &&
4140 spec->stream_digital_capture) {
1da177e4
LT
4141 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4142 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4143 }
963f803f
TI
4144 /* FIXME: do we need this for all Realtek codec models? */
4145 codec->spdif_status_reset = 1;
1da177e4
LT
4146 }
4147
e64f14f4
TI
4148 if (spec->no_analog)
4149 return 0;
4150
e08a007d
TI
4151 /* If the use of more than one ADC is requested for the current
4152 * model, configure a second analog capture-only PCM.
4153 */
4154 /* Additional Analaog capture for index #2 */
6330079f
TI
4155 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4156 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 4157 codec->num_pcms = 3;
c06134d7 4158 info = spec->pcm_rec + 2;
e08a007d 4159 info->name = spec->stream_name_analog;
6330079f
TI
4160 if (spec->alt_dac_nid) {
4161 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4162 *spec->stream_analog_alt_playback;
4163 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4164 spec->alt_dac_nid;
4165 } else {
4166 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4167 alc_pcm_null_stream;
4168 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4169 }
4170 if (spec->num_adc_nids > 1) {
4171 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4172 *spec->stream_analog_alt_capture;
4173 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4174 spec->adc_nids[1];
4175 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4176 spec->num_adc_nids - 1;
4177 } else {
4178 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4179 alc_pcm_null_stream;
4180 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4181 }
4182 }
4183
1da177e4
LT
4184 return 0;
4185}
4186
a4e09aa3
TI
4187static inline void alc_shutup(struct hda_codec *codec)
4188{
4189 snd_hda_shutup_pins(codec);
4190}
4191
603c4019
TI
4192static void alc_free_kctls(struct hda_codec *codec)
4193{
4194 struct alc_spec *spec = codec->spec;
4195
4196 if (spec->kctls.list) {
4197 struct snd_kcontrol_new *kctl = spec->kctls.list;
4198 int i;
4199 for (i = 0; i < spec->kctls.used; i++)
4200 kfree(kctl[i].name);
4201 }
4202 snd_array_free(&spec->kctls);
4203}
4204
1da177e4
LT
4205static void alc_free(struct hda_codec *codec)
4206{
e9edcee0 4207 struct alc_spec *spec = codec->spec;
e9edcee0 4208
f12ab1e0 4209 if (!spec)
e9edcee0
TI
4210 return;
4211
a4e09aa3 4212 alc_shutup(codec);
603c4019 4213 alc_free_kctls(codec);
e9edcee0 4214 kfree(spec);
680cd536 4215 snd_hda_detach_beep_device(codec);
1da177e4
LT
4216}
4217
f5de24b0 4218#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4219static void alc_power_eapd(struct hda_codec *codec)
4220{
4221 /* We currently only handle front, HP */
4222 switch (codec->vendor_id) {
4223 case 0x10ec0260:
9e4c8496
TI
4224 set_eapd(codec, 0x0f, 0);
4225 set_eapd(codec, 0x10, 0);
c97259df
DC
4226 break;
4227 case 0x10ec0262:
4228 case 0x10ec0267:
4229 case 0x10ec0268:
4230 case 0x10ec0269:
9e4c8496 4231 case 0x10ec0270:
c97259df
DC
4232 case 0x10ec0272:
4233 case 0x10ec0660:
4234 case 0x10ec0662:
4235 case 0x10ec0663:
4236 case 0x10ec0862:
4237 case 0x10ec0889:
9e4c8496
TI
4238 set_eapd(codec, 0x14, 0);
4239 set_eapd(codec, 0x15, 0);
c97259df
DC
4240 break;
4241 }
4242}
4243
f5de24b0
HM
4244static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4245{
4246 struct alc_spec *spec = codec->spec;
a4e09aa3 4247 alc_shutup(codec);
f5de24b0 4248 if (spec && spec->power_hook)
c97259df 4249 spec->power_hook(codec);
f5de24b0
HM
4250 return 0;
4251}
4252#endif
4253
e044c39a 4254#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4255static int alc_resume(struct hda_codec *codec)
4256{
e044c39a
TI
4257 codec->patch_ops.init(codec);
4258 snd_hda_codec_resume_amp(codec);
4259 snd_hda_codec_resume_cache(codec);
9e5341b9 4260 hda_call_check_power_status(codec, 0x01);
e044c39a
TI
4261 return 0;
4262}
e044c39a
TI
4263#endif
4264
1da177e4
LT
4265/*
4266 */
4267static struct hda_codec_ops alc_patch_ops = {
4268 .build_controls = alc_build_controls,
4269 .build_pcms = alc_build_pcms,
4270 .init = alc_init,
4271 .free = alc_free,
ae6b813a 4272 .unsol_event = alc_unsol_event,
e044c39a
TI
4273#ifdef SND_HDA_NEEDS_RESUME
4274 .resume = alc_resume,
4275#endif
cb53c626 4276#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4277 .suspend = alc_suspend,
cb53c626
TI
4278 .check_power_status = alc_check_power_status,
4279#endif
c97259df 4280 .reboot_notify = alc_shutup,
1da177e4
LT
4281};
4282
c027ddcd
KY
4283/* replace the codec chip_name with the given string */
4284static int alc_codec_rename(struct hda_codec *codec, const char *name)
4285{
4286 kfree(codec->chip_name);
4287 codec->chip_name = kstrdup(name, GFP_KERNEL);
4288 if (!codec->chip_name) {
4289 alc_free(codec);
4290 return -ENOMEM;
4291 }
4292 return 0;
4293}
4294
2fa522be
TI
4295/*
4296 * Test configuration for debugging
4297 *
4298 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4299 * enum controls.
4300 */
4301#ifdef CONFIG_SND_DEBUG
4302static hda_nid_t alc880_test_dac_nids[4] = {
4303 0x02, 0x03, 0x04, 0x05
4304};
4305
4306static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4307 .num_items = 7,
2fa522be
TI
4308 .items = {
4309 { "In-1", 0x0 },
4310 { "In-2", 0x1 },
4311 { "In-3", 0x2 },
4312 { "In-4", 0x3 },
4313 { "CD", 0x4 },
ae6b813a
TI
4314 { "Front", 0x5 },
4315 { "Surround", 0x6 },
2fa522be
TI
4316 },
4317};
4318
d2a6d7dc 4319static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4320 { 2, NULL },
fd2c326d 4321 { 4, NULL },
2fa522be 4322 { 6, NULL },
fd2c326d 4323 { 8, NULL },
2fa522be
TI
4324};
4325
9c7f852e
TI
4326static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4327 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4328{
4329 static char *texts[] = {
4330 "N/A", "Line Out", "HP Out",
4331 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4332 };
4333 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4334 uinfo->count = 1;
4335 uinfo->value.enumerated.items = 8;
4336 if (uinfo->value.enumerated.item >= 8)
4337 uinfo->value.enumerated.item = 7;
4338 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4339 return 0;
4340}
4341
9c7f852e
TI
4342static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4343 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4344{
4345 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4346 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4347 unsigned int pin_ctl, item = 0;
4348
4349 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4350 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4351 if (pin_ctl & AC_PINCTL_OUT_EN) {
4352 if (pin_ctl & AC_PINCTL_HP_EN)
4353 item = 2;
4354 else
4355 item = 1;
4356 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4357 switch (pin_ctl & AC_PINCTL_VREFEN) {
4358 case AC_PINCTL_VREF_HIZ: item = 3; break;
4359 case AC_PINCTL_VREF_50: item = 4; break;
4360 case AC_PINCTL_VREF_GRD: item = 5; break;
4361 case AC_PINCTL_VREF_80: item = 6; break;
4362 case AC_PINCTL_VREF_100: item = 7; break;
4363 }
4364 }
4365 ucontrol->value.enumerated.item[0] = item;
4366 return 0;
4367}
4368
9c7f852e
TI
4369static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4370 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4371{
4372 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4373 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4374 static unsigned int ctls[] = {
4375 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4376 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4377 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4378 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4379 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4380 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4381 };
4382 unsigned int old_ctl, new_ctl;
4383
4384 old_ctl = snd_hda_codec_read(codec, nid, 0,
4385 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4386 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4387 if (old_ctl != new_ctl) {
82beb8fd
TI
4388 int val;
4389 snd_hda_codec_write_cache(codec, nid, 0,
4390 AC_VERB_SET_PIN_WIDGET_CONTROL,
4391 new_ctl);
47fd830a
TI
4392 val = ucontrol->value.enumerated.item[0] >= 3 ?
4393 HDA_AMP_MUTE : 0;
4394 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4395 HDA_AMP_MUTE, val);
2fa522be
TI
4396 return 1;
4397 }
4398 return 0;
4399}
4400
9c7f852e
TI
4401static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4402 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4403{
4404 static char *texts[] = {
4405 "Front", "Surround", "CLFE", "Side"
4406 };
4407 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4408 uinfo->count = 1;
4409 uinfo->value.enumerated.items = 4;
4410 if (uinfo->value.enumerated.item >= 4)
4411 uinfo->value.enumerated.item = 3;
4412 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4413 return 0;
4414}
4415
9c7f852e
TI
4416static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4417 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4418{
4419 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4420 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4421 unsigned int sel;
4422
4423 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4424 ucontrol->value.enumerated.item[0] = sel & 3;
4425 return 0;
4426}
4427
9c7f852e
TI
4428static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4429 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4430{
4431 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4432 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4433 unsigned int sel;
4434
4435 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4436 if (ucontrol->value.enumerated.item[0] != sel) {
4437 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4438 snd_hda_codec_write_cache(codec, nid, 0,
4439 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4440 return 1;
4441 }
4442 return 0;
4443}
4444
4445#define PIN_CTL_TEST(xname,nid) { \
4446 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4447 .name = xname, \
5b0cb1d8 4448 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4449 .info = alc_test_pin_ctl_info, \
4450 .get = alc_test_pin_ctl_get, \
4451 .put = alc_test_pin_ctl_put, \
4452 .private_value = nid \
4453 }
4454
4455#define PIN_SRC_TEST(xname,nid) { \
4456 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4457 .name = xname, \
5b0cb1d8 4458 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4459 .info = alc_test_pin_src_info, \
4460 .get = alc_test_pin_src_get, \
4461 .put = alc_test_pin_src_put, \
4462 .private_value = nid \
4463 }
4464
c8b6bf9b 4465static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4466 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4467 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4468 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4469 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4470 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4471 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4472 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4473 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4474 PIN_CTL_TEST("Front Pin Mode", 0x14),
4475 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4476 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4477 PIN_CTL_TEST("Side Pin Mode", 0x17),
4478 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4479 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4480 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4481 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4482 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4483 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4484 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4485 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4486 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4487 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4488 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4489 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4490 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4491 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4492 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4493 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4494 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4495 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4496 {
4497 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4498 .name = "Channel Mode",
df694daa
KY
4499 .info = alc_ch_mode_info,
4500 .get = alc_ch_mode_get,
4501 .put = alc_ch_mode_put,
2fa522be
TI
4502 },
4503 { } /* end */
4504};
4505
4506static struct hda_verb alc880_test_init_verbs[] = {
4507 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4508 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4510 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4511 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4512 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4513 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4514 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4515 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4516 /* Vol output for 0x0c-0x0f */
05acb863
TI
4517 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4518 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4519 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4520 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4521 /* Set output pins 0x14-0x17 */
05acb863
TI
4522 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4523 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4524 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4525 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4526 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4527 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4528 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4529 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4530 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4531 /* Set input pins 0x18-0x1c */
16ded525
TI
4532 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4533 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4534 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4535 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4536 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4537 /* Mute input pins 0x18-0x1b */
05acb863
TI
4538 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4539 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4540 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4541 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4542 /* ADC set up */
05acb863 4543 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4544 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4545 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4546 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4547 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4548 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4549 /* Analog input/passthru */
4550 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4551 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4552 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4553 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4554 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4555 { }
4556};
4557#endif
4558
1da177e4
LT
4559/*
4560 */
4561
f5fcc13c
TI
4562static const char *alc880_models[ALC880_MODEL_LAST] = {
4563 [ALC880_3ST] = "3stack",
4564 [ALC880_TCL_S700] = "tcl",
4565 [ALC880_3ST_DIG] = "3stack-digout",
4566 [ALC880_CLEVO] = "clevo",
4567 [ALC880_5ST] = "5stack",
4568 [ALC880_5ST_DIG] = "5stack-digout",
4569 [ALC880_W810] = "w810",
4570 [ALC880_Z71V] = "z71v",
4571 [ALC880_6ST] = "6stack",
4572 [ALC880_6ST_DIG] = "6stack-digout",
4573 [ALC880_ASUS] = "asus",
4574 [ALC880_ASUS_W1V] = "asus-w1v",
4575 [ALC880_ASUS_DIG] = "asus-dig",
4576 [ALC880_ASUS_DIG2] = "asus-dig2",
4577 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4578 [ALC880_UNIWILL_P53] = "uniwill-p53",
4579 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4580 [ALC880_F1734] = "F1734",
4581 [ALC880_LG] = "lg",
4582 [ALC880_LG_LW] = "lg-lw",
df99cd33 4583 [ALC880_MEDION_RIM] = "medion",
2fa522be 4584#ifdef CONFIG_SND_DEBUG
f5fcc13c 4585 [ALC880_TEST] = "test",
2fa522be 4586#endif
f5fcc13c
TI
4587 [ALC880_AUTO] = "auto",
4588};
4589
4590static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4591 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4592 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4593 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4594 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4595 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4596 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4597 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4598 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4599 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4600 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4601 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4602 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4603 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4604 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4605 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4606 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4607 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4608 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4609 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4610 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4611 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4612 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4613 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4614 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4615 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4616 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4617 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4618 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4619 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4620 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4621 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4622 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4623 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4624 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4625 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4626 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4627 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4628 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4629 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4630 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 4631 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
4632 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4633 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4634 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4635 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4636 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4637 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4638 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4639 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4640 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4641 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4642 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c 4643 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
77c4d5cd 4644 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
f5fcc13c 4645 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4646 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4647 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4648 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4649 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4650 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4651 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4652 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4653 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4654 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4655 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4656 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4657 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4658 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4659 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4660 /* default Intel */
4661 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4662 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4663 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4664 {}
4665};
4666
16ded525 4667/*
df694daa 4668 * ALC880 codec presets
16ded525 4669 */
16ded525
TI
4670static struct alc_config_preset alc880_presets[] = {
4671 [ALC880_3ST] = {
e9edcee0 4672 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4673 .init_verbs = { alc880_volume_init_verbs,
4674 alc880_pin_3stack_init_verbs },
16ded525 4675 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4676 .dac_nids = alc880_dac_nids,
16ded525
TI
4677 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4678 .channel_mode = alc880_threestack_modes,
4e195a7b 4679 .need_dac_fix = 1,
16ded525
TI
4680 .input_mux = &alc880_capture_source,
4681 },
4682 [ALC880_3ST_DIG] = {
e9edcee0 4683 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4684 .init_verbs = { alc880_volume_init_verbs,
4685 alc880_pin_3stack_init_verbs },
16ded525 4686 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4687 .dac_nids = alc880_dac_nids,
4688 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4689 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4690 .channel_mode = alc880_threestack_modes,
4e195a7b 4691 .need_dac_fix = 1,
16ded525
TI
4692 .input_mux = &alc880_capture_source,
4693 },
df694daa
KY
4694 [ALC880_TCL_S700] = {
4695 .mixers = { alc880_tcl_s700_mixer },
4696 .init_verbs = { alc880_volume_init_verbs,
4697 alc880_pin_tcl_S700_init_verbs,
4698 alc880_gpio2_init_verbs },
4699 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4700 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4701 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4702 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4703 .hp_nid = 0x03,
4704 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4705 .channel_mode = alc880_2_jack_modes,
4706 .input_mux = &alc880_capture_source,
4707 },
16ded525 4708 [ALC880_5ST] = {
f12ab1e0
TI
4709 .mixers = { alc880_three_stack_mixer,
4710 alc880_five_stack_mixer},
4711 .init_verbs = { alc880_volume_init_verbs,
4712 alc880_pin_5stack_init_verbs },
16ded525
TI
4713 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4714 .dac_nids = alc880_dac_nids,
16ded525
TI
4715 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4716 .channel_mode = alc880_fivestack_modes,
4717 .input_mux = &alc880_capture_source,
4718 },
4719 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4720 .mixers = { alc880_three_stack_mixer,
4721 alc880_five_stack_mixer },
4722 .init_verbs = { alc880_volume_init_verbs,
4723 alc880_pin_5stack_init_verbs },
16ded525
TI
4724 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4725 .dac_nids = alc880_dac_nids,
4726 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4727 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4728 .channel_mode = alc880_fivestack_modes,
4729 .input_mux = &alc880_capture_source,
4730 },
b6482d48
TI
4731 [ALC880_6ST] = {
4732 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4733 .init_verbs = { alc880_volume_init_verbs,
4734 alc880_pin_6stack_init_verbs },
b6482d48
TI
4735 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4736 .dac_nids = alc880_6st_dac_nids,
4737 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4738 .channel_mode = alc880_sixstack_modes,
4739 .input_mux = &alc880_6stack_capture_source,
4740 },
16ded525 4741 [ALC880_6ST_DIG] = {
e9edcee0 4742 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4743 .init_verbs = { alc880_volume_init_verbs,
4744 alc880_pin_6stack_init_verbs },
16ded525
TI
4745 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4746 .dac_nids = alc880_6st_dac_nids,
4747 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4748 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4749 .channel_mode = alc880_sixstack_modes,
4750 .input_mux = &alc880_6stack_capture_source,
4751 },
4752 [ALC880_W810] = {
e9edcee0 4753 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4754 .init_verbs = { alc880_volume_init_verbs,
4755 alc880_pin_w810_init_verbs,
b0af0de5 4756 alc880_gpio2_init_verbs },
16ded525
TI
4757 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4758 .dac_nids = alc880_w810_dac_nids,
4759 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4760 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4761 .channel_mode = alc880_w810_modes,
4762 .input_mux = &alc880_capture_source,
4763 },
4764 [ALC880_Z71V] = {
e9edcee0 4765 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
4766 .init_verbs = { alc880_volume_init_verbs,
4767 alc880_pin_z71v_init_verbs },
16ded525
TI
4768 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4769 .dac_nids = alc880_z71v_dac_nids,
4770 .dig_out_nid = ALC880_DIGOUT_NID,
4771 .hp_nid = 0x03,
e9edcee0
TI
4772 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4773 .channel_mode = alc880_2_jack_modes,
16ded525
TI
4774 .input_mux = &alc880_capture_source,
4775 },
4776 [ALC880_F1734] = {
e9edcee0 4777 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
4778 .init_verbs = { alc880_volume_init_verbs,
4779 alc880_pin_f1734_init_verbs },
e9edcee0
TI
4780 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4781 .dac_nids = alc880_f1734_dac_nids,
4782 .hp_nid = 0x02,
4783 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4784 .channel_mode = alc880_2_jack_modes,
937b4160
TI
4785 .input_mux = &alc880_f1734_capture_source,
4786 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4787 .setup = alc880_uniwill_p53_setup,
4788 .init_hook = alc_automute_amp,
16ded525
TI
4789 },
4790 [ALC880_ASUS] = {
e9edcee0 4791 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4792 .init_verbs = { alc880_volume_init_verbs,
4793 alc880_pin_asus_init_verbs,
e9edcee0
TI
4794 alc880_gpio1_init_verbs },
4795 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4796 .dac_nids = alc880_asus_dac_nids,
4797 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4798 .channel_mode = alc880_asus_modes,
4e195a7b 4799 .need_dac_fix = 1,
16ded525
TI
4800 .input_mux = &alc880_capture_source,
4801 },
4802 [ALC880_ASUS_DIG] = {
e9edcee0 4803 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4804 .init_verbs = { alc880_volume_init_verbs,
4805 alc880_pin_asus_init_verbs,
e9edcee0
TI
4806 alc880_gpio1_init_verbs },
4807 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4808 .dac_nids = alc880_asus_dac_nids,
16ded525 4809 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4810 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4811 .channel_mode = alc880_asus_modes,
4e195a7b 4812 .need_dac_fix = 1,
16ded525
TI
4813 .input_mux = &alc880_capture_source,
4814 },
df694daa
KY
4815 [ALC880_ASUS_DIG2] = {
4816 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4817 .init_verbs = { alc880_volume_init_verbs,
4818 alc880_pin_asus_init_verbs,
df694daa
KY
4819 alc880_gpio2_init_verbs }, /* use GPIO2 */
4820 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4821 .dac_nids = alc880_asus_dac_nids,
4822 .dig_out_nid = ALC880_DIGOUT_NID,
4823 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4824 .channel_mode = alc880_asus_modes,
4e195a7b 4825 .need_dac_fix = 1,
df694daa
KY
4826 .input_mux = &alc880_capture_source,
4827 },
16ded525 4828 [ALC880_ASUS_W1V] = {
e9edcee0 4829 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
4830 .init_verbs = { alc880_volume_init_verbs,
4831 alc880_pin_asus_init_verbs,
e9edcee0
TI
4832 alc880_gpio1_init_verbs },
4833 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4834 .dac_nids = alc880_asus_dac_nids,
16ded525 4835 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4836 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4837 .channel_mode = alc880_asus_modes,
4e195a7b 4838 .need_dac_fix = 1,
16ded525
TI
4839 .input_mux = &alc880_capture_source,
4840 },
4841 [ALC880_UNIWILL_DIG] = {
45bdd1c1 4842 .mixers = { alc880_asus_mixer },
ccc656ce
KY
4843 .init_verbs = { alc880_volume_init_verbs,
4844 alc880_pin_asus_init_verbs },
e9edcee0
TI
4845 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4846 .dac_nids = alc880_asus_dac_nids,
16ded525 4847 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4848 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4849 .channel_mode = alc880_asus_modes,
4e195a7b 4850 .need_dac_fix = 1,
16ded525
TI
4851 .input_mux = &alc880_capture_source,
4852 },
ccc656ce
KY
4853 [ALC880_UNIWILL] = {
4854 .mixers = { alc880_uniwill_mixer },
4855 .init_verbs = { alc880_volume_init_verbs,
4856 alc880_uniwill_init_verbs },
4857 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4858 .dac_nids = alc880_asus_dac_nids,
4859 .dig_out_nid = ALC880_DIGOUT_NID,
4860 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4861 .channel_mode = alc880_threestack_modes,
4862 .need_dac_fix = 1,
4863 .input_mux = &alc880_capture_source,
4864 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 4865 .setup = alc880_uniwill_setup,
a9fd4f3f 4866 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
4867 },
4868 [ALC880_UNIWILL_P53] = {
4869 .mixers = { alc880_uniwill_p53_mixer },
4870 .init_verbs = { alc880_volume_init_verbs,
4871 alc880_uniwill_p53_init_verbs },
4872 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4873 .dac_nids = alc880_asus_dac_nids,
4874 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4875 .channel_mode = alc880_threestack_modes,
4876 .input_mux = &alc880_capture_source,
4877 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4878 .setup = alc880_uniwill_p53_setup,
4879 .init_hook = alc_automute_amp,
2cf9f0fc
TD
4880 },
4881 [ALC880_FUJITSU] = {
45bdd1c1 4882 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4883 .init_verbs = { alc880_volume_init_verbs,
4884 alc880_uniwill_p53_init_verbs,
4885 alc880_beep_init_verbs },
4886 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4887 .dac_nids = alc880_dac_nids,
d53d7d9e 4888 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4889 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4890 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4891 .input_mux = &alc880_capture_source,
4892 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4893 .setup = alc880_uniwill_p53_setup,
4894 .init_hook = alc_automute_amp,
ccc656ce 4895 },
df694daa
KY
4896 [ALC880_CLEVO] = {
4897 .mixers = { alc880_three_stack_mixer },
4898 .init_verbs = { alc880_volume_init_verbs,
4899 alc880_pin_clevo_init_verbs },
4900 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4901 .dac_nids = alc880_dac_nids,
4902 .hp_nid = 0x03,
4903 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4904 .channel_mode = alc880_threestack_modes,
4e195a7b 4905 .need_dac_fix = 1,
df694daa
KY
4906 .input_mux = &alc880_capture_source,
4907 },
ae6b813a
TI
4908 [ALC880_LG] = {
4909 .mixers = { alc880_lg_mixer },
4910 .init_verbs = { alc880_volume_init_verbs,
4911 alc880_lg_init_verbs },
4912 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4913 .dac_nids = alc880_lg_dac_nids,
4914 .dig_out_nid = ALC880_DIGOUT_NID,
4915 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4916 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4917 .need_dac_fix = 1,
ae6b813a 4918 .input_mux = &alc880_lg_capture_source,
a9fd4f3f 4919 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4920 .setup = alc880_lg_setup,
4921 .init_hook = alc_automute_amp,
cb53c626
TI
4922#ifdef CONFIG_SND_HDA_POWER_SAVE
4923 .loopbacks = alc880_lg_loopbacks,
4924#endif
ae6b813a 4925 },
d681518a
TI
4926 [ALC880_LG_LW] = {
4927 .mixers = { alc880_lg_lw_mixer },
4928 .init_verbs = { alc880_volume_init_verbs,
4929 alc880_lg_lw_init_verbs },
0a8c5da3 4930 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
4931 .dac_nids = alc880_dac_nids,
4932 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
4933 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4934 .channel_mode = alc880_lg_lw_modes,
d681518a 4935 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f 4936 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4937 .setup = alc880_lg_lw_setup,
4938 .init_hook = alc_automute_amp,
d681518a 4939 },
df99cd33
TI
4940 [ALC880_MEDION_RIM] = {
4941 .mixers = { alc880_medion_rim_mixer },
4942 .init_verbs = { alc880_volume_init_verbs,
4943 alc880_medion_rim_init_verbs,
4944 alc_gpio2_init_verbs },
4945 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4946 .dac_nids = alc880_dac_nids,
4947 .dig_out_nid = ALC880_DIGOUT_NID,
4948 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4949 .channel_mode = alc880_2_jack_modes,
4950 .input_mux = &alc880_medion_rim_capture_source,
4951 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
4952 .setup = alc880_medion_rim_setup,
4953 .init_hook = alc880_medion_rim_automute,
df99cd33 4954 },
16ded525
TI
4955#ifdef CONFIG_SND_DEBUG
4956 [ALC880_TEST] = {
e9edcee0
TI
4957 .mixers = { alc880_test_mixer },
4958 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
4959 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4960 .dac_nids = alc880_test_dac_nids,
4961 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4962 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4963 .channel_mode = alc880_test_modes,
4964 .input_mux = &alc880_test_capture_source,
4965 },
4966#endif
4967};
4968
e9edcee0
TI
4969/*
4970 * Automatic parse of I/O pins from the BIOS configuration
4971 */
4972
e9edcee0
TI
4973enum {
4974 ALC_CTL_WIDGET_VOL,
4975 ALC_CTL_WIDGET_MUTE,
4976 ALC_CTL_BIND_MUTE,
4977};
c8b6bf9b 4978static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
4979 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4980 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 4981 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
4982};
4983
4984/* add dynamic controls */
f12ab1e0 4985static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 4986 int cidx, unsigned long val)
e9edcee0 4987{
c8b6bf9b 4988 struct snd_kcontrol_new *knew;
e9edcee0 4989
603c4019
TI
4990 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4991 knew = snd_array_new(&spec->kctls);
4992 if (!knew)
4993 return -ENOMEM;
e9edcee0 4994 *knew = alc880_control_templates[type];
543537bd 4995 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 4996 if (!knew->name)
e9edcee0 4997 return -ENOMEM;
66ceeb6b 4998 knew->index = cidx;
4d02d1b6 4999 if (get_amp_nid_(val))
5e26dfd0 5000 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 5001 knew->private_value = val;
e9edcee0
TI
5002 return 0;
5003}
5004
0afe5f89
TI
5005static int add_control_with_pfx(struct alc_spec *spec, int type,
5006 const char *pfx, const char *dir,
66ceeb6b 5007 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
5008{
5009 char name[32];
5010 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 5011 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
5012}
5013
66ceeb6b
TI
5014#define add_pb_vol_ctrl(spec, type, pfx, val) \
5015 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5016#define add_pb_sw_ctrl(spec, type, pfx, val) \
5017 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5018#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5019 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5020#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5021 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 5022
e9edcee0
TI
5023#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5024#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5025#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5026#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
5027#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5028#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5029#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5030#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5031#define ALC880_PIN_CD_NID 0x1c
5032
5033/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
5034static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5035 const struct auto_pin_cfg *cfg)
e9edcee0
TI
5036{
5037 hda_nid_t nid;
5038 int assigned[4];
5039 int i, j;
5040
5041 memset(assigned, 0, sizeof(assigned));
b0af0de5 5042 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
5043
5044 /* check the pins hardwired to audio widget */
5045 for (i = 0; i < cfg->line_outs; i++) {
5046 nid = cfg->line_out_pins[i];
5047 if (alc880_is_fixed_pin(nid)) {
5048 int idx = alc880_fixed_pin_idx(nid);
5014f193 5049 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
5050 assigned[idx] = 1;
5051 }
5052 }
5053 /* left pins can be connect to any audio widget */
5054 for (i = 0; i < cfg->line_outs; i++) {
5055 nid = cfg->line_out_pins[i];
5056 if (alc880_is_fixed_pin(nid))
5057 continue;
5058 /* search for an empty channel */
5059 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
5060 if (!assigned[j]) {
5061 spec->multiout.dac_nids[i] =
5062 alc880_idx_to_dac(j);
e9edcee0
TI
5063 assigned[j] = 1;
5064 break;
5065 }
5066 }
5067 }
5068 spec->multiout.num_dacs = cfg->line_outs;
5069 return 0;
5070}
5071
bcb2f0f5
TI
5072static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg,
5073 bool can_be_master)
5074{
5075 if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5076 return "Master";
5077
5078 switch (cfg->line_out_type) {
5079 case AUTO_PIN_SPEAKER_OUT:
5080 return "Speaker";
5081 case AUTO_PIN_HP_OUT:
5082 return "Headphone";
5083 default:
5084 if (cfg->line_outs == 1)
5085 return "PCM";
5086 break;
5087 }
5088 return NULL;
5089}
5090
e9edcee0 5091/* add playback controls from the parsed DAC table */
df694daa
KY
5092static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5093 const struct auto_pin_cfg *cfg)
e9edcee0 5094{
f12ab1e0
TI
5095 static const char *chname[4] = {
5096 "Front", "Surround", NULL /*CLFE*/, "Side"
5097 };
bcb2f0f5 5098 const char *pfx = alc_get_line_out_pfx(cfg, false);
e9edcee0
TI
5099 hda_nid_t nid;
5100 int i, err;
5101
5102 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 5103 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
5104 continue;
5105 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
bcb2f0f5 5106 if (!pfx && i == 2) {
e9edcee0 5107 /* Center/LFE */
0afe5f89
TI
5108 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5109 "Center",
f12ab1e0
TI
5110 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5111 HDA_OUTPUT));
5112 if (err < 0)
e9edcee0 5113 return err;
0afe5f89
TI
5114 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5115 "LFE",
f12ab1e0
TI
5116 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5117 HDA_OUTPUT));
5118 if (err < 0)
e9edcee0 5119 return err;
0afe5f89
TI
5120 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5121 "Center",
f12ab1e0
TI
5122 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5123 HDA_INPUT));
5124 if (err < 0)
e9edcee0 5125 return err;
0afe5f89
TI
5126 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5127 "LFE",
f12ab1e0
TI
5128 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5129 HDA_INPUT));
5130 if (err < 0)
e9edcee0
TI
5131 return err;
5132 } else {
bcb2f0f5
TI
5133 const char *name = pfx;
5134 if (!name)
5135 name = chname[i];
5136 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5137 name, i,
f12ab1e0
TI
5138 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5139 HDA_OUTPUT));
5140 if (err < 0)
e9edcee0 5141 return err;
bcb2f0f5
TI
5142 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5143 name, i,
f12ab1e0
TI
5144 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5145 HDA_INPUT));
5146 if (err < 0)
e9edcee0
TI
5147 return err;
5148 }
5149 }
e9edcee0
TI
5150 return 0;
5151}
5152
8d88bc3d
TI
5153/* add playback controls for speaker and HP outputs */
5154static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5155 const char *pfx)
e9edcee0
TI
5156{
5157 hda_nid_t nid;
5158 int err;
5159
f12ab1e0 5160 if (!pin)
e9edcee0
TI
5161 return 0;
5162
5163 if (alc880_is_fixed_pin(pin)) {
5164 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5165 /* specify the DAC as the extra output */
f12ab1e0 5166 if (!spec->multiout.hp_nid)
e9edcee0 5167 spec->multiout.hp_nid = nid;
82bc955f
TI
5168 else
5169 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5170 /* control HP volume/switch on the output mixer amp */
5171 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5172 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5173 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5174 if (err < 0)
e9edcee0 5175 return err;
0afe5f89 5176 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5177 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5178 if (err < 0)
e9edcee0
TI
5179 return err;
5180 } else if (alc880_is_multi_pin(pin)) {
5181 /* set manual connection */
e9edcee0 5182 /* we have only a switch on HP-out PIN */
0afe5f89 5183 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5184 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5185 if (err < 0)
e9edcee0
TI
5186 return err;
5187 }
5188 return 0;
5189}
5190
5191/* create input playback/capture controls for the given pin */
f12ab1e0 5192static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5193 const char *ctlname, int ctlidx,
df694daa 5194 int idx, hda_nid_t mix_nid)
e9edcee0 5195{
df694daa 5196 int err;
e9edcee0 5197
66ceeb6b 5198 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5199 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5200 if (err < 0)
e9edcee0 5201 return err;
66ceeb6b 5202 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5203 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5204 if (err < 0)
e9edcee0
TI
5205 return err;
5206 return 0;
5207}
5208
05f5f477
TI
5209static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5210{
5211 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5212 return (pincap & AC_PINCAP_IN) != 0;
5213}
5214
e9edcee0 5215/* create playback/capture controls for input pins */
05f5f477
TI
5216static int alc_auto_create_input_ctls(struct hda_codec *codec,
5217 const struct auto_pin_cfg *cfg,
5218 hda_nid_t mixer,
5219 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5220{
05f5f477 5221 struct alc_spec *spec = codec->spec;
61b9b9b1 5222 struct hda_input_mux *imux = &spec->private_imux[0];
5322bf27
DH
5223 int i, err, idx, type_idx = 0;
5224 const char *prev_label = NULL;
e9edcee0 5225
66ceeb6b 5226 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5227 hda_nid_t pin;
10a20af7 5228 const char *label;
05f5f477 5229
66ceeb6b 5230 pin = cfg->inputs[i].pin;
05f5f477
TI
5231 if (!alc_is_input_pin(codec, pin))
5232 continue;
5233
5322bf27
DH
5234 label = hda_get_autocfg_input_label(codec, cfg, i);
5235 if (prev_label && !strcmp(label, prev_label))
66ceeb6b
TI
5236 type_idx++;
5237 else
5238 type_idx = 0;
5322bf27
DH
5239 prev_label = label;
5240
05f5f477
TI
5241 if (mixer) {
5242 idx = get_connection_index(codec, mixer, pin);
5243 if (idx >= 0) {
5244 err = new_analog_input(spec, pin,
10a20af7
TI
5245 label, type_idx,
5246 idx, mixer);
05f5f477
TI
5247 if (err < 0)
5248 return err;
5249 }
5250 }
5251
5252 if (!cap1)
5253 continue;
5254 idx = get_connection_index(codec, cap1, pin);
5255 if (idx < 0 && cap2)
5256 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5257 if (idx >= 0)
5258 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5259 }
5260 return 0;
5261}
5262
05f5f477
TI
5263static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5264 const struct auto_pin_cfg *cfg)
5265{
5266 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5267}
5268
f6c7e546
TI
5269static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5270 unsigned int pin_type)
5271{
5272 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5273 pin_type);
5274 /* unmute pin */
d260cdf6
TI
5275 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5276 AMP_OUT_UNMUTE);
f6c7e546
TI
5277}
5278
df694daa
KY
5279static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5280 hda_nid_t nid, int pin_type,
e9edcee0
TI
5281 int dac_idx)
5282{
f6c7e546 5283 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5284 /* need the manual connection? */
5285 if (alc880_is_multi_pin(nid)) {
5286 struct alc_spec *spec = codec->spec;
5287 int idx = alc880_multi_pin_idx(nid);
5288 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5289 AC_VERB_SET_CONNECT_SEL,
5290 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5291 }
5292}
5293
baba8ee9
TI
5294static int get_pin_type(int line_out_type)
5295{
5296 if (line_out_type == AUTO_PIN_HP_OUT)
5297 return PIN_HP;
5298 else
5299 return PIN_OUT;
5300}
5301
e9edcee0
TI
5302static void alc880_auto_init_multi_out(struct hda_codec *codec)
5303{
5304 struct alc_spec *spec = codec->spec;
5305 int i;
ea1fb29a 5306
e9edcee0
TI
5307 for (i = 0; i < spec->autocfg.line_outs; i++) {
5308 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5309 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5310 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5311 }
5312}
5313
8d88bc3d 5314static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5315{
5316 struct alc_spec *spec = codec->spec;
5317 hda_nid_t pin;
5318
82bc955f 5319 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5320 if (pin) /* connect to front */
5321 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5322 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5323 if (pin) /* connect to front */
5324 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5325}
5326
5327static void alc880_auto_init_analog_input(struct hda_codec *codec)
5328{
5329 struct alc_spec *spec = codec->spec;
66ceeb6b 5330 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5331 int i;
5332
66ceeb6b
TI
5333 for (i = 0; i < cfg->num_inputs; i++) {
5334 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5335 if (alc_is_input_pin(codec, nid)) {
30ea098f 5336 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
5337 if (nid != ALC880_PIN_CD_NID &&
5338 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5339 snd_hda_codec_write(codec, nid, 0,
5340 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5341 AMP_OUT_MUTE);
5342 }
5343 }
5344}
5345
7f311a46
TI
5346static void alc880_auto_init_input_src(struct hda_codec *codec)
5347{
5348 struct alc_spec *spec = codec->spec;
5349 int c;
5350
5351 for (c = 0; c < spec->num_adc_nids; c++) {
5352 unsigned int mux_idx;
5353 const struct hda_input_mux *imux;
5354 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5355 imux = &spec->input_mux[mux_idx];
5356 if (!imux->num_items && mux_idx > 0)
5357 imux = &spec->input_mux[0];
5358 if (imux)
5359 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5360 AC_VERB_SET_CONNECT_SEL,
5361 imux->items[0].index);
5362 }
5363}
5364
e9edcee0 5365/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5366/* return 1 if successful, 0 if the proper config is not found,
5367 * or a negative error code
5368 */
e9edcee0
TI
5369static int alc880_parse_auto_config(struct hda_codec *codec)
5370{
5371 struct alc_spec *spec = codec->spec;
757899ac 5372 int err;
df694daa 5373 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5374
f12ab1e0
TI
5375 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5376 alc880_ignore);
5377 if (err < 0)
e9edcee0 5378 return err;
f12ab1e0 5379 if (!spec->autocfg.line_outs)
e9edcee0 5380 return 0; /* can't find valid BIOS pin config */
df694daa 5381
f12ab1e0
TI
5382 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5383 if (err < 0)
5384 return err;
5385 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5386 if (err < 0)
5387 return err;
5388 err = alc880_auto_create_extra_out(spec,
5389 spec->autocfg.speaker_pins[0],
5390 "Speaker");
5391 if (err < 0)
5392 return err;
5393 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5394 "Headphone");
5395 if (err < 0)
5396 return err;
05f5f477 5397 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5398 if (err < 0)
e9edcee0
TI
5399 return err;
5400
5401 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5402
757899ac 5403 alc_auto_parse_digital(codec);
e9edcee0 5404
603c4019 5405 if (spec->kctls.list)
d88897ea 5406 add_mixer(spec, spec->kctls.list);
e9edcee0 5407
d88897ea 5408 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5409
a1e8d2da 5410 spec->num_mux_defs = 1;
61b9b9b1 5411 spec->input_mux = &spec->private_imux[0];
e9edcee0 5412
6227cdce 5413 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5414
e9edcee0
TI
5415 return 1;
5416}
5417
ae6b813a
TI
5418/* additional initialization for auto-configuration model */
5419static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5420{
f6c7e546 5421 struct alc_spec *spec = codec->spec;
e9edcee0 5422 alc880_auto_init_multi_out(codec);
8d88bc3d 5423 alc880_auto_init_extra_out(codec);
e9edcee0 5424 alc880_auto_init_analog_input(codec);
7f311a46 5425 alc880_auto_init_input_src(codec);
757899ac 5426 alc_auto_init_digital(codec);
f6c7e546 5427 if (spec->unsol_event)
7fb0d78f 5428 alc_inithook(codec);
e9edcee0
TI
5429}
5430
b59bdf3b
TI
5431/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5432 * one of two digital mic pins, e.g. on ALC272
5433 */
5434static void fixup_automic_adc(struct hda_codec *codec)
5435{
5436 struct alc_spec *spec = codec->spec;
5437 int i;
5438
5439 for (i = 0; i < spec->num_adc_nids; i++) {
5440 hda_nid_t cap = spec->capsrc_nids ?
5441 spec->capsrc_nids[i] : spec->adc_nids[i];
5442 int iidx, eidx;
5443
5444 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5445 if (iidx < 0)
5446 continue;
5447 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5448 if (eidx < 0)
5449 continue;
5450 spec->int_mic.mux_idx = iidx;
5451 spec->ext_mic.mux_idx = eidx;
5452 if (spec->capsrc_nids)
5453 spec->capsrc_nids += i;
5454 spec->adc_nids += i;
5455 spec->num_adc_nids = 1;
5456 return;
5457 }
5458 snd_printd(KERN_INFO "hda_codec: %s: "
5459 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5460 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5461 spec->auto_mic = 0; /* disable auto-mic to be sure */
5462}
5463
748cce43
TI
5464/* select or unmute the given capsrc route */
5465static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5466 int idx)
5467{
5468 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5469 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5470 HDA_AMP_MUTE, 0);
5471 } else {
5472 snd_hda_codec_write_cache(codec, cap, 0,
5473 AC_VERB_SET_CONNECT_SEL, idx);
5474 }
5475}
5476
840b64c0
TI
5477/* set the default connection to that pin */
5478static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5479{
5480 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5481 int i;
5482
eaa9b3a7
TI
5483 for (i = 0; i < spec->num_adc_nids; i++) {
5484 hda_nid_t cap = spec->capsrc_nids ?
5485 spec->capsrc_nids[i] : spec->adc_nids[i];
5486 int idx;
5487
5488 idx = get_connection_index(codec, cap, pin);
5489 if (idx < 0)
5490 continue;
748cce43 5491 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5492 return i; /* return the found index */
5493 }
5494 return -1; /* not found */
5495}
5496
5497/* choose the ADC/MUX containing the input pin and initialize the setup */
5498static void fixup_single_adc(struct hda_codec *codec)
5499{
5500 struct alc_spec *spec = codec->spec;
66ceeb6b 5501 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5502 int i;
5503
5504 /* search for the input pin; there must be only one */
66ceeb6b 5505 if (cfg->num_inputs != 1)
eaa9b3a7 5506 return;
66ceeb6b 5507 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5508 if (i >= 0) {
5509 /* use only this ADC */
5510 if (spec->capsrc_nids)
5511 spec->capsrc_nids += i;
5512 spec->adc_nids += i;
5513 spec->num_adc_nids = 1;
eaa9b3a7
TI
5514 }
5515}
5516
840b64c0
TI
5517/* initialize dual adcs */
5518static void fixup_dual_adc_switch(struct hda_codec *codec)
5519{
5520 struct alc_spec *spec = codec->spec;
5521 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5522 init_capsrc_for_pin(codec, spec->int_mic.pin);
5523}
5524
b59bdf3b 5525static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5526{
b59bdf3b 5527 struct alc_spec *spec = codec->spec;
a23b688f
TI
5528 static struct snd_kcontrol_new *caps[2][3] = {
5529 { alc_capture_mixer_nosrc1,
5530 alc_capture_mixer_nosrc2,
5531 alc_capture_mixer_nosrc3 },
5532 { alc_capture_mixer1,
5533 alc_capture_mixer2,
5534 alc_capture_mixer3 },
f9e336f6 5535 };
a23b688f 5536 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5537 int mux = 0;
840b64c0
TI
5538 int num_adcs = spec->num_adc_nids;
5539 if (spec->dual_adc_switch)
5540 fixup_dual_adc_switch(codec);
5541 else if (spec->auto_mic)
b59bdf3b 5542 fixup_automic_adc(codec);
eaa9b3a7
TI
5543 else if (spec->input_mux) {
5544 if (spec->input_mux->num_items > 1)
5545 mux = 1;
5546 else if (spec->input_mux->num_items == 1)
5547 fixup_single_adc(codec);
5548 }
840b64c0
TI
5549 if (spec->dual_adc_switch)
5550 num_adcs = 1;
5551 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5552 }
f9e336f6
TI
5553}
5554
6694635d
TI
5555/* fill adc_nids (and capsrc_nids) containing all active input pins */
5556static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5557 int num_nids)
5558{
5559 struct alc_spec *spec = codec->spec;
66ceeb6b 5560 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5561 int n;
5562 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5563
5564 for (n = 0; n < num_nids; n++) {
5565 hda_nid_t adc, cap;
5566 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5567 int nconns, i, j;
5568
5569 adc = nids[n];
5570 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5571 continue;
5572 cap = adc;
5573 nconns = snd_hda_get_connections(codec, cap, conn,
5574 ARRAY_SIZE(conn));
5575 if (nconns == 1) {
5576 cap = conn[0];
5577 nconns = snd_hda_get_connections(codec, cap, conn,
5578 ARRAY_SIZE(conn));
5579 }
5580 if (nconns <= 0)
5581 continue;
5582 if (!fallback_adc) {
5583 fallback_adc = adc;
5584 fallback_cap = cap;
5585 }
66ceeb6b
TI
5586 for (i = 0; i < cfg->num_inputs; i++) {
5587 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5588 for (j = 0; j < nconns; j++) {
5589 if (conn[j] == nid)
5590 break;
5591 }
5592 if (j >= nconns)
5593 break;
5594 }
66ceeb6b 5595 if (i >= cfg->num_inputs) {
6694635d
TI
5596 int num_adcs = spec->num_adc_nids;
5597 spec->private_adc_nids[num_adcs] = adc;
5598 spec->private_capsrc_nids[num_adcs] = cap;
5599 spec->num_adc_nids++;
5600 spec->adc_nids = spec->private_adc_nids;
5601 if (adc != cap)
5602 spec->capsrc_nids = spec->private_capsrc_nids;
5603 }
5604 }
5605 if (!spec->num_adc_nids) {
5606 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5607 " using fallback 0x%x\n",
5608 codec->chip_name, fallback_adc);
6694635d
TI
5609 spec->private_adc_nids[0] = fallback_adc;
5610 spec->adc_nids = spec->private_adc_nids;
5611 if (fallback_adc != fallback_cap) {
5612 spec->private_capsrc_nids[0] = fallback_cap;
5613 spec->capsrc_nids = spec->private_adc_nids;
5614 }
5615 }
5616}
5617
67d634c0 5618#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5619#define set_beep_amp(spec, nid, idx, dir) \
5620 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25
TI
5621
5622static struct snd_pci_quirk beep_white_list[] = {
5623 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5624 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
e096c8e6 5625 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5626 {}
5627};
5628
5629static inline int has_cdefine_beep(struct hda_codec *codec)
5630{
5631 struct alc_spec *spec = codec->spec;
5632 const struct snd_pci_quirk *q;
5633 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5634 if (q)
5635 return q->value;
5636 return spec->cdefine.enable_pcbeep;
5637}
67d634c0
TI
5638#else
5639#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5640#define has_cdefine_beep(codec) 0
67d634c0 5641#endif
45bdd1c1
TI
5642
5643/*
5644 * OK, here we have finally the patch for ALC880
5645 */
5646
1da177e4
LT
5647static int patch_alc880(struct hda_codec *codec)
5648{
5649 struct alc_spec *spec;
5650 int board_config;
df694daa 5651 int err;
1da177e4 5652
e560d8d8 5653 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5654 if (spec == NULL)
5655 return -ENOMEM;
5656
5657 codec->spec = spec;
5658
f5fcc13c
TI
5659 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5660 alc880_models,
5661 alc880_cfg_tbl);
5662 if (board_config < 0) {
9a11f1aa
TI
5663 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5664 codec->chip_name);
e9edcee0 5665 board_config = ALC880_AUTO;
1da177e4 5666 }
1da177e4 5667
e9edcee0
TI
5668 if (board_config == ALC880_AUTO) {
5669 /* automatic parse from the BIOS config */
5670 err = alc880_parse_auto_config(codec);
5671 if (err < 0) {
5672 alc_free(codec);
5673 return err;
f12ab1e0 5674 } else if (!err) {
9c7f852e
TI
5675 printk(KERN_INFO
5676 "hda_codec: Cannot set up configuration "
5677 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5678 board_config = ALC880_3ST;
5679 }
1da177e4
LT
5680 }
5681
680cd536
KK
5682 err = snd_hda_attach_beep_device(codec, 0x1);
5683 if (err < 0) {
5684 alc_free(codec);
5685 return err;
5686 }
5687
df694daa 5688 if (board_config != ALC880_AUTO)
e9c364c0 5689 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5690
1da177e4
LT
5691 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5692 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5693 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5694
1da177e4
LT
5695 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5696 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5697
f12ab1e0 5698 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5699 /* check whether NID 0x07 is valid */
54d17403 5700 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5701 /* get type */
a22d543a 5702 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5703 if (wcap != AC_WID_AUD_IN) {
5704 spec->adc_nids = alc880_adc_nids_alt;
5705 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5706 } else {
5707 spec->adc_nids = alc880_adc_nids;
5708 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5709 }
5710 }
b59bdf3b 5711 set_capture_mixer(codec);
45bdd1c1 5712 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5713
2134ea4f
TI
5714 spec->vmaster_nid = 0x0c;
5715
1da177e4 5716 codec->patch_ops = alc_patch_ops;
e9edcee0 5717 if (board_config == ALC880_AUTO)
ae6b813a 5718 spec->init_hook = alc880_auto_init;
cb53c626
TI
5719#ifdef CONFIG_SND_HDA_POWER_SAVE
5720 if (!spec->loopback.amplist)
5721 spec->loopback.amplist = alc880_loopbacks;
5722#endif
1da177e4
LT
5723
5724 return 0;
5725}
5726
e9edcee0 5727
1da177e4
LT
5728/*
5729 * ALC260 support
5730 */
5731
e9edcee0
TI
5732static hda_nid_t alc260_dac_nids[1] = {
5733 /* front */
5734 0x02,
5735};
5736
5737static hda_nid_t alc260_adc_nids[1] = {
5738 /* ADC0 */
5739 0x04,
5740};
5741
df694daa 5742static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5743 /* ADC1 */
5744 0x05,
5745};
5746
d57fdac0
JW
5747/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5748 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5749 */
5750static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5751 /* ADC0, ADC1 */
5752 0x04, 0x05
5753};
5754
e9edcee0
TI
5755#define ALC260_DIGOUT_NID 0x03
5756#define ALC260_DIGIN_NID 0x06
5757
5758static struct hda_input_mux alc260_capture_source = {
5759 .num_items = 4,
5760 .items = {
5761 { "Mic", 0x0 },
5762 { "Front Mic", 0x1 },
5763 { "Line", 0x2 },
5764 { "CD", 0x4 },
5765 },
5766};
5767
17e7aec6 5768/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5769 * headphone jack and the internal CD lines since these are the only pins at
5770 * which audio can appear. For flexibility, also allow the option of
5771 * recording the mixer output on the second ADC (ADC0 doesn't have a
5772 * connection to the mixer output).
a9430dd8 5773 */
a1e8d2da
JW
5774static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5775 {
5776 .num_items = 3,
5777 .items = {
5778 { "Mic/Line", 0x0 },
5779 { "CD", 0x4 },
5780 { "Headphone", 0x2 },
5781 },
a9430dd8 5782 },
a1e8d2da
JW
5783 {
5784 .num_items = 4,
5785 .items = {
5786 { "Mic/Line", 0x0 },
5787 { "CD", 0x4 },
5788 { "Headphone", 0x2 },
5789 { "Mixer", 0x5 },
5790 },
5791 },
5792
a9430dd8
JW
5793};
5794
a1e8d2da
JW
5795/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5796 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5797 */
a1e8d2da
JW
5798static struct hda_input_mux alc260_acer_capture_sources[2] = {
5799 {
5800 .num_items = 4,
5801 .items = {
5802 { "Mic", 0x0 },
5803 { "Line", 0x2 },
5804 { "CD", 0x4 },
5805 { "Headphone", 0x5 },
5806 },
5807 },
5808 {
5809 .num_items = 5,
5810 .items = {
5811 { "Mic", 0x0 },
5812 { "Line", 0x2 },
5813 { "CD", 0x4 },
5814 { "Headphone", 0x6 },
5815 { "Mixer", 0x5 },
5816 },
0bfc90e9
JW
5817 },
5818};
cc959489
MS
5819
5820/* Maxdata Favorit 100XS */
5821static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5822 {
5823 .num_items = 2,
5824 .items = {
5825 { "Line/Mic", 0x0 },
5826 { "CD", 0x4 },
5827 },
5828 },
5829 {
5830 .num_items = 3,
5831 .items = {
5832 { "Line/Mic", 0x0 },
5833 { "CD", 0x4 },
5834 { "Mixer", 0x5 },
5835 },
5836 },
5837};
5838
1da177e4
LT
5839/*
5840 * This is just place-holder, so there's something for alc_build_pcms to look
5841 * at when it calculates the maximum number of channels. ALC260 has no mixer
5842 * element which allows changing the channel mode, so the verb list is
5843 * never used.
5844 */
d2a6d7dc 5845static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5846 { 2, NULL },
5847};
5848
df694daa
KY
5849
5850/* Mixer combinations
5851 *
5852 * basic: base_output + input + pc_beep + capture
5853 * HP: base_output + input + capture_alt
5854 * HP_3013: hp_3013 + input + capture
5855 * fujitsu: fujitsu + capture
0bfc90e9 5856 * acer: acer + capture
df694daa
KY
5857 */
5858
5859static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5860 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5861 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5862 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5863 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5864 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5865 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5866 { } /* end */
f12ab1e0 5867};
1da177e4 5868
df694daa 5869static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5870 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5871 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5872 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5873 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5874 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5875 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5876 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5877 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5878 { } /* end */
5879};
5880
bec15c3a
TI
5881/* update HP, line and mono out pins according to the master switch */
5882static void alc260_hp_master_update(struct hda_codec *codec,
5883 hda_nid_t hp, hda_nid_t line,
5884 hda_nid_t mono)
5885{
5886 struct alc_spec *spec = codec->spec;
5887 unsigned int val = spec->master_sw ? PIN_HP : 0;
5888 /* change HP and line-out pins */
30cde0aa 5889 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5890 val);
30cde0aa 5891 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5892 val);
5893 /* mono (speaker) depending on the HP jack sense */
5894 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5895 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5896 val);
5897}
5898
5899static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5900 struct snd_ctl_elem_value *ucontrol)
5901{
5902 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5903 struct alc_spec *spec = codec->spec;
5904 *ucontrol->value.integer.value = spec->master_sw;
5905 return 0;
5906}
5907
5908static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5909 struct snd_ctl_elem_value *ucontrol)
5910{
5911 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5912 struct alc_spec *spec = codec->spec;
5913 int val = !!*ucontrol->value.integer.value;
5914 hda_nid_t hp, line, mono;
5915
5916 if (val == spec->master_sw)
5917 return 0;
5918 spec->master_sw = val;
5919 hp = (kcontrol->private_value >> 16) & 0xff;
5920 line = (kcontrol->private_value >> 8) & 0xff;
5921 mono = kcontrol->private_value & 0xff;
5922 alc260_hp_master_update(codec, hp, line, mono);
5923 return 1;
5924}
5925
5926static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5927 {
5928 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5929 .name = "Master Playback Switch",
5b0cb1d8 5930 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5931 .info = snd_ctl_boolean_mono_info,
5932 .get = alc260_hp_master_sw_get,
5933 .put = alc260_hp_master_sw_put,
5934 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5935 },
5936 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5937 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5938 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5939 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5940 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5941 HDA_OUTPUT),
5942 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5943 { } /* end */
5944};
5945
5946static struct hda_verb alc260_hp_unsol_verbs[] = {
5947 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5948 {},
5949};
5950
5951static void alc260_hp_automute(struct hda_codec *codec)
5952{
5953 struct alc_spec *spec = codec->spec;
bec15c3a 5954
864f92be 5955 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5956 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5957}
5958
5959static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5960{
5961 if ((res >> 26) == ALC880_HP_EVENT)
5962 alc260_hp_automute(codec);
5963}
5964
df694daa 5965static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5966 {
5967 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5968 .name = "Master Playback Switch",
5b0cb1d8 5969 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5970 .info = snd_ctl_boolean_mono_info,
5971 .get = alc260_hp_master_sw_get,
5972 .put = alc260_hp_master_sw_put,
30cde0aa 5973 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5974 },
df694daa
KY
5975 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5976 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5977 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5978 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5979 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5980 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
5981 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5982 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
5983 { } /* end */
5984};
5985
3f878308
KY
5986static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5987 .ops = &snd_hda_bind_vol,
5988 .values = {
5989 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5990 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5991 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5992 0
5993 },
5994};
5995
5996static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5997 .ops = &snd_hda_bind_sw,
5998 .values = {
5999 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6000 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6001 0
6002 },
6003};
6004
6005static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6006 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6007 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6008 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6009 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6010 { } /* end */
6011};
6012
bec15c3a
TI
6013static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6014 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6015 {},
6016};
6017
6018static void alc260_hp_3013_automute(struct hda_codec *codec)
6019{
6020 struct alc_spec *spec = codec->spec;
bec15c3a 6021
864f92be 6022 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 6023 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
6024}
6025
6026static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
6027 unsigned int res)
6028{
6029 if ((res >> 26) == ALC880_HP_EVENT)
6030 alc260_hp_3013_automute(codec);
6031}
6032
3f878308
KY
6033static void alc260_hp_3012_automute(struct hda_codec *codec)
6034{
864f92be 6035 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 6036
3f878308
KY
6037 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6038 bits);
6039 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6040 bits);
6041 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6042 bits);
6043}
6044
6045static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
6046 unsigned int res)
6047{
6048 if ((res >> 26) == ALC880_HP_EVENT)
6049 alc260_hp_3012_automute(codec);
6050}
6051
6052/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
6053 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6054 */
c8b6bf9b 6055static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 6056 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6057 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 6058 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
6059 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6060 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6061 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6062 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 6063 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
6064 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6065 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
6066 { } /* end */
6067};
6068
a1e8d2da
JW
6069/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6070 * versions of the ALC260 don't act on requests to enable mic bias from NID
6071 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6072 * datasheet doesn't mention this restriction. At this stage it's not clear
6073 * whether this behaviour is intentional or is a hardware bug in chip
6074 * revisions available in early 2006. Therefore for now allow the
6075 * "Headphone Jack Mode" control to span all choices, but if it turns out
6076 * that the lack of mic bias for this NID is intentional we could change the
6077 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6078 *
6079 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6080 * don't appear to make the mic bias available from the "line" jack, even
6081 * though the NID used for this jack (0x14) can supply it. The theory is
6082 * that perhaps Acer have included blocking capacitors between the ALC260
6083 * and the output jack. If this turns out to be the case for all such
6084 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6085 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
6086 *
6087 * The C20x Tablet series have a mono internal speaker which is controlled
6088 * via the chip's Mono sum widget and pin complex, so include the necessary
6089 * controls for such models. On models without a "mono speaker" the control
6090 * won't do anything.
a1e8d2da 6091 */
0bfc90e9
JW
6092static struct snd_kcontrol_new alc260_acer_mixer[] = {
6093 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6094 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 6095 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 6096 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 6097 HDA_OUTPUT),
31bffaa9 6098 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 6099 HDA_INPUT),
0bfc90e9
JW
6100 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6101 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6102 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6103 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6104 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6105 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6106 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6107 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
6108 { } /* end */
6109};
6110
cc959489
MS
6111/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6112 */
6113static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6114 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6115 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6116 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6117 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6118 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6119 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6120 { } /* end */
6121};
6122
bc9f98a9
KY
6123/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6124 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6125 */
6126static struct snd_kcontrol_new alc260_will_mixer[] = {
6127 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6128 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6129 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6130 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6131 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6132 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6133 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6134 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6135 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6136 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
6137 { } /* end */
6138};
6139
6140/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6141 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6142 */
6143static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6144 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6145 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6146 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6147 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6148 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6149 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6150 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6151 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6152 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6153 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6154 { } /* end */
6155};
6156
df694daa
KY
6157/*
6158 * initialization verbs
6159 */
1da177e4
LT
6160static struct hda_verb alc260_init_verbs[] = {
6161 /* Line In pin widget for input */
05acb863 6162 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6163 /* CD pin widget for input */
05acb863 6164 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6165 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6166 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6167 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6168 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6169 /* LINE-2 is used for line-out in rear */
05acb863 6170 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6171 /* select line-out */
fd56f2db 6172 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6173 /* LINE-OUT pin */
05acb863 6174 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6175 /* enable HP */
05acb863 6176 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6177 /* enable Mono */
05acb863
TI
6178 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6179 /* mute capture amp left and right */
16ded525 6180 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6181 /* set connection select to line in (default select for this ADC) */
6182 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6183 /* mute capture amp left and right */
6184 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6185 /* set connection select to line in (default select for this ADC) */
6186 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6187 /* set vol=0 Line-Out mixer amp left and right */
6188 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6189 /* unmute pin widget amp left and right (no gain on this amp) */
6190 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6191 /* set vol=0 HP mixer amp left and right */
6192 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6193 /* unmute pin widget amp left and right (no gain on this amp) */
6194 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6195 /* set vol=0 Mono mixer amp left and right */
6196 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6197 /* unmute pin widget amp left and right (no gain on this amp) */
6198 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6199 /* unmute LINE-2 out pin */
6200 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6201 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6202 * Line In 2 = 0x03
6203 */
cb53c626
TI
6204 /* mute analog inputs */
6205 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6206 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6207 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6208 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6209 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6210 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6211 /* mute Front out path */
6212 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6213 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6214 /* mute Headphone out path */
6215 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6216 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6217 /* mute Mono out path */
6218 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6219 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6220 { }
6221};
6222
474167d6 6223#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
6224static struct hda_verb alc260_hp_init_verbs[] = {
6225 /* Headphone and output */
6226 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6227 /* mono output */
6228 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6229 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6230 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6231 /* Mic2 (front panel) pin widget for input and vref at 80% */
6232 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6233 /* Line In pin widget for input */
6234 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6235 /* Line-2 pin widget for output */
6236 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6237 /* CD pin widget for input */
6238 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6239 /* unmute amp left and right */
6240 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6241 /* set connection select to line in (default select for this ADC) */
6242 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6243 /* unmute Line-Out mixer amp left and right (volume = 0) */
6244 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6245 /* mute pin widget amp left and right (no gain on this amp) */
6246 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6247 /* unmute HP mixer amp left and right (volume = 0) */
6248 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6249 /* mute pin widget amp left and right (no gain on this amp) */
6250 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6251 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6252 * Line In 2 = 0x03
6253 */
cb53c626
TI
6254 /* mute analog inputs */
6255 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6256 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6257 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6258 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6259 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6260 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6261 /* Unmute Front out path */
6262 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6263 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6264 /* Unmute Headphone out path */
6265 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6266 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6267 /* Unmute Mono out path */
6268 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6269 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6270 { }
6271};
474167d6 6272#endif
df694daa
KY
6273
6274static struct hda_verb alc260_hp_3013_init_verbs[] = {
6275 /* Line out and output */
6276 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6277 /* mono output */
6278 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6279 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6280 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6281 /* Mic2 (front panel) pin widget for input and vref at 80% */
6282 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6283 /* Line In pin widget for input */
6284 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6285 /* Headphone pin widget for output */
6286 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6287 /* CD pin widget for input */
6288 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6289 /* unmute amp left and right */
6290 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6291 /* set connection select to line in (default select for this ADC) */
6292 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6293 /* unmute Line-Out mixer amp left and right (volume = 0) */
6294 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6295 /* mute pin widget amp left and right (no gain on this amp) */
6296 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6297 /* unmute HP mixer amp left and right (volume = 0) */
6298 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6299 /* mute pin widget amp left and right (no gain on this amp) */
6300 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6301 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6302 * Line In 2 = 0x03
6303 */
cb53c626
TI
6304 /* mute analog inputs */
6305 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6306 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6307 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6308 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6309 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6310 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6311 /* Unmute Front out path */
6312 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6313 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6314 /* Unmute Headphone out path */
6315 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6316 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6317 /* Unmute Mono out path */
6318 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6319 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6320 { }
6321};
6322
a9430dd8 6323/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6324 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6325 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
6326 */
6327static struct hda_verb alc260_fujitsu_init_verbs[] = {
6328 /* Disable all GPIOs */
6329 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6330 /* Internal speaker is connected to headphone pin */
6331 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6332 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6333 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6334 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6335 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6336 /* Ensure all other unused pins are disabled and muted. */
6337 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6338 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6339 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6340 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6341 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6342 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6343 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6344 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6345
6346 /* Disable digital (SPDIF) pins */
6347 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6348 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6349
ea1fb29a 6350 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6351 * when acting as an output.
6352 */
6353 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6354
f7ace40d 6355 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6356 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6357 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6358 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6359 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6360 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6361 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6362 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6363 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6364 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6365
f7ace40d
JW
6366 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6367 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6368 /* Unmute Line1 pin widget output buffer since it starts as an output.
6369 * If the pin mode is changed by the user the pin mode control will
6370 * take care of enabling the pin's input/output buffers as needed.
6371 * Therefore there's no need to enable the input buffer at this
6372 * stage.
cdcd9268 6373 */
f7ace40d 6374 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6375 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6376 * mixer ctrl)
6377 */
f7ace40d
JW
6378 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6379
6380 /* Mute capture amp left and right */
6381 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6382 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6383 * in (on mic1 pin)
6384 */
6385 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6386
6387 /* Do the same for the second ADC: mute capture input amp and
6388 * set ADC connection to line in (on mic1 pin)
6389 */
6390 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6391 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6392
6393 /* Mute all inputs to mixer widget (even unconnected ones) */
6394 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6395 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6396 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6397 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6398 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6399 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6400 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6401 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6402
6403 { }
a9430dd8
JW
6404};
6405
0bfc90e9
JW
6406/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6407 * similar laptops (adapted from Fujitsu init verbs).
6408 */
6409static struct hda_verb alc260_acer_init_verbs[] = {
6410 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6411 * the headphone jack. Turn this on and rely on the standard mute
6412 * methods whenever the user wants to turn these outputs off.
6413 */
6414 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6415 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6416 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6417 /* Internal speaker/Headphone jack is connected to Line-out pin */
6418 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6419 /* Internal microphone/Mic jack is connected to Mic1 pin */
6420 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6421 /* Line In jack is connected to Line1 pin */
6422 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6423 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6424 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6425 /* Ensure all other unused pins are disabled and muted. */
6426 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6427 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6428 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6429 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6430 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6431 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6432 /* Disable digital (SPDIF) pins */
6433 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6434 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6435
ea1fb29a 6436 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6437 * bus when acting as outputs.
6438 */
6439 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6440 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6441
6442 /* Start with output sum widgets muted and their output gains at min */
6443 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6444 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6445 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6446 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6447 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6448 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6449 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6450 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6451 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6452
f12ab1e0
TI
6453 /* Unmute Line-out pin widget amp left and right
6454 * (no equiv mixer ctrl)
6455 */
0bfc90e9 6456 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6457 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6458 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6459 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6460 * inputs. If the pin mode is changed by the user the pin mode control
6461 * will take care of enabling the pin's input/output buffers as needed.
6462 * Therefore there's no need to enable the input buffer at this
6463 * stage.
6464 */
6465 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6466 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6467
6468 /* Mute capture amp left and right */
6469 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6470 /* Set ADC connection select to match default mixer setting - mic
6471 * (on mic1 pin)
6472 */
6473 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6474
6475 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6476 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6477 */
6478 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6479 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6480
6481 /* Mute all inputs to mixer widget (even unconnected ones) */
6482 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6483 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6484 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6485 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6486 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6487 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6488 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6489 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6490
6491 { }
6492};
6493
cc959489
MS
6494/* Initialisation sequence for Maxdata Favorit 100XS
6495 * (adapted from Acer init verbs).
6496 */
6497static struct hda_verb alc260_favorit100_init_verbs[] = {
6498 /* GPIO 0 enables the output jack.
6499 * Turn this on and rely on the standard mute
6500 * methods whenever the user wants to turn these outputs off.
6501 */
6502 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6503 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6504 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6505 /* Line/Mic input jack is connected to Mic1 pin */
6506 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6507 /* Ensure all other unused pins are disabled and muted. */
6508 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6509 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6510 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6511 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6512 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6513 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6514 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6515 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6516 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6517 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6518 /* Disable digital (SPDIF) pins */
6519 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6520 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6521
6522 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6523 * bus when acting as outputs.
6524 */
6525 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6526 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6527
6528 /* Start with output sum widgets muted and their output gains at min */
6529 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6530 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6531 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6532 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6533 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6534 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6535 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6536 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6537 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6538
6539 /* Unmute Line-out pin widget amp left and right
6540 * (no equiv mixer ctrl)
6541 */
6542 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6543 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6544 * inputs. If the pin mode is changed by the user the pin mode control
6545 * will take care of enabling the pin's input/output buffers as needed.
6546 * Therefore there's no need to enable the input buffer at this
6547 * stage.
6548 */
6549 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6550
6551 /* Mute capture amp left and right */
6552 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6553 /* Set ADC connection select to match default mixer setting - mic
6554 * (on mic1 pin)
6555 */
6556 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6557
6558 /* Do similar with the second ADC: mute capture input amp and
6559 * set ADC connection to mic to match ALSA's default state.
6560 */
6561 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6562 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6563
6564 /* Mute all inputs to mixer widget (even unconnected ones) */
6565 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6566 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6567 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6568 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6569 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6570 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6571 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6572 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6573
6574 { }
6575};
6576
bc9f98a9
KY
6577static struct hda_verb alc260_will_verbs[] = {
6578 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6579 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6580 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6581 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6582 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6583 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6584 {}
6585};
6586
6587static struct hda_verb alc260_replacer_672v_verbs[] = {
6588 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6589 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6590 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6591
6592 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6593 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6594 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6595
6596 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6597 {}
6598};
6599
6600/* toggle speaker-output according to the hp-jack state */
6601static void alc260_replacer_672v_automute(struct hda_codec *codec)
6602{
6603 unsigned int present;
6604
6605 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6606 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6607 if (present) {
82beb8fd
TI
6608 snd_hda_codec_write_cache(codec, 0x01, 0,
6609 AC_VERB_SET_GPIO_DATA, 1);
6610 snd_hda_codec_write_cache(codec, 0x0f, 0,
6611 AC_VERB_SET_PIN_WIDGET_CONTROL,
6612 PIN_HP);
bc9f98a9 6613 } else {
82beb8fd
TI
6614 snd_hda_codec_write_cache(codec, 0x01, 0,
6615 AC_VERB_SET_GPIO_DATA, 0);
6616 snd_hda_codec_write_cache(codec, 0x0f, 0,
6617 AC_VERB_SET_PIN_WIDGET_CONTROL,
6618 PIN_OUT);
bc9f98a9
KY
6619 }
6620}
6621
6622static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6623 unsigned int res)
6624{
6625 if ((res >> 26) == ALC880_HP_EVENT)
6626 alc260_replacer_672v_automute(codec);
6627}
6628
3f878308
KY
6629static struct hda_verb alc260_hp_dc7600_verbs[] = {
6630 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6631 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6632 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6633 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6634 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6635 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6636 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6637 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6638 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6639 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6640 {}
6641};
6642
7cf51e48
JW
6643/* Test configuration for debugging, modelled after the ALC880 test
6644 * configuration.
6645 */
6646#ifdef CONFIG_SND_DEBUG
6647static hda_nid_t alc260_test_dac_nids[1] = {
6648 0x02,
6649};
6650static hda_nid_t alc260_test_adc_nids[2] = {
6651 0x04, 0x05,
6652};
a1e8d2da 6653/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6654 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6655 * is NID 0x04.
17e7aec6 6656 */
a1e8d2da
JW
6657static struct hda_input_mux alc260_test_capture_sources[2] = {
6658 {
6659 .num_items = 7,
6660 .items = {
6661 { "MIC1 pin", 0x0 },
6662 { "MIC2 pin", 0x1 },
6663 { "LINE1 pin", 0x2 },
6664 { "LINE2 pin", 0x3 },
6665 { "CD pin", 0x4 },
6666 { "LINE-OUT pin", 0x5 },
6667 { "HP-OUT pin", 0x6 },
6668 },
6669 },
6670 {
6671 .num_items = 8,
6672 .items = {
6673 { "MIC1 pin", 0x0 },
6674 { "MIC2 pin", 0x1 },
6675 { "LINE1 pin", 0x2 },
6676 { "LINE2 pin", 0x3 },
6677 { "CD pin", 0x4 },
6678 { "Mixer", 0x5 },
6679 { "LINE-OUT pin", 0x6 },
6680 { "HP-OUT pin", 0x7 },
6681 },
7cf51e48
JW
6682 },
6683};
6684static struct snd_kcontrol_new alc260_test_mixer[] = {
6685 /* Output driver widgets */
6686 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6687 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6688 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6689 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6690 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6691 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6692
a1e8d2da
JW
6693 /* Modes for retasking pin widgets
6694 * Note: the ALC260 doesn't seem to act on requests to enable mic
6695 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6696 * mention this restriction. At this stage it's not clear whether
6697 * this behaviour is intentional or is a hardware bug in chip
6698 * revisions available at least up until early 2006. Therefore for
6699 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6700 * choices, but if it turns out that the lack of mic bias for these
6701 * NIDs is intentional we could change their modes from
6702 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6703 */
7cf51e48
JW
6704 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6705 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6706 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6707 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6708 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6709 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6710
6711 /* Loopback mixer controls */
6712 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6713 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6714 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6715 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6716 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6717 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6718 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6719 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6720 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6721 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6722 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6723 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6724 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6725 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6726
6727 /* Controls for GPIO pins, assuming they are configured as outputs */
6728 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6729 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6730 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6731 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6732
92621f13
JW
6733 /* Switches to allow the digital IO pins to be enabled. The datasheet
6734 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6735 * make this output available should provide clarification.
92621f13
JW
6736 */
6737 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6738 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6739
f8225f6d
JW
6740 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6741 * this output to turn on an external amplifier.
6742 */
6743 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6744 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6745
7cf51e48
JW
6746 { } /* end */
6747};
6748static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6749 /* Enable all GPIOs as outputs with an initial value of 0 */
6750 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6751 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6752 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6753
7cf51e48
JW
6754 /* Enable retasking pins as output, initially without power amp */
6755 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6756 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6757 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6758 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6759 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6760 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6761
92621f13
JW
6762 /* Disable digital (SPDIF) pins initially, but users can enable
6763 * them via a mixer switch. In the case of SPDIF-out, this initverb
6764 * payload also sets the generation to 0, output to be in "consumer"
6765 * PCM format, copyright asserted, no pre-emphasis and no validity
6766 * control.
6767 */
7cf51e48
JW
6768 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6769 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6770
ea1fb29a 6771 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6772 * OUT1 sum bus when acting as an output.
6773 */
6774 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6775 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6776 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6777 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6778
6779 /* Start with output sum widgets muted and their output gains at min */
6780 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6781 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6782 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6783 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6784 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6785 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6786 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6787 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6788 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6789
cdcd9268
JW
6790 /* Unmute retasking pin widget output buffers since the default
6791 * state appears to be output. As the pin mode is changed by the
6792 * user the pin mode control will take care of enabling the pin's
6793 * input/output buffers as needed.
6794 */
7cf51e48
JW
6795 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6796 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6797 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6798 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6799 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6800 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6801 /* Also unmute the mono-out pin widget */
6802 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6803
7cf51e48
JW
6804 /* Mute capture amp left and right */
6805 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6806 /* Set ADC connection select to match default mixer setting (mic1
6807 * pin)
7cf51e48
JW
6808 */
6809 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6810
6811 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6812 * set ADC connection to mic1 pin
7cf51e48
JW
6813 */
6814 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6815 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6816
6817 /* Mute all inputs to mixer widget (even unconnected ones) */
6818 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6819 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6820 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6821 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6822 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6823 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6824 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6825 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6826
6827 { }
6828};
6829#endif
6830
6330079f
TI
6831#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6832#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6833
a3bcba38
TI
6834#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6835#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6836
df694daa
KY
6837/*
6838 * for BIOS auto-configuration
6839 */
16ded525 6840
df694daa 6841static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6842 const char *pfx, int *vol_bits)
df694daa
KY
6843{
6844 hda_nid_t nid_vol;
6845 unsigned long vol_val, sw_val;
df694daa
KY
6846 int err;
6847
6848 if (nid >= 0x0f && nid < 0x11) {
6849 nid_vol = nid - 0x7;
6850 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6851 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6852 } else if (nid == 0x11) {
6853 nid_vol = nid - 0x7;
6854 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6855 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6856 } else if (nid >= 0x12 && nid <= 0x15) {
6857 nid_vol = 0x08;
6858 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6859 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6860 } else
6861 return 0; /* N/A */
ea1fb29a 6862
863b4518
TI
6863 if (!(*vol_bits & (1 << nid_vol))) {
6864 /* first control for the volume widget */
0afe5f89 6865 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6866 if (err < 0)
6867 return err;
6868 *vol_bits |= (1 << nid_vol);
6869 }
0afe5f89 6870 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6871 if (err < 0)
df694daa
KY
6872 return err;
6873 return 1;
6874}
6875
6876/* add playback controls from the parsed DAC table */
6877static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6878 const struct auto_pin_cfg *cfg)
6879{
6880 hda_nid_t nid;
6881 int err;
863b4518 6882 int vols = 0;
df694daa
KY
6883
6884 spec->multiout.num_dacs = 1;
6885 spec->multiout.dac_nids = spec->private_dac_nids;
6886 spec->multiout.dac_nids[0] = 0x02;
6887
6888 nid = cfg->line_out_pins[0];
6889 if (nid) {
23112d6d
TI
6890 const char *pfx;
6891 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6892 pfx = "Master";
6893 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6894 pfx = "Speaker";
6895 else
6896 pfx = "Front";
6897 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6898 if (err < 0)
6899 return err;
6900 }
6901
82bc955f 6902 nid = cfg->speaker_pins[0];
df694daa 6903 if (nid) {
863b4518 6904 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6905 if (err < 0)
6906 return err;
6907 }
6908
eb06ed8f 6909 nid = cfg->hp_pins[0];
df694daa 6910 if (nid) {
863b4518
TI
6911 err = alc260_add_playback_controls(spec, nid, "Headphone",
6912 &vols);
df694daa
KY
6913 if (err < 0)
6914 return err;
6915 }
f12ab1e0 6916 return 0;
df694daa
KY
6917}
6918
6919/* create playback/capture controls for input pins */
05f5f477 6920static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6921 const struct auto_pin_cfg *cfg)
6922{
05f5f477 6923 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6924}
6925
6926static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6927 hda_nid_t nid, int pin_type,
6928 int sel_idx)
6929{
f6c7e546 6930 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6931 /* need the manual connection? */
6932 if (nid >= 0x12) {
6933 int idx = nid - 0x12;
6934 snd_hda_codec_write(codec, idx + 0x0b, 0,
6935 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6936 }
6937}
6938
6939static void alc260_auto_init_multi_out(struct hda_codec *codec)
6940{
6941 struct alc_spec *spec = codec->spec;
6942 hda_nid_t nid;
6943
f12ab1e0 6944 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6945 if (nid) {
6946 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6947 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6948 }
ea1fb29a 6949
82bc955f 6950 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6951 if (nid)
6952 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6953
eb06ed8f 6954 nid = spec->autocfg.hp_pins[0];
df694daa 6955 if (nid)
baba8ee9 6956 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6957}
df694daa
KY
6958
6959#define ALC260_PIN_CD_NID 0x16
6960static void alc260_auto_init_analog_input(struct hda_codec *codec)
6961{
6962 struct alc_spec *spec = codec->spec;
66ceeb6b 6963 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
6964 int i;
6965
66ceeb6b
TI
6966 for (i = 0; i < cfg->num_inputs; i++) {
6967 hda_nid_t nid = cfg->inputs[i].pin;
df694daa 6968 if (nid >= 0x12) {
30ea098f 6969 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
6970 if (nid != ALC260_PIN_CD_NID &&
6971 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6972 snd_hda_codec_write(codec, nid, 0,
6973 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6974 AMP_OUT_MUTE);
6975 }
6976 }
6977}
6978
7f311a46
TI
6979#define alc260_auto_init_input_src alc880_auto_init_input_src
6980
df694daa
KY
6981/*
6982 * generic initialization of ADC, input mixers and output mixers
6983 */
6984static struct hda_verb alc260_volume_init_verbs[] = {
6985 /*
6986 * Unmute ADC0-1 and set the default input to mic-in
6987 */
6988 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6989 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6990 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6991 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 6992
df694daa
KY
6993 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6994 * mixer widget
f12ab1e0
TI
6995 * Note: PASD motherboards uses the Line In 2 as the input for
6996 * front panel mic (mic 2)
df694daa
KY
6997 */
6998 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6999 /* mute analog inputs */
7000 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7001 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7002 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7003 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7004 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
7005
7006 /*
7007 * Set up output mixers (0x08 - 0x0a)
7008 */
7009 /* set vol=0 to output mixers */
7010 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7011 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7012 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7013 /* set up input amps for analog loopback */
7014 /* Amp Indices: DAC = 0, mixer = 1 */
7015 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7016 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7017 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7018 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7019 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7020 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 7021
df694daa
KY
7022 { }
7023};
7024
7025static int alc260_parse_auto_config(struct hda_codec *codec)
7026{
7027 struct alc_spec *spec = codec->spec;
df694daa
KY
7028 int err;
7029 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
7030
f12ab1e0
TI
7031 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7032 alc260_ignore);
7033 if (err < 0)
df694daa 7034 return err;
f12ab1e0
TI
7035 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7036 if (err < 0)
4a471b7d 7037 return err;
603c4019 7038 if (!spec->kctls.list)
df694daa 7039 return 0; /* can't find valid BIOS pin config */
05f5f477 7040 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 7041 if (err < 0)
df694daa
KY
7042 return err;
7043
7044 spec->multiout.max_channels = 2;
7045
0852d7a6 7046 if (spec->autocfg.dig_outs)
df694daa 7047 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 7048 if (spec->kctls.list)
d88897ea 7049 add_mixer(spec, spec->kctls.list);
df694daa 7050
d88897ea 7051 add_verb(spec, alc260_volume_init_verbs);
df694daa 7052
a1e8d2da 7053 spec->num_mux_defs = 1;
61b9b9b1 7054 spec->input_mux = &spec->private_imux[0];
df694daa 7055
6227cdce 7056 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 7057
df694daa
KY
7058 return 1;
7059}
7060
ae6b813a
TI
7061/* additional initialization for auto-configuration model */
7062static void alc260_auto_init(struct hda_codec *codec)
df694daa 7063{
f6c7e546 7064 struct alc_spec *spec = codec->spec;
df694daa
KY
7065 alc260_auto_init_multi_out(codec);
7066 alc260_auto_init_analog_input(codec);
7f311a46 7067 alc260_auto_init_input_src(codec);
757899ac 7068 alc_auto_init_digital(codec);
f6c7e546 7069 if (spec->unsol_event)
7fb0d78f 7070 alc_inithook(codec);
df694daa
KY
7071}
7072
cb53c626
TI
7073#ifdef CONFIG_SND_HDA_POWER_SAVE
7074static struct hda_amp_list alc260_loopbacks[] = {
7075 { 0x07, HDA_INPUT, 0 },
7076 { 0x07, HDA_INPUT, 1 },
7077 { 0x07, HDA_INPUT, 2 },
7078 { 0x07, HDA_INPUT, 3 },
7079 { 0x07, HDA_INPUT, 4 },
7080 { } /* end */
7081};
7082#endif
7083
fc091769
TI
7084/*
7085 * Pin config fixes
7086 */
7087enum {
7088 PINFIX_HP_DC5750,
7089};
7090
fc091769
TI
7091static const struct alc_fixup alc260_fixups[] = {
7092 [PINFIX_HP_DC5750] = {
73413b12
TI
7093 .pins = (const struct alc_pincfg[]) {
7094 { 0x11, 0x90130110 }, /* speaker */
7095 { }
7096 }
fc091769
TI
7097 },
7098};
7099
7100static struct snd_pci_quirk alc260_fixup_tbl[] = {
7101 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7102 {}
7103};
7104
df694daa
KY
7105/*
7106 * ALC260 configurations
7107 */
f5fcc13c
TI
7108static const char *alc260_models[ALC260_MODEL_LAST] = {
7109 [ALC260_BASIC] = "basic",
7110 [ALC260_HP] = "hp",
7111 [ALC260_HP_3013] = "hp-3013",
2922c9af 7112 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
7113 [ALC260_FUJITSU_S702X] = "fujitsu",
7114 [ALC260_ACER] = "acer",
bc9f98a9
KY
7115 [ALC260_WILL] = "will",
7116 [ALC260_REPLACER_672V] = "replacer",
cc959489 7117 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 7118#ifdef CONFIG_SND_DEBUG
f5fcc13c 7119 [ALC260_TEST] = "test",
7cf51e48 7120#endif
f5fcc13c
TI
7121 [ALC260_AUTO] = "auto",
7122};
7123
7124static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 7125 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 7126 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 7127 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 7128 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 7129 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 7130 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 7131 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 7132 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 7133 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
7134 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7135 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7136 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7137 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7138 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7139 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7140 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7141 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7142 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7143 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7144 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7145 {}
7146};
7147
7148static struct alc_config_preset alc260_presets[] = {
7149 [ALC260_BASIC] = {
7150 .mixers = { alc260_base_output_mixer,
45bdd1c1 7151 alc260_input_mixer },
df694daa
KY
7152 .init_verbs = { alc260_init_verbs },
7153 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7154 .dac_nids = alc260_dac_nids,
f9e336f6 7155 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7156 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7157 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7158 .channel_mode = alc260_modes,
7159 .input_mux = &alc260_capture_source,
7160 },
7161 [ALC260_HP] = {
bec15c3a 7162 .mixers = { alc260_hp_output_mixer,
f9e336f6 7163 alc260_input_mixer },
bec15c3a
TI
7164 .init_verbs = { alc260_init_verbs,
7165 alc260_hp_unsol_verbs },
df694daa
KY
7166 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7167 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7168 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7169 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7170 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7171 .channel_mode = alc260_modes,
7172 .input_mux = &alc260_capture_source,
bec15c3a
TI
7173 .unsol_event = alc260_hp_unsol_event,
7174 .init_hook = alc260_hp_automute,
df694daa 7175 },
3f878308
KY
7176 [ALC260_HP_DC7600] = {
7177 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7178 alc260_input_mixer },
3f878308
KY
7179 .init_verbs = { alc260_init_verbs,
7180 alc260_hp_dc7600_verbs },
7181 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7182 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7183 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7184 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7185 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7186 .channel_mode = alc260_modes,
7187 .input_mux = &alc260_capture_source,
7188 .unsol_event = alc260_hp_3012_unsol_event,
7189 .init_hook = alc260_hp_3012_automute,
7190 },
df694daa
KY
7191 [ALC260_HP_3013] = {
7192 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7193 alc260_input_mixer },
bec15c3a
TI
7194 .init_verbs = { alc260_hp_3013_init_verbs,
7195 alc260_hp_3013_unsol_verbs },
df694daa
KY
7196 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7197 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7198 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7199 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7200 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7201 .channel_mode = alc260_modes,
7202 .input_mux = &alc260_capture_source,
bec15c3a
TI
7203 .unsol_event = alc260_hp_3013_unsol_event,
7204 .init_hook = alc260_hp_3013_automute,
df694daa
KY
7205 },
7206 [ALC260_FUJITSU_S702X] = {
f9e336f6 7207 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7208 .init_verbs = { alc260_fujitsu_init_verbs },
7209 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7210 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7211 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7212 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7213 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7214 .channel_mode = alc260_modes,
a1e8d2da
JW
7215 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7216 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7217 },
0bfc90e9 7218 [ALC260_ACER] = {
f9e336f6 7219 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7220 .init_verbs = { alc260_acer_init_verbs },
7221 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7222 .dac_nids = alc260_dac_nids,
7223 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7224 .adc_nids = alc260_dual_adc_nids,
7225 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7226 .channel_mode = alc260_modes,
a1e8d2da
JW
7227 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7228 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7229 },
cc959489
MS
7230 [ALC260_FAVORIT100] = {
7231 .mixers = { alc260_favorit100_mixer },
7232 .init_verbs = { alc260_favorit100_init_verbs },
7233 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7234 .dac_nids = alc260_dac_nids,
7235 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7236 .adc_nids = alc260_dual_adc_nids,
7237 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7238 .channel_mode = alc260_modes,
7239 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7240 .input_mux = alc260_favorit100_capture_sources,
7241 },
bc9f98a9 7242 [ALC260_WILL] = {
f9e336f6 7243 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7244 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7245 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7246 .dac_nids = alc260_dac_nids,
7247 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7248 .adc_nids = alc260_adc_nids,
7249 .dig_out_nid = ALC260_DIGOUT_NID,
7250 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7251 .channel_mode = alc260_modes,
7252 .input_mux = &alc260_capture_source,
7253 },
7254 [ALC260_REPLACER_672V] = {
f9e336f6 7255 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7256 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7257 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7258 .dac_nids = alc260_dac_nids,
7259 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7260 .adc_nids = alc260_adc_nids,
7261 .dig_out_nid = ALC260_DIGOUT_NID,
7262 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7263 .channel_mode = alc260_modes,
7264 .input_mux = &alc260_capture_source,
7265 .unsol_event = alc260_replacer_672v_unsol_event,
7266 .init_hook = alc260_replacer_672v_automute,
7267 },
7cf51e48
JW
7268#ifdef CONFIG_SND_DEBUG
7269 [ALC260_TEST] = {
f9e336f6 7270 .mixers = { alc260_test_mixer },
7cf51e48
JW
7271 .init_verbs = { alc260_test_init_verbs },
7272 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7273 .dac_nids = alc260_test_dac_nids,
7274 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7275 .adc_nids = alc260_test_adc_nids,
7276 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7277 .channel_mode = alc260_modes,
a1e8d2da
JW
7278 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7279 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7280 },
7281#endif
df694daa
KY
7282};
7283
7284static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7285{
7286 struct alc_spec *spec;
df694daa 7287 int err, board_config;
1da177e4 7288
e560d8d8 7289 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7290 if (spec == NULL)
7291 return -ENOMEM;
7292
7293 codec->spec = spec;
7294
f5fcc13c
TI
7295 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7296 alc260_models,
7297 alc260_cfg_tbl);
7298 if (board_config < 0) {
9a11f1aa 7299 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7300 codec->chip_name);
df694daa 7301 board_config = ALC260_AUTO;
16ded525 7302 }
1da177e4 7303
fc091769
TI
7304 if (board_config == ALC260_AUTO)
7305 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 1);
7306
df694daa
KY
7307 if (board_config == ALC260_AUTO) {
7308 /* automatic parse from the BIOS config */
7309 err = alc260_parse_auto_config(codec);
7310 if (err < 0) {
7311 alc_free(codec);
7312 return err;
f12ab1e0 7313 } else if (!err) {
9c7f852e
TI
7314 printk(KERN_INFO
7315 "hda_codec: Cannot set up configuration "
7316 "from BIOS. Using base mode...\n");
df694daa
KY
7317 board_config = ALC260_BASIC;
7318 }
a9430dd8 7319 }
e9edcee0 7320
680cd536
KK
7321 err = snd_hda_attach_beep_device(codec, 0x1);
7322 if (err < 0) {
7323 alc_free(codec);
7324 return err;
7325 }
7326
df694daa 7327 if (board_config != ALC260_AUTO)
e9c364c0 7328 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7329
1da177e4
LT
7330 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7331 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7332 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7333
a3bcba38
TI
7334 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7335 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7336
4ef0ef19
TI
7337 if (!spec->adc_nids && spec->input_mux) {
7338 /* check whether NID 0x04 is valid */
7339 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7340 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7341 /* get type */
7342 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7343 spec->adc_nids = alc260_adc_nids_alt;
7344 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7345 } else {
7346 spec->adc_nids = alc260_adc_nids;
7347 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7348 }
7349 }
b59bdf3b 7350 set_capture_mixer(codec);
45bdd1c1 7351 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7352
fc091769
TI
7353 if (board_config == ALC260_AUTO)
7354 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 0);
7355
2134ea4f
TI
7356 spec->vmaster_nid = 0x08;
7357
1da177e4 7358 codec->patch_ops = alc_patch_ops;
df694daa 7359 if (board_config == ALC260_AUTO)
ae6b813a 7360 spec->init_hook = alc260_auto_init;
cb53c626
TI
7361#ifdef CONFIG_SND_HDA_POWER_SAVE
7362 if (!spec->loopback.amplist)
7363 spec->loopback.amplist = alc260_loopbacks;
7364#endif
1da177e4
LT
7365
7366 return 0;
7367}
7368
e9edcee0 7369
1da177e4 7370/*
4953550a 7371 * ALC882/883/885/888/889 support
1da177e4
LT
7372 *
7373 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7374 * configuration. Each pin widget can choose any input DACs and a mixer.
7375 * Each ADC is connected from a mixer of all inputs. This makes possible
7376 * 6-channel independent captures.
7377 *
7378 * In addition, an independent DAC for the multi-playback (not used in this
7379 * driver yet).
7380 */
df694daa
KY
7381#define ALC882_DIGOUT_NID 0x06
7382#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7383#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7384#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7385#define ALC1200_DIGOUT_NID 0x10
7386
1da177e4 7387
d2a6d7dc 7388static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7389 { 8, NULL }
7390};
7391
4953550a 7392/* DACs */
1da177e4
LT
7393static hda_nid_t alc882_dac_nids[4] = {
7394 /* front, rear, clfe, rear_surr */
7395 0x02, 0x03, 0x04, 0x05
7396};
4953550a 7397#define alc883_dac_nids alc882_dac_nids
1da177e4 7398
4953550a 7399/* ADCs */
df694daa
KY
7400#define alc882_adc_nids alc880_adc_nids
7401#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
7402#define alc883_adc_nids alc882_adc_nids_alt
7403static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7404static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7405#define alc889_adc_nids alc880_adc_nids
1da177e4 7406
e1406348
TI
7407static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7408static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
7409#define alc883_capsrc_nids alc882_capsrc_nids_alt
7410static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7411#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7412
1da177e4
LT
7413/* input MUX */
7414/* FIXME: should be a matrix-type input source selection */
7415
7416static struct hda_input_mux alc882_capture_source = {
7417 .num_items = 4,
7418 .items = {
7419 { "Mic", 0x0 },
7420 { "Front Mic", 0x1 },
7421 { "Line", 0x2 },
7422 { "CD", 0x4 },
7423 },
7424};
41d5545d 7425
4953550a
TI
7426#define alc883_capture_source alc882_capture_source
7427
87a8c370
JK
7428static struct hda_input_mux alc889_capture_source = {
7429 .num_items = 3,
7430 .items = {
7431 { "Front Mic", 0x0 },
7432 { "Mic", 0x3 },
7433 { "Line", 0x2 },
7434 },
7435};
7436
41d5545d
KS
7437static struct hda_input_mux mb5_capture_source = {
7438 .num_items = 3,
7439 .items = {
7440 { "Mic", 0x1 },
b8f171e7 7441 { "Line", 0x7 },
41d5545d
KS
7442 { "CD", 0x4 },
7443 },
7444};
7445
e458b1fa
LY
7446static struct hda_input_mux macmini3_capture_source = {
7447 .num_items = 2,
7448 .items = {
7449 { "Line", 0x2 },
7450 { "CD", 0x4 },
7451 },
7452};
7453
4953550a
TI
7454static struct hda_input_mux alc883_3stack_6ch_intel = {
7455 .num_items = 4,
7456 .items = {
7457 { "Mic", 0x1 },
7458 { "Front Mic", 0x0 },
7459 { "Line", 0x2 },
7460 { "CD", 0x4 },
7461 },
7462};
7463
7464static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7465 .num_items = 2,
7466 .items = {
7467 { "Mic", 0x1 },
7468 { "Line", 0x2 },
7469 },
7470};
7471
7472static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7473 .num_items = 4,
7474 .items = {
7475 { "Mic", 0x0 },
28c4edb7 7476 { "Internal Mic", 0x1 },
4953550a
TI
7477 { "Line", 0x2 },
7478 { "CD", 0x4 },
7479 },
7480};
7481
7482static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7483 .num_items = 2,
7484 .items = {
7485 { "Mic", 0x0 },
28c4edb7 7486 { "Internal Mic", 0x1 },
4953550a
TI
7487 },
7488};
7489
7490static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7491 .num_items = 3,
7492 .items = {
7493 { "Mic", 0x0 },
7494 { "Front Mic", 0x1 },
7495 { "Line", 0x4 },
7496 },
7497};
7498
7499static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7500 .num_items = 2,
7501 .items = {
7502 { "Mic", 0x0 },
7503 { "Line", 0x2 },
7504 },
7505};
7506
7507static struct hda_input_mux alc889A_mb31_capture_source = {
7508 .num_items = 2,
7509 .items = {
7510 { "Mic", 0x0 },
7511 /* Front Mic (0x01) unused */
7512 { "Line", 0x2 },
7513 /* Line 2 (0x03) unused */
af901ca1 7514 /* CD (0x04) unused? */
4953550a
TI
7515 },
7516};
7517
b7cccc52
JM
7518static struct hda_input_mux alc889A_imac91_capture_source = {
7519 .num_items = 2,
7520 .items = {
7521 { "Mic", 0x01 },
7522 { "Line", 0x2 }, /* Not sure! */
7523 },
7524};
7525
4953550a
TI
7526/*
7527 * 2ch mode
7528 */
7529static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7530 { 2, NULL }
7531};
7532
272a527c
KY
7533/*
7534 * 2ch mode
7535 */
7536static struct hda_verb alc882_3ST_ch2_init[] = {
7537 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7538 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7539 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7540 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7541 { } /* end */
7542};
7543
4953550a
TI
7544/*
7545 * 4ch mode
7546 */
7547static struct hda_verb alc882_3ST_ch4_init[] = {
7548 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7549 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7550 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7551 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7552 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7553 { } /* end */
7554};
7555
272a527c
KY
7556/*
7557 * 6ch mode
7558 */
7559static struct hda_verb alc882_3ST_ch6_init[] = {
7560 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7561 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7562 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7563 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7564 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7565 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7566 { } /* end */
7567};
7568
4953550a 7569static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7570 { 2, alc882_3ST_ch2_init },
4953550a 7571 { 4, alc882_3ST_ch4_init },
272a527c
KY
7572 { 6, alc882_3ST_ch6_init },
7573};
7574
4953550a
TI
7575#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7576
a65cc60f 7577/*
7578 * 2ch mode
7579 */
7580static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7581 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7582 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7583 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7584 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7585 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7586 { } /* end */
7587};
7588
7589/*
7590 * 4ch mode
7591 */
7592static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7593 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7594 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7595 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7596 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7597 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7598 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7599 { } /* end */
7600};
7601
7602/*
7603 * 6ch mode
7604 */
7605static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7606 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7607 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7608 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7609 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7610 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7611 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7612 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7613 { } /* end */
7614};
7615
7616static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7617 { 2, alc883_3ST_ch2_clevo_init },
7618 { 4, alc883_3ST_ch4_clevo_init },
7619 { 6, alc883_3ST_ch6_clevo_init },
7620};
7621
7622
df694daa
KY
7623/*
7624 * 6ch mode
7625 */
7626static struct hda_verb alc882_sixstack_ch6_init[] = {
7627 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7628 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7629 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7630 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7631 { } /* end */
7632};
7633
7634/*
7635 * 8ch mode
7636 */
7637static struct hda_verb alc882_sixstack_ch8_init[] = {
7638 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7639 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7640 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7641 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7642 { } /* end */
7643};
7644
7645static struct hda_channel_mode alc882_sixstack_modes[2] = {
7646 { 6, alc882_sixstack_ch6_init },
7647 { 8, alc882_sixstack_ch8_init },
7648};
7649
76e6f5a9
RH
7650
7651/* Macbook Air 2,1 */
7652
7653static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7654 { 2, NULL },
7655};
7656
87350ad0 7657/*
def319f9 7658 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7659 */
7660
7661/*
7662 * 2ch mode
7663 */
7664static struct hda_verb alc885_mbp_ch2_init[] = {
7665 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7666 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7667 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7668 { } /* end */
7669};
7670
7671/*
a3f730af 7672 * 4ch mode
87350ad0 7673 */
a3f730af 7674static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
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 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7679 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7680 { } /* end */
7681};
7682
a3f730af 7683static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7684 { 2, alc885_mbp_ch2_init },
a3f730af 7685 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7686};
7687
92b9de83
KS
7688/*
7689 * 2ch
7690 * Speakers/Woofer/HP = Front
7691 * LineIn = Input
7692 */
7693static struct hda_verb alc885_mb5_ch2_init[] = {
7694 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7695 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7696 { } /* end */
7697};
7698
7699/*
7700 * 6ch mode
7701 * Speakers/HP = Front
7702 * Woofer = LFE
7703 * LineIn = Surround
7704 */
7705static struct hda_verb alc885_mb5_ch6_init[] = {
7706 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7707 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7708 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7709 { } /* end */
7710};
7711
7712static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7713 { 2, alc885_mb5_ch2_init },
7714 { 6, alc885_mb5_ch6_init },
7715};
87350ad0 7716
d01aecdf 7717#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7718
7719/*
7720 * 2ch mode
7721 */
7722static struct hda_verb alc883_4ST_ch2_init[] = {
7723 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7724 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7725 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7726 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7727 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7728 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7729 { } /* end */
7730};
7731
7732/*
7733 * 4ch mode
7734 */
7735static struct hda_verb alc883_4ST_ch4_init[] = {
7736 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7737 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7738 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7739 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7740 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7741 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7742 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7743 { } /* end */
7744};
7745
7746/*
7747 * 6ch mode
7748 */
7749static struct hda_verb alc883_4ST_ch6_init[] = {
7750 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7751 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7752 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7753 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7754 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7755 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7756 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7757 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7758 { } /* end */
7759};
7760
7761/*
7762 * 8ch mode
7763 */
7764static struct hda_verb alc883_4ST_ch8_init[] = {
7765 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7766 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7767 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7768 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7769 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7770 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7771 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7772 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7773 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7774 { } /* end */
7775};
7776
7777static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7778 { 2, alc883_4ST_ch2_init },
7779 { 4, alc883_4ST_ch4_init },
7780 { 6, alc883_4ST_ch6_init },
7781 { 8, alc883_4ST_ch8_init },
7782};
7783
7784
7785/*
7786 * 2ch mode
7787 */
7788static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7789 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7790 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7791 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7792 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7793 { } /* end */
7794};
7795
7796/*
7797 * 4ch mode
7798 */
7799static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7800 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7801 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7802 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7803 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7804 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7805 { } /* end */
7806};
7807
7808/*
7809 * 6ch mode
7810 */
7811static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7812 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7813 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7814 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7815 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7816 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7817 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7818 { } /* end */
7819};
7820
7821static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7822 { 2, alc883_3ST_ch2_intel_init },
7823 { 4, alc883_3ST_ch4_intel_init },
7824 { 6, alc883_3ST_ch6_intel_init },
7825};
7826
dd7714c9
WF
7827/*
7828 * 2ch mode
7829 */
7830static struct hda_verb alc889_ch2_intel_init[] = {
7831 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7832 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7833 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7834 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7835 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7836 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7837 { } /* end */
7838};
7839
87a8c370
JK
7840/*
7841 * 6ch mode
7842 */
7843static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7844 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7845 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7846 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7847 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7848 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7849 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7850 { } /* end */
7851};
7852
7853/*
7854 * 8ch mode
7855 */
7856static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7857 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7858 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7859 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7860 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7861 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7862 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7863 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7864 { } /* end */
7865};
7866
dd7714c9
WF
7867static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7868 { 2, alc889_ch2_intel_init },
87a8c370
JK
7869 { 6, alc889_ch6_intel_init },
7870 { 8, alc889_ch8_intel_init },
7871};
7872
4953550a
TI
7873/*
7874 * 6ch mode
7875 */
7876static struct hda_verb alc883_sixstack_ch6_init[] = {
7877 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7878 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7879 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7880 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7881 { } /* end */
7882};
7883
7884/*
7885 * 8ch mode
7886 */
7887static struct hda_verb alc883_sixstack_ch8_init[] = {
7888 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7889 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7890 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7891 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7892 { } /* end */
7893};
7894
7895static struct hda_channel_mode alc883_sixstack_modes[2] = {
7896 { 6, alc883_sixstack_ch6_init },
7897 { 8, alc883_sixstack_ch8_init },
7898};
7899
7900
1da177e4
LT
7901/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7902 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7903 */
c8b6bf9b 7904static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7905 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7906 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7907 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7908 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7909 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7910 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7911 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7912 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7913 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7914 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7915 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7916 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7917 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7918 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7919 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7920 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 7921 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1da177e4
LT
7922 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7923 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 7924 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1da177e4 7925 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7926 { } /* end */
7927};
7928
76e6f5a9
RH
7929/* Macbook Air 2,1 same control for HP and internal Speaker */
7930
7931static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7932 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7933 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7934 { }
7935};
7936
7937
87350ad0 7938static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7939 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7940 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7941 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7942 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7943 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7944 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7945 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7946 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7947 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5f99f86a
DH
7948 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
7949 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
87350ad0
TI
7950 { } /* end */
7951};
41d5545d
KS
7952
7953static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
7954 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7955 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7956 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7957 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7958 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7959 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
7960 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7961 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
7962 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7963 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
7964 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7965 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
7966 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
7967 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
41d5545d
KS
7968 { } /* end */
7969};
92b9de83 7970
e458b1fa
LY
7971static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7972 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7973 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7974 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7975 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7976 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7977 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7978 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7979 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7980 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7981 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
5f99f86a 7982 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
e458b1fa
LY
7983 { } /* end */
7984};
7985
4b7e1803 7986static struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
7987 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7988 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
7989 { } /* end */
7990};
7991
7992
bdd148a3
KY
7993static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7994 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7995 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7996 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7997 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7998 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7999 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8000 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8001 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3 8002 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
8003 { } /* end */
8004};
8005
272a527c
KY
8006static struct snd_kcontrol_new alc882_targa_mixer[] = {
8007 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8008 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8009 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8010 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8011 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8012 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8013 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8014 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8015 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8016 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8017 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8018 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8019 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272a527c
KY
8020 { } /* end */
8021};
8022
8023/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8024 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8025 */
8026static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8027 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8028 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8029 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8030 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8031 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8032 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8033 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8034 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8035 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8036 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8037 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8038 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8039 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8040 { } /* end */
8041};
8042
914759b7
TI
8043static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8044 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8045 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8046 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8047 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8048 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8049 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8050 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8051 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8052 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
914759b7 8053 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
8054 { } /* end */
8055};
8056
df694daa
KY
8057static struct snd_kcontrol_new alc882_chmode_mixer[] = {
8058 {
8059 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8060 .name = "Channel Mode",
8061 .info = alc_ch_mode_info,
8062 .get = alc_ch_mode_get,
8063 .put = alc_ch_mode_put,
8064 },
8065 { } /* end */
8066};
8067
4953550a 8068static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 8069 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
8070 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8071 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8072 /* Rear mixer */
05acb863
TI
8073 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8074 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8075 /* CLFE mixer */
05acb863
TI
8076 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8077 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8078 /* Side mixer */
05acb863
TI
8079 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8080 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8081
e9edcee0 8082 /* Front Pin: output 0 (0x0c) */
05acb863 8083 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8084 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8085 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 8086 /* Rear Pin: output 1 (0x0d) */
05acb863 8087 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8088 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8089 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 8090 /* CLFE Pin: output 2 (0x0e) */
05acb863 8091 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8092 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8093 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 8094 /* Side Pin: output 3 (0x0f) */
05acb863 8095 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8096 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8097 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 8098 /* Mic (rear) pin: input vref at 80% */
16ded525 8099 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8100 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8101 /* Front Mic pin: input vref at 80% */
16ded525 8102 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8103 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8104 /* Line In pin: input */
05acb863 8105 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
8106 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8107 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8108 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8109 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8110 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 8111 /* CD pin widget for input */
05acb863 8112 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
8113
8114 /* FIXME: use matrix-type input source selection */
8115 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 8116 /* Input mixer2 */
05acb863 8117 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 8118 /* Input mixer3 */
05acb863 8119 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
8120 /* ADC2: mute amp left and right */
8121 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8122 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
8123 /* ADC3: mute amp left and right */
8124 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8125 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
8126
8127 { }
8128};
8129
4953550a
TI
8130static struct hda_verb alc882_adc1_init_verbs[] = {
8131 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8132 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8133 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8134 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8135 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8136 /* ADC1: mute amp left and right */
8137 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8138 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8139 { }
8140};
8141
4b146cb0
TI
8142static struct hda_verb alc882_eapd_verbs[] = {
8143 /* change to EAPD mode */
8144 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8145 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8146 { }
4b146cb0
TI
8147};
8148
87a8c370
JK
8149static struct hda_verb alc889_eapd_verbs[] = {
8150 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8151 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8152 { }
8153};
8154
6732bd0d
WF
8155static struct hda_verb alc_hp15_unsol_verbs[] = {
8156 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8157 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8158 {}
8159};
87a8c370
JK
8160
8161static struct hda_verb alc885_init_verbs[] = {
8162 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8163 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8164 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8165 /* Rear mixer */
88102f3f
KY
8166 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8167 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8168 /* CLFE mixer */
88102f3f
KY
8169 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8170 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8171 /* Side mixer */
88102f3f
KY
8172 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8173 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8174
8175 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8176 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8177 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8178 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8179 /* Front Pin: output 0 (0x0c) */
8180 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8181 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8182 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8183 /* Rear Pin: output 1 (0x0d) */
8184 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8185 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8186 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8187 /* CLFE Pin: output 2 (0x0e) */
8188 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8189 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8190 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8191 /* Side Pin: output 3 (0x0f) */
8192 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8193 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8194 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8195 /* Mic (rear) pin: input vref at 80% */
8196 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8197 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8198 /* Front Mic pin: input vref at 80% */
8199 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8200 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8201 /* Line In pin: input */
8202 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8203 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8204
8205 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8206 /* Input mixer1 */
88102f3f 8207 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8208 /* Input mixer2 */
8209 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8210 /* Input mixer3 */
88102f3f 8211 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8212 /* ADC2: mute amp left and right */
8213 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8214 /* ADC3: mute amp left and right */
8215 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8216
8217 { }
8218};
8219
8220static struct hda_verb alc885_init_input_verbs[] = {
8221 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8222 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8223 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8224 { }
8225};
8226
8227
8228/* Unmute Selector 24h and set the default input to front mic */
8229static struct hda_verb alc889_init_input_verbs[] = {
8230 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8231 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8232 { }
8233};
8234
8235
4953550a
TI
8236#define alc883_init_verbs alc882_base_init_verbs
8237
9102cd1c
TD
8238/* Mac Pro test */
8239static struct snd_kcontrol_new alc882_macpro_mixer[] = {
8240 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8241 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8242 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8243 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8244 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8245 /* FIXME: this looks suspicious...
d355c82a
JK
8246 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8247 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8248 */
9102cd1c
TD
8249 { } /* end */
8250};
8251
8252static struct hda_verb alc882_macpro_init_verbs[] = {
8253 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8254 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8255 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8256 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8257 /* Front Pin: output 0 (0x0c) */
8258 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8259 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8260 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8261 /* Front Mic pin: input vref at 80% */
8262 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8263 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8264 /* Speaker: output */
8265 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8266 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8267 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8268 /* Headphone output (output 0 - 0x0c) */
8269 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8270 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8271 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8272
8273 /* FIXME: use matrix-type input source selection */
8274 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8275 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8276 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8277 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8278 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8279 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8280 /* Input mixer2 */
8281 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8282 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8283 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8284 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8285 /* Input mixer3 */
8286 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8287 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8288 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8289 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8290 /* ADC1: mute amp left and right */
8291 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8292 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8293 /* ADC2: mute amp left and right */
8294 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8295 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8296 /* ADC3: mute amp left and right */
8297 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8298 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8299
8300 { }
8301};
f12ab1e0 8302
41d5545d
KS
8303/* Macbook 5,1 */
8304static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8305 /* DACs */
8306 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8307 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8308 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8309 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8310 /* Front mixer */
41d5545d
KS
8311 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8312 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8313 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8314 /* Surround mixer */
8315 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8316 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8317 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8318 /* LFE mixer */
8319 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8320 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8321 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8322 /* HP mixer */
8323 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8324 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8325 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8326 /* Front Pin (0x0c) */
41d5545d
KS
8327 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8328 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8329 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8330 /* LFE Pin (0x0e) */
8331 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8332 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8333 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8334 /* HP Pin (0x0f) */
41d5545d
KS
8335 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8336 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8337 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8338 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8339 /* Front Mic pin: input vref at 80% */
8340 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8341 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8342 /* Line In pin */
8343 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8344 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8345
b8f171e7
AM
8346 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8347 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8348 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8349 { }
8350};
8351
e458b1fa
LY
8352/* Macmini 3,1 */
8353static struct hda_verb alc885_macmini3_init_verbs[] = {
8354 /* DACs */
8355 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8356 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8357 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8358 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8359 /* Front mixer */
8360 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8361 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8362 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8363 /* Surround mixer */
8364 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8365 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8366 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8367 /* LFE mixer */
8368 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8369 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8370 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8371 /* HP mixer */
8372 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8373 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8374 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8375 /* Front Pin (0x0c) */
8376 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8377 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8378 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8379 /* LFE Pin (0x0e) */
8380 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8381 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8382 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8383 /* HP Pin (0x0f) */
8384 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8385 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8386 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8387 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8388 /* Line In pin */
8389 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8390 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8391
8392 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8393 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8394 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8395 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8396 { }
8397};
8398
76e6f5a9
RH
8399
8400static struct hda_verb alc885_mba21_init_verbs[] = {
8401 /*Internal and HP Speaker Mixer*/
8402 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8403 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8404 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8405 /*Internal Speaker Pin (0x0c)*/
8406 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8407 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8408 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8409 /* HP Pin: output 0 (0x0e) */
8410 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8411 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8412 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8413 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8414 /* Line in (is hp when jack connected)*/
8415 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8416 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8417
8418 { }
8419 };
8420
8421
87350ad0
TI
8422/* Macbook Pro rev3 */
8423static struct hda_verb alc885_mbp3_init_verbs[] = {
8424 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8425 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8426 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8427 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8428 /* Rear mixer */
8429 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8430 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8431 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8432 /* HP mixer */
8433 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8434 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8435 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8436 /* Front Pin: output 0 (0x0c) */
8437 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8438 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8439 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8440 /* HP Pin: output 0 (0x0e) */
87350ad0 8441 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8442 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8443 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8444 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8445 /* Mic (rear) pin: input vref at 80% */
8446 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8447 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8448 /* Front Mic pin: input vref at 80% */
8449 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8450 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8451 /* Line In pin: use output 1 when in LineOut mode */
8452 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8453 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8454 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8455
8456 /* FIXME: use matrix-type input source selection */
8457 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8458 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8459 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8460 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8461 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8462 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8463 /* Input mixer2 */
8464 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8465 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8466 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8467 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8468 /* Input mixer3 */
8469 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8470 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8471 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8472 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8473 /* ADC1: mute amp left and right */
8474 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8475 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8476 /* ADC2: mute amp left and right */
8477 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8478 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8479 /* ADC3: mute amp left and right */
8480 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8481 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8482
8483 { }
8484};
8485
4b7e1803
JM
8486/* iMac 9,1 */
8487static struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8488 /* Internal Speaker Pin (0x0c) */
8489 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8490 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8491 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8492 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8493 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8494 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8495 /* HP Pin: Rear */
4b7e1803
JM
8496 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8497 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8498 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8499 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8500 /* Line in Rear */
8501 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8502 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8503 /* Front Mic pin: input vref at 80% */
8504 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8505 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8506 /* Rear mixer */
8507 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8508 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8509 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8510 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8511 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8513 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8514 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8515 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8516 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8517 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8518 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8519 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8520 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8521 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8522 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8523 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8524 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8525 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8526 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8527 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8528 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8529 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8530 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8531 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8532 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8533 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8534 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8535 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8536 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8537 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8538 { }
8539};
8540
c54728d8
NF
8541/* iMac 24 mixer. */
8542static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8543 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8544 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8545 { } /* end */
8546};
8547
8548/* iMac 24 init verbs. */
8549static struct hda_verb alc885_imac24_init_verbs[] = {
8550 /* Internal speakers: output 0 (0x0c) */
8551 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8552 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8553 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8554 /* Internal speakers: output 0 (0x0c) */
8555 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8556 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8557 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8558 /* Headphone: output 0 (0x0c) */
8559 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8560 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8561 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8562 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8563 /* Front Mic: input vref at 80% */
8564 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8565 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8566 { }
8567};
8568
8569/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8570static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8571{
a9fd4f3f 8572 struct alc_spec *spec = codec->spec;
c54728d8 8573
a9fd4f3f
TI
8574 spec->autocfg.hp_pins[0] = 0x14;
8575 spec->autocfg.speaker_pins[0] = 0x18;
8576 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8577}
8578
9d54f08b
TI
8579#define alc885_mb5_setup alc885_imac24_setup
8580#define alc885_macmini3_setup alc885_imac24_setup
8581
76e6f5a9
RH
8582/* Macbook Air 2,1 */
8583static void alc885_mba21_setup(struct hda_codec *codec)
8584{
8585 struct alc_spec *spec = codec->spec;
8586
8587 spec->autocfg.hp_pins[0] = 0x14;
8588 spec->autocfg.speaker_pins[0] = 0x18;
8589}
8590
8591
8592
4f5d1706 8593static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8594{
a9fd4f3f 8595 struct alc_spec *spec = codec->spec;
87350ad0 8596
a9fd4f3f
TI
8597 spec->autocfg.hp_pins[0] = 0x15;
8598 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8599}
8600
9d54f08b 8601static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8602{
9d54f08b 8603 struct alc_spec *spec = codec->spec;
4b7e1803 8604
9d54f08b 8605 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8606 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8607 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8608}
87350ad0 8609
272a527c
KY
8610static struct hda_verb alc882_targa_verbs[] = {
8611 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8613
8614 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8615 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8616
272a527c
KY
8617 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8618 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8619 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8620
8621 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8622 { } /* end */
8623};
8624
8625/* toggle speaker-output according to the hp-jack state */
8626static void alc882_targa_automute(struct hda_codec *codec)
8627{
a9fd4f3f
TI
8628 struct alc_spec *spec = codec->spec;
8629 alc_automute_amp(codec);
82beb8fd 8630 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8631 spec->jack_present ? 1 : 3);
8632}
8633
4f5d1706 8634static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8635{
8636 struct alc_spec *spec = codec->spec;
8637
8638 spec->autocfg.hp_pins[0] = 0x14;
8639 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8640}
8641
8642static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8643{
a9fd4f3f 8644 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8645 alc882_targa_automute(codec);
272a527c
KY
8646}
8647
8648static struct hda_verb alc882_asus_a7j_verbs[] = {
8649 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8650 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8651
8652 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8653 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8654 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8655
272a527c
KY
8656 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8657 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8658 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8659
8660 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8661 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8662 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8663 { } /* end */
8664};
8665
914759b7
TI
8666static struct hda_verb alc882_asus_a7m_verbs[] = {
8667 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8668 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8669
8670 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8671 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8672 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8673
914759b7
TI
8674 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8675 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8676 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8677
8678 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8679 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8680 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8681 { } /* end */
8682};
8683
9102cd1c
TD
8684static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8685{
8686 unsigned int gpiostate, gpiomask, gpiodir;
8687
8688 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8689 AC_VERB_GET_GPIO_DATA, 0);
8690
8691 if (!muted)
8692 gpiostate |= (1 << pin);
8693 else
8694 gpiostate &= ~(1 << pin);
8695
8696 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8697 AC_VERB_GET_GPIO_MASK, 0);
8698 gpiomask |= (1 << pin);
8699
8700 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8701 AC_VERB_GET_GPIO_DIRECTION, 0);
8702 gpiodir |= (1 << pin);
8703
8704
8705 snd_hda_codec_write(codec, codec->afg, 0,
8706 AC_VERB_SET_GPIO_MASK, gpiomask);
8707 snd_hda_codec_write(codec, codec->afg, 0,
8708 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8709
8710 msleep(1);
8711
8712 snd_hda_codec_write(codec, codec->afg, 0,
8713 AC_VERB_SET_GPIO_DATA, gpiostate);
8714}
8715
7debbe51
TI
8716/* set up GPIO at initialization */
8717static void alc885_macpro_init_hook(struct hda_codec *codec)
8718{
8719 alc882_gpio_mute(codec, 0, 0);
8720 alc882_gpio_mute(codec, 1, 0);
8721}
8722
8723/* set up GPIO and update auto-muting at initialization */
8724static void alc885_imac24_init_hook(struct hda_codec *codec)
8725{
8726 alc885_macpro_init_hook(codec);
4f5d1706 8727 alc_automute_amp(codec);
7debbe51
TI
8728}
8729
df694daa
KY
8730/*
8731 * generic initialization of ADC, input mixers and output mixers
8732 */
4953550a 8733static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8734 /*
8735 * Unmute ADC0-2 and set the default input to mic-in
8736 */
4953550a
TI
8737 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8738 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8739 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8740 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8741
4953550a
TI
8742 /*
8743 * Set up output mixers (0x0c - 0x0f)
8744 */
8745 /* set vol=0 to output mixers */
8746 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8747 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8748 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8749 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8750 /* set up input amps for analog loopback */
8751 /* Amp Indices: DAC = 0, mixer = 1 */
8752 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8753 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8754 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8755 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8756 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8757 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8758 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8759 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8760 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8761 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8762
4953550a
TI
8763 /* FIXME: use matrix-type input source selection */
8764 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8765 /* Input mixer2 */
88102f3f 8766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8767 /* Input mixer3 */
88102f3f 8768 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8769 { }
9c7f852e
TI
8770};
8771
eb4c41d3
TS
8772/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8773static struct hda_verb alc889A_mb31_ch2_init[] = {
8774 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8775 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8776 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8777 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8778 { } /* end */
8779};
8780
8781/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8782static struct hda_verb alc889A_mb31_ch4_init[] = {
8783 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8784 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8785 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8786 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8787 { } /* end */
8788};
8789
8790/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8791static struct hda_verb alc889A_mb31_ch5_init[] = {
8792 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8793 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8794 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8795 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8796 { } /* end */
8797};
8798
8799/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8800static struct hda_verb alc889A_mb31_ch6_init[] = {
8801 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8802 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8803 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8804 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8805 { } /* end */
8806};
8807
8808static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8809 { 2, alc889A_mb31_ch2_init },
8810 { 4, alc889A_mb31_ch4_init },
8811 { 5, alc889A_mb31_ch5_init },
8812 { 6, alc889A_mb31_ch6_init },
8813};
8814
b373bdeb
AN
8815static struct hda_verb alc883_medion_eapd_verbs[] = {
8816 /* eanable EAPD on medion laptop */
8817 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8818 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8819 { }
8820};
8821
4953550a 8822#define alc883_base_mixer alc882_base_mixer
834be88d 8823
a8848bd6
AS
8824static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8825 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8826 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8827 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8828 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8829 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8830 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8831 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8832 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8833 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
a8848bd6
AS
8834 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8835 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8836 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
a8848bd6 8837 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8838 { } /* end */
8839};
8840
0c4cc443 8841static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8842 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8843 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8844 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8845 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8846 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8847 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
368c7a95 8848 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8849 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8850 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8851 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8852 { } /* end */
8853};
8854
fb97dc67
J
8855static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8856 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8857 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8858 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8859 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8861 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
fb97dc67 8862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8863 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8864 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8865 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8866 { } /* end */
8867};
8868
9c7f852e
TI
8869static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8870 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8871 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8872 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8873 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8874 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8875 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8876 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8877 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8878 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8879 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8880 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8881 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8882 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8883 { } /* end */
8884};
df694daa 8885
9c7f852e
TI
8886static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8887 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8888 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8889 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8890 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8891 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8892 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8893 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8894 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8895 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8896 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8897 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8898 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8899 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8900 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8901 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8902 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8903 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8904 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8905 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8906 { } /* end */
8907};
8908
17bba1b7
J
8909static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8910 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8911 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8912 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8913 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8914 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8915 HDA_OUTPUT),
8916 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8917 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8918 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8919 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8920 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8921 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8922 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8923 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8924 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8925 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
17bba1b7
J
8926 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8927 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8928 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
17bba1b7 8929 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8930 { } /* end */
8931};
8932
87a8c370
JK
8933static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8934 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8935 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8936 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8937 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8938 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8939 HDA_OUTPUT),
8940 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8941 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8942 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8943 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8944 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8945 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8946 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8947 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8948 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
5f99f86a 8949 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
87a8c370
JK
8950 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8951 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8952 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
87a8c370
JK
8953 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8954 { } /* end */
8955};
8956
d1d985f0 8957static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8958 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8959 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8960 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8961 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8962 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8963 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8964 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8965 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8966 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8967 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8968 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8969 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8970 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8972 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
c07584c8
TD
8973 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8974 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8975 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
c07584c8 8976 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
8977 { } /* end */
8978};
8979
c259249f 8980static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 8981 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8982 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8983 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8984 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8985 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8986 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8987 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8988 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8989 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8990 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8991 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8992 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8993 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8994 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8996 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 8997 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 8998 { } /* end */
f12ab1e0 8999};
ccc656ce 9000
c259249f 9001static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 9002 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9003 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9004 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9005 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9006 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9007 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9008 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9009 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9010 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9011 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9012 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9013 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 9014 { } /* end */
f12ab1e0 9015};
ccc656ce 9016
b99dba34
TI
9017static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9018 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9019 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
28c4edb7 9020 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9021 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9022 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
b99dba34
TI
9023 { } /* end */
9024};
9025
bc9f98a9
KY
9026static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9027 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9028 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
9029 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9030 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
9031 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9032 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9033 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bc9f98a9 9034 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 9035 { } /* end */
f12ab1e0 9036};
bc9f98a9 9037
272a527c
KY
9038static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9039 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9040 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9041 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9042 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9043 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9044 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9045 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
9046 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9047 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
9048 { } /* end */
9049};
9050
7ad7b218
MC
9051static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9052 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9053 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9054 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9055 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9056 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9057 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9058 { } /* end */
9059};
9060
9061static struct hda_verb alc883_medion_wim2160_verbs[] = {
9062 /* Unmute front mixer */
9063 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9064 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9065
9066 /* Set speaker pin to front mixer */
9067 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9068
9069 /* Init headphone pin */
9070 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9071 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9072 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9073 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9074
9075 { } /* end */
9076};
9077
9078/* toggle speaker-output according to the hp-jack state */
9079static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9080{
9081 struct alc_spec *spec = codec->spec;
9082
9083 spec->autocfg.hp_pins[0] = 0x1a;
9084 spec->autocfg.speaker_pins[0] = 0x15;
9085}
9086
2880a867 9087static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
9088 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9089 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 9090 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
9091 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9092 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6 9093 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9094 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d1a991a6 9095 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 9096 { } /* end */
d1a991a6 9097};
2880a867 9098
d2fd4b09
TV
9099static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9100 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 9101 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
9102 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9103 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
9104 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9105 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9106 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9107 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d2fd4b09
TV
9108 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9109 { } /* end */
9110};
9111
e2757d5e
KY
9112static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9113 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9114 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9115 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9116 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9117 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9118 0x0d, 1, 0x0, HDA_OUTPUT),
9119 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9120 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9121 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9122 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9123 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
9124 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9125 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9126 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9127 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9128 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9129 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e2757d5e
KY
9130 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9131 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9132 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
e2757d5e 9133 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9134 { } /* end */
9135};
9136
eb4c41d3
TS
9137static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9138 /* Output mixers */
9139 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9140 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9141 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9142 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9143 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9144 HDA_OUTPUT),
9145 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9146 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9147 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9148 /* Output switches */
9149 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9150 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9151 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9152 /* Boost mixers */
5f99f86a
DH
9153 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9154 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
eb4c41d3
TS
9155 /* Input mixers */
9156 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9157 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9158 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9159 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9160 { } /* end */
9161};
9162
3e1647c5
GG
9163static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9164 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9165 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9166 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9167 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9168 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
3e1647c5
GG
9169 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9170 { } /* end */
9171};
9172
e2757d5e
KY
9173static struct hda_bind_ctls alc883_bind_cap_vol = {
9174 .ops = &snd_hda_bind_vol,
9175 .values = {
9176 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9177 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9178 0
9179 },
9180};
9181
9182static struct hda_bind_ctls alc883_bind_cap_switch = {
9183 .ops = &snd_hda_bind_sw,
9184 .values = {
9185 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9186 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9187 0
9188 },
9189};
9190
9191static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9192 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9193 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9194 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9195 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9196 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9197 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9198 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
4953550a
TI
9199 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9200 { } /* end */
9201};
df694daa 9202
4953550a
TI
9203static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9204 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9205 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9206 {
9207 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9208 /* .name = "Capture Source", */
9209 .name = "Input Source",
9210 .count = 1,
9211 .info = alc_mux_enum_info,
9212 .get = alc_mux_enum_get,
9213 .put = alc_mux_enum_put,
9214 },
9215 { } /* end */
9216};
9c7f852e 9217
4953550a
TI
9218static struct snd_kcontrol_new alc883_chmode_mixer[] = {
9219 {
9220 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9221 .name = "Channel Mode",
9222 .info = alc_ch_mode_info,
9223 .get = alc_ch_mode_get,
9224 .put = alc_ch_mode_put,
9225 },
9226 { } /* end */
9c7f852e
TI
9227};
9228
a8848bd6 9229/* toggle speaker-output according to the hp-jack state */
4f5d1706 9230static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9231{
a9fd4f3f 9232 struct alc_spec *spec = codec->spec;
a8848bd6 9233
a9fd4f3f
TI
9234 spec->autocfg.hp_pins[0] = 0x15;
9235 spec->autocfg.speaker_pins[0] = 0x14;
9236 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
9237}
9238
a8848bd6
AS
9239static struct hda_verb alc883_mitac_verbs[] = {
9240 /* HP */
9241 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9242 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9243 /* Subwoofer */
9244 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9245 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9246
9247 /* enable unsolicited event */
9248 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9249 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9250
9251 { } /* end */
9252};
9253
a65cc60f 9254static struct hda_verb alc883_clevo_m540r_verbs[] = {
9255 /* HP */
9256 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9257 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9258 /* Int speaker */
9259 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9260
9261 /* enable unsolicited event */
9262 /*
9263 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9264 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9265 */
9266
9267 { } /* end */
9268};
9269
0c4cc443 9270static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9271 /* HP */
9272 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9273 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9274 /* Int speaker */
9275 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9276 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9277
9278 /* enable unsolicited event */
9279 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9280 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9281
9282 { } /* end */
9283};
9284
fb97dc67
J
9285static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9286 /* HP */
9287 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9288 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9289 /* Subwoofer */
9290 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9291 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9292
9293 /* enable unsolicited event */
9294 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9295
9296 { } /* end */
9297};
9298
c259249f 9299static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9300 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9301 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9302
9303 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9304 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9305
64a8be74
DH
9306/* Connect Line-Out side jack (SPDIF) to Side */
9307 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9308 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9309 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9310/* Connect Mic jack to CLFE */
9311 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9312 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9313 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9314/* Connect Line-in jack to Surround */
9315 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9316 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9317 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9318/* Connect HP out jack to Front */
9319 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9320 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9321 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9322
9323 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9324
9325 { } /* end */
9326};
9327
bc9f98a9
KY
9328static struct hda_verb alc883_lenovo_101e_verbs[] = {
9329 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9330 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9331 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9332 { } /* end */
9333};
9334
272a527c
KY
9335static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9336 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9337 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9338 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9339 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9340 { } /* end */
9341};
9342
9343static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9344 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9345 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9346 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9347 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9348 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9349 { } /* end */
9350};
9351
189609ae
KY
9352static struct hda_verb alc883_haier_w66_verbs[] = {
9353 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9354 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9355
9356 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9357
9358 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9359 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9360 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9361 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9362 { } /* end */
9363};
9364
e2757d5e
KY
9365static struct hda_verb alc888_lenovo_sky_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 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9369 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9370 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9371 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9372 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9373 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9374 { } /* end */
9375};
9376
8718b700
HRK
9377static struct hda_verb alc888_6st_dell_verbs[] = {
9378 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9379 { }
9380};
9381
3e1647c5
GG
9382static struct hda_verb alc883_vaiott_verbs[] = {
9383 /* HP */
9384 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9385 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9386
9387 /* enable unsolicited event */
9388 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9389
9390 { } /* end */
9391};
9392
4f5d1706 9393static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9394{
a9fd4f3f 9395 struct alc_spec *spec = codec->spec;
8718b700 9396
a9fd4f3f
TI
9397 spec->autocfg.hp_pins[0] = 0x1b;
9398 spec->autocfg.speaker_pins[0] = 0x14;
9399 spec->autocfg.speaker_pins[1] = 0x16;
9400 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
9401}
9402
4723c022 9403static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9404 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9405 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9406 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9407 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9408 { } /* end */
5795b9e6
CM
9409};
9410
3ea0d7cf
HRK
9411/*
9412 * 2ch mode
9413 */
4723c022 9414static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9415 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9416 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9417 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9418 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9419 { } /* end */
8341de60
CM
9420};
9421
3ea0d7cf
HRK
9422/*
9423 * 4ch mode
9424 */
9425static struct hda_verb alc888_3st_hp_4ch_init[] = {
9426 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9427 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9428 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9429 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9430 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9431 { } /* end */
9432};
9433
9434/*
9435 * 6ch mode
9436 */
4723c022 9437static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9438 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9439 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9440 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9441 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9442 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9443 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9444 { } /* end */
8341de60
CM
9445};
9446
3ea0d7cf 9447static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9448 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9449 { 4, alc888_3st_hp_4ch_init },
4723c022 9450 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9451};
9452
272a527c
KY
9453/* toggle front-jack and RCA according to the hp-jack state */
9454static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9455{
864f92be 9456 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 9457
47fd830a
TI
9458 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9459 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9460 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9461 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
9462}
9463
9464/* toggle RCA according to the front-jack state */
9465static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9466{
864f92be 9467 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 9468
47fd830a
TI
9469 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9470 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 9471}
47fd830a 9472
272a527c
KY
9473static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9474 unsigned int res)
9475{
9476 if ((res >> 26) == ALC880_HP_EVENT)
9477 alc888_lenovo_ms7195_front_automute(codec);
9478 if ((res >> 26) == ALC880_FRONT_EVENT)
9479 alc888_lenovo_ms7195_rca_automute(codec);
9480}
9481
272a527c 9482/* toggle speaker-output according to the hp-jack state */
dc427170 9483static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
272a527c 9484{
a9fd4f3f 9485 struct alc_spec *spec = codec->spec;
272a527c 9486
a9fd4f3f
TI
9487 spec->autocfg.hp_pins[0] = 0x14;
9488 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
9489}
9490
ccc656ce 9491/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9492#define alc883_targa_init_hook alc882_targa_init_hook
9493#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9494
4f5d1706 9495static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9496{
a9fd4f3f
TI
9497 struct alc_spec *spec = codec->spec;
9498
9499 spec->autocfg.hp_pins[0] = 0x15;
9500 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
9501}
9502
9503static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9504{
a9fd4f3f 9505 alc_automute_amp(codec);
eeb43387 9506 alc88x_simple_mic_automute(codec);
0c4cc443
HRK
9507}
9508
9509static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9510 unsigned int res)
9511{
0c4cc443 9512 switch (res >> 26) {
0c4cc443 9513 case ALC880_MIC_EVENT:
eeb43387 9514 alc88x_simple_mic_automute(codec);
0c4cc443 9515 break;
a9fd4f3f
TI
9516 default:
9517 alc_automute_amp_unsol_event(codec, res);
9518 break;
0c4cc443 9519 }
368c7a95
J
9520}
9521
fb97dc67 9522/* toggle speaker-output according to the hp-jack state */
4f5d1706 9523static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9524{
a9fd4f3f 9525 struct alc_spec *spec = codec->spec;
fb97dc67 9526
a9fd4f3f
TI
9527 spec->autocfg.hp_pins[0] = 0x14;
9528 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9529}
9530
4f5d1706 9531static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9532{
a9fd4f3f 9533 struct alc_spec *spec = codec->spec;
189609ae 9534
a9fd4f3f
TI
9535 spec->autocfg.hp_pins[0] = 0x1b;
9536 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9537}
9538
bc9f98a9
KY
9539static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9540{
864f92be 9541 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9542
47fd830a
TI
9543 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9544 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9545}
9546
9547static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9548{
864f92be 9549 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9550
47fd830a
TI
9551 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9552 HDA_AMP_MUTE, bits);
9553 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9554 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9555}
9556
9557static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9558 unsigned int res)
9559{
9560 if ((res >> 26) == ALC880_HP_EVENT)
9561 alc883_lenovo_101e_all_automute(codec);
9562 if ((res >> 26) == ALC880_FRONT_EVENT)
9563 alc883_lenovo_101e_ispeaker_automute(codec);
9564}
9565
676a9b53 9566/* toggle speaker-output according to the hp-jack state */
4f5d1706 9567static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9568{
a9fd4f3f 9569 struct alc_spec *spec = codec->spec;
676a9b53 9570
a9fd4f3f
TI
9571 spec->autocfg.hp_pins[0] = 0x14;
9572 spec->autocfg.speaker_pins[0] = 0x15;
9573 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9574}
9575
d1a991a6
KY
9576static struct hda_verb alc883_acer_eapd_verbs[] = {
9577 /* HP Pin: output 0 (0x0c) */
9578 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9579 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9580 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9581 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9582 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9583 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9584 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9585 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9586 /* eanable EAPD on medion laptop */
9587 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9588 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9589 /* enable unsolicited event */
9590 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9591 { }
9592};
9593
4f5d1706 9594static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9595{
a9fd4f3f 9596 struct alc_spec *spec = codec->spec;
5795b9e6 9597
a9fd4f3f
TI
9598 spec->autocfg.hp_pins[0] = 0x1b;
9599 spec->autocfg.speaker_pins[0] = 0x14;
9600 spec->autocfg.speaker_pins[1] = 0x15;
9601 spec->autocfg.speaker_pins[2] = 0x16;
9602 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9603}
9604
4f5d1706 9605static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9606{
a9fd4f3f 9607 struct alc_spec *spec = codec->spec;
e2757d5e 9608
a9fd4f3f
TI
9609 spec->autocfg.hp_pins[0] = 0x1b;
9610 spec->autocfg.speaker_pins[0] = 0x14;
9611 spec->autocfg.speaker_pins[1] = 0x15;
9612 spec->autocfg.speaker_pins[2] = 0x16;
9613 spec->autocfg.speaker_pins[3] = 0x17;
9614 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9615}
9616
4f5d1706 9617static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9618{
9619 struct alc_spec *spec = codec->spec;
9620
9621 spec->autocfg.hp_pins[0] = 0x15;
9622 spec->autocfg.speaker_pins[0] = 0x14;
9623 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9624}
9625
e2757d5e
KY
9626static struct hda_verb alc888_asus_m90v_verbs[] = {
9627 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9628 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9629 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9630 /* enable unsolicited event */
9631 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9632 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9633 { } /* end */
9634};
9635
4f5d1706 9636static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9637{
a9fd4f3f 9638 struct alc_spec *spec = codec->spec;
e2757d5e 9639
a9fd4f3f
TI
9640 spec->autocfg.hp_pins[0] = 0x1b;
9641 spec->autocfg.speaker_pins[0] = 0x14;
9642 spec->autocfg.speaker_pins[1] = 0x15;
9643 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9644 spec->ext_mic.pin = 0x18;
9645 spec->int_mic.pin = 0x19;
9646 spec->ext_mic.mux_idx = 0;
9647 spec->int_mic.mux_idx = 1;
9648 spec->auto_mic = 1;
e2757d5e
KY
9649}
9650
9651static struct hda_verb alc888_asus_eee1601_verbs[] = {
9652 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9653 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9654 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9655 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9656 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9657 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9658 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9659 /* enable unsolicited event */
9660 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9661 { } /* end */
9662};
9663
e2757d5e
KY
9664static void alc883_eee1601_inithook(struct hda_codec *codec)
9665{
a9fd4f3f
TI
9666 struct alc_spec *spec = codec->spec;
9667
9668 spec->autocfg.hp_pins[0] = 0x14;
9669 spec->autocfg.speaker_pins[0] = 0x1b;
9670 alc_automute_pin(codec);
e2757d5e
KY
9671}
9672
eb4c41d3
TS
9673static struct hda_verb alc889A_mb31_verbs[] = {
9674 /* Init rear pin (used as headphone output) */
9675 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9676 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9677 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9678 /* Init line pin (used as output in 4ch and 6ch mode) */
9679 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9680 /* Init line 2 pin (used as headphone out by default) */
9681 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9682 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9683 { } /* end */
9684};
9685
9686/* Mute speakers according to the headphone jack state */
9687static void alc889A_mb31_automute(struct hda_codec *codec)
9688{
9689 unsigned int present;
9690
9691 /* Mute only in 2ch or 4ch mode */
9692 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9693 == 0x00) {
864f92be 9694 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9695 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9696 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9697 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9698 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9699 }
9700}
9701
9702static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9703{
9704 if ((res >> 26) == ALC880_HP_EVENT)
9705 alc889A_mb31_automute(codec);
9706}
9707
4953550a 9708
cb53c626 9709#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9710#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9711#endif
9712
def319f9 9713/* pcm configuration: identical with ALC880 */
4953550a
TI
9714#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9715#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9716#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9717#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9718
9719static hda_nid_t alc883_slave_dig_outs[] = {
9720 ALC1200_DIGOUT_NID, 0,
9721};
9722
9723static hda_nid_t alc1200_slave_dig_outs[] = {
9724 ALC883_DIGOUT_NID, 0,
9725};
9c7f852e
TI
9726
9727/*
9728 * configuration and preset
9729 */
4953550a
TI
9730static const char *alc882_models[ALC882_MODEL_LAST] = {
9731 [ALC882_3ST_DIG] = "3stack-dig",
9732 [ALC882_6ST_DIG] = "6stack-dig",
9733 [ALC882_ARIMA] = "arima",
9734 [ALC882_W2JC] = "w2jc",
9735 [ALC882_TARGA] = "targa",
9736 [ALC882_ASUS_A7J] = "asus-a7j",
9737 [ALC882_ASUS_A7M] = "asus-a7m",
9738 [ALC885_MACPRO] = "macpro",
9739 [ALC885_MB5] = "mb5",
e458b1fa 9740 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9741 [ALC885_MBA21] = "mba21",
4953550a
TI
9742 [ALC885_MBP3] = "mbp3",
9743 [ALC885_IMAC24] = "imac24",
4b7e1803 9744 [ALC885_IMAC91] = "imac91",
4953550a 9745 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9746 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9747 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9748 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9749 [ALC883_TARGA_DIG] = "targa-dig",
9750 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9751 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9752 [ALC883_ACER] = "acer",
2880a867 9753 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9754 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9755 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9756 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9757 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9758 [ALC883_MEDION] = "medion",
7ad7b218 9759 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9760 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9761 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9762 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9763 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9764 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9765 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9766 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9767 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9768 [ALC883_MITAC] = "mitac",
a65cc60f 9769 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9770 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9771 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9772 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9773 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9774 [ALC889A_INTEL] = "intel-alc889a",
9775 [ALC889_INTEL] = "intel-x58",
3ab90935 9776 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9777 [ALC889A_MB31] = "mb31",
3e1647c5 9778 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9779 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9780};
9781
4953550a
TI
9782static struct snd_pci_quirk alc882_cfg_tbl[] = {
9783 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9784
ac3e3741 9785 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9786 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9787 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9788 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9789 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9790 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9791 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9792 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9793 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9794 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9795 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9796 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9797 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9798 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9799 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9800 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9801 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9802 ALC888_ACER_ASPIRE_6530G),
cc374c47 9803 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9804 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9805 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9806 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9807 /* default Acer -- disabled as it causes more problems.
9808 * model=auto should work fine now
9809 */
9810 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9811
5795b9e6 9812 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9813
febe3375 9814 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9815 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9816 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9817 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9818 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9819 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9820
9821 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9822 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9823 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9824 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9825 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9826 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9827 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9828 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9829 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9830 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9831 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9832
9833 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9834 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9835 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9836 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9837 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9838 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9839 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9840 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9841 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9842
6f3bf657 9843 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9844 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9845 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9846 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9847 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9848 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9849 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9850 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9851 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9852 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9853 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9854 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9855 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9856 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9857 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9858 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9859 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9860 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9861 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9862 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9863 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9864 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9865 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9866 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9867 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9868 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9869 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9870 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9871 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9872 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9873 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9874
ac3e3741 9875 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9876 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9877 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9878 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9879 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9880 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9881 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9882 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9883 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9884 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9885 ALC883_FUJITSU_PI2515),
bfb53037 9886 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9887 ALC888_FUJITSU_XA3530),
272a527c 9888 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9889 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9890 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9891 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9892 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
959973b9 9893 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9894 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9895 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9896
17bba1b7
J
9897 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9898 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9899 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9900 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9901 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9902 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9903 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9904
4953550a 9905 {}
f3cd3f5d
WF
9906};
9907
4953550a
TI
9908/* codec SSID table for Intel Mac */
9909static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9910 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9911 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9912 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9913 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9914 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9915 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9916 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 9917 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 9918 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 9919 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 9920 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
9921 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9922 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9923 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9924 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9925 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 9926 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
9927 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9928 * so apparently no perfect solution yet
4953550a
TI
9929 */
9930 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9931 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9932 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9933 {} /* terminator */
b25c9da1
WF
9934};
9935
4953550a
TI
9936static struct alc_config_preset alc882_presets[] = {
9937 [ALC882_3ST_DIG] = {
9938 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9939 .init_verbs = { alc882_base_init_verbs,
9940 alc882_adc1_init_verbs },
4953550a
TI
9941 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9942 .dac_nids = alc882_dac_nids,
9943 .dig_out_nid = ALC882_DIGOUT_NID,
9944 .dig_in_nid = ALC882_DIGIN_NID,
9945 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9946 .channel_mode = alc882_ch_modes,
9947 .need_dac_fix = 1,
9948 .input_mux = &alc882_capture_source,
9949 },
9950 [ALC882_6ST_DIG] = {
9951 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9952 .init_verbs = { alc882_base_init_verbs,
9953 alc882_adc1_init_verbs },
4953550a
TI
9954 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9955 .dac_nids = alc882_dac_nids,
9956 .dig_out_nid = ALC882_DIGOUT_NID,
9957 .dig_in_nid = ALC882_DIGIN_NID,
9958 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9959 .channel_mode = alc882_sixstack_modes,
9960 .input_mux = &alc882_capture_source,
9961 },
9962 [ALC882_ARIMA] = {
9963 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9964 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9965 alc882_eapd_verbs },
4953550a
TI
9966 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9967 .dac_nids = alc882_dac_nids,
9968 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9969 .channel_mode = alc882_sixstack_modes,
9970 .input_mux = &alc882_capture_source,
9971 },
9972 [ALC882_W2JC] = {
9973 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9974 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9975 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
9976 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9977 .dac_nids = alc882_dac_nids,
9978 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9979 .channel_mode = alc880_threestack_modes,
9980 .need_dac_fix = 1,
9981 .input_mux = &alc882_capture_source,
9982 .dig_out_nid = ALC882_DIGOUT_NID,
9983 },
76e6f5a9
RH
9984 [ALC885_MBA21] = {
9985 .mixers = { alc885_mba21_mixer },
9986 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9987 .num_dacs = 2,
9988 .dac_nids = alc882_dac_nids,
9989 .channel_mode = alc885_mba21_ch_modes,
9990 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9991 .input_mux = &alc882_capture_source,
9992 .unsol_event = alc_automute_amp_unsol_event,
9993 .setup = alc885_mba21_setup,
9994 .init_hook = alc_automute_amp,
9995 },
4953550a
TI
9996 [ALC885_MBP3] = {
9997 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9998 .init_verbs = { alc885_mbp3_init_verbs,
9999 alc880_gpio1_init_verbs },
be0ae923 10000 .num_dacs = 2,
4953550a 10001 .dac_nids = alc882_dac_nids,
be0ae923
TI
10002 .hp_nid = 0x04,
10003 .channel_mode = alc885_mbp_4ch_modes,
10004 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
10005 .input_mux = &alc882_capture_source,
10006 .dig_out_nid = ALC882_DIGOUT_NID,
10007 .dig_in_nid = ALC882_DIGIN_NID,
10008 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10009 .setup = alc885_mbp3_setup,
10010 .init_hook = alc_automute_amp,
4953550a
TI
10011 },
10012 [ALC885_MB5] = {
10013 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10014 .init_verbs = { alc885_mb5_init_verbs,
10015 alc880_gpio1_init_verbs },
10016 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10017 .dac_nids = alc882_dac_nids,
10018 .channel_mode = alc885_mb5_6ch_modes,
10019 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10020 .input_mux = &mb5_capture_source,
10021 .dig_out_nid = ALC882_DIGOUT_NID,
10022 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10023 .unsol_event = alc_automute_amp_unsol_event,
10024 .setup = alc885_mb5_setup,
10025 .init_hook = alc_automute_amp,
4953550a 10026 },
e458b1fa
LY
10027 [ALC885_MACMINI3] = {
10028 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10029 .init_verbs = { alc885_macmini3_init_verbs,
10030 alc880_gpio1_init_verbs },
10031 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10032 .dac_nids = alc882_dac_nids,
10033 .channel_mode = alc885_macmini3_6ch_modes,
10034 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10035 .input_mux = &macmini3_capture_source,
10036 .dig_out_nid = ALC882_DIGOUT_NID,
10037 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10038 .unsol_event = alc_automute_amp_unsol_event,
10039 .setup = alc885_macmini3_setup,
10040 .init_hook = alc_automute_amp,
e458b1fa 10041 },
4953550a
TI
10042 [ALC885_MACPRO] = {
10043 .mixers = { alc882_macpro_mixer },
10044 .init_verbs = { alc882_macpro_init_verbs },
10045 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10046 .dac_nids = alc882_dac_nids,
10047 .dig_out_nid = ALC882_DIGOUT_NID,
10048 .dig_in_nid = ALC882_DIGIN_NID,
10049 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10050 .channel_mode = alc882_ch_modes,
10051 .input_mux = &alc882_capture_source,
10052 .init_hook = alc885_macpro_init_hook,
10053 },
10054 [ALC885_IMAC24] = {
10055 .mixers = { alc885_imac24_mixer },
10056 .init_verbs = { alc885_imac24_init_verbs },
10057 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10058 .dac_nids = alc882_dac_nids,
10059 .dig_out_nid = ALC882_DIGOUT_NID,
10060 .dig_in_nid = ALC882_DIGIN_NID,
10061 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10062 .channel_mode = alc882_ch_modes,
10063 .input_mux = &alc882_capture_source,
10064 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 10065 .setup = alc885_imac24_setup,
4953550a
TI
10066 .init_hook = alc885_imac24_init_hook,
10067 },
4b7e1803 10068 [ALC885_IMAC91] = {
b7cccc52 10069 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
10070 .init_verbs = { alc885_imac91_init_verbs,
10071 alc880_gpio1_init_verbs },
10072 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10073 .dac_nids = alc882_dac_nids,
b7cccc52
JM
10074 .channel_mode = alc885_mba21_ch_modes,
10075 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10076 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
10077 .dig_out_nid = ALC882_DIGOUT_NID,
10078 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10079 .unsol_event = alc_automute_amp_unsol_event,
10080 .setup = alc885_imac91_setup,
10081 .init_hook = alc_automute_amp,
4b7e1803 10082 },
4953550a
TI
10083 [ALC882_TARGA] = {
10084 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 10085 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 10086 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
10087 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10088 .dac_nids = alc882_dac_nids,
10089 .dig_out_nid = ALC882_DIGOUT_NID,
10090 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10091 .adc_nids = alc882_adc_nids,
10092 .capsrc_nids = alc882_capsrc_nids,
10093 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10094 .channel_mode = alc882_3ST_6ch_modes,
10095 .need_dac_fix = 1,
10096 .input_mux = &alc882_capture_source,
10097 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
10098 .setup = alc882_targa_setup,
10099 .init_hook = alc882_targa_automute,
4953550a
TI
10100 },
10101 [ALC882_ASUS_A7J] = {
10102 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10103 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10104 alc882_asus_a7j_verbs},
4953550a
TI
10105 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10106 .dac_nids = alc882_dac_nids,
10107 .dig_out_nid = ALC882_DIGOUT_NID,
10108 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10109 .adc_nids = alc882_adc_nids,
10110 .capsrc_nids = alc882_capsrc_nids,
10111 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10112 .channel_mode = alc882_3ST_6ch_modes,
10113 .need_dac_fix = 1,
10114 .input_mux = &alc882_capture_source,
10115 },
10116 [ALC882_ASUS_A7M] = {
10117 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10118 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10119 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10120 alc882_asus_a7m_verbs },
10121 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10122 .dac_nids = alc882_dac_nids,
10123 .dig_out_nid = ALC882_DIGOUT_NID,
10124 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10125 .channel_mode = alc880_threestack_modes,
10126 .need_dac_fix = 1,
10127 .input_mux = &alc882_capture_source,
10128 },
9c7f852e
TI
10129 [ALC883_3ST_2ch_DIG] = {
10130 .mixers = { alc883_3ST_2ch_mixer },
10131 .init_verbs = { alc883_init_verbs },
10132 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10133 .dac_nids = alc883_dac_nids,
10134 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10135 .dig_in_nid = ALC883_DIGIN_NID,
10136 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10137 .channel_mode = alc883_3ST_2ch_modes,
10138 .input_mux = &alc883_capture_source,
10139 },
10140 [ALC883_3ST_6ch_DIG] = {
10141 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10142 .init_verbs = { alc883_init_verbs },
10143 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10144 .dac_nids = alc883_dac_nids,
10145 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10146 .dig_in_nid = ALC883_DIGIN_NID,
10147 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10148 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10149 .need_dac_fix = 1,
9c7f852e 10150 .input_mux = &alc883_capture_source,
f12ab1e0 10151 },
9c7f852e
TI
10152 [ALC883_3ST_6ch] = {
10153 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10154 .init_verbs = { alc883_init_verbs },
10155 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10156 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10157 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10158 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10159 .need_dac_fix = 1,
9c7f852e 10160 .input_mux = &alc883_capture_source,
f12ab1e0 10161 },
17bba1b7
J
10162 [ALC883_3ST_6ch_INTEL] = {
10163 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10164 .init_verbs = { alc883_init_verbs },
10165 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10166 .dac_nids = alc883_dac_nids,
10167 .dig_out_nid = ALC883_DIGOUT_NID,
10168 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10169 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10170 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10171 .channel_mode = alc883_3ST_6ch_intel_modes,
10172 .need_dac_fix = 1,
10173 .input_mux = &alc883_3stack_6ch_intel,
10174 },
87a8c370
JK
10175 [ALC889A_INTEL] = {
10176 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10177 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10178 alc_hp15_unsol_verbs },
87a8c370
JK
10179 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10180 .dac_nids = alc883_dac_nids,
10181 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10182 .adc_nids = alc889_adc_nids,
10183 .dig_out_nid = ALC883_DIGOUT_NID,
10184 .dig_in_nid = ALC883_DIGIN_NID,
10185 .slave_dig_outs = alc883_slave_dig_outs,
10186 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10187 .channel_mode = alc889_8ch_intel_modes,
10188 .capsrc_nids = alc889_capsrc_nids,
10189 .input_mux = &alc889_capture_source,
4f5d1706
TI
10190 .setup = alc889_automute_setup,
10191 .init_hook = alc_automute_amp,
6732bd0d 10192 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10193 .need_dac_fix = 1,
10194 },
10195 [ALC889_INTEL] = {
10196 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10197 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10198 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10199 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10200 .dac_nids = alc883_dac_nids,
10201 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10202 .adc_nids = alc889_adc_nids,
10203 .dig_out_nid = ALC883_DIGOUT_NID,
10204 .dig_in_nid = ALC883_DIGIN_NID,
10205 .slave_dig_outs = alc883_slave_dig_outs,
10206 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10207 .channel_mode = alc889_8ch_intel_modes,
10208 .capsrc_nids = alc889_capsrc_nids,
10209 .input_mux = &alc889_capture_source,
4f5d1706 10210 .setup = alc889_automute_setup,
6732bd0d
WF
10211 .init_hook = alc889_intel_init_hook,
10212 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10213 .need_dac_fix = 1,
10214 },
9c7f852e
TI
10215 [ALC883_6ST_DIG] = {
10216 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10217 .init_verbs = { alc883_init_verbs },
10218 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10219 .dac_nids = alc883_dac_nids,
10220 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10221 .dig_in_nid = ALC883_DIGIN_NID,
10222 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10223 .channel_mode = alc883_sixstack_modes,
10224 .input_mux = &alc883_capture_source,
10225 },
ccc656ce 10226 [ALC883_TARGA_DIG] = {
c259249f 10227 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10228 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10229 alc883_targa_verbs},
ccc656ce
KY
10230 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10231 .dac_nids = alc883_dac_nids,
10232 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10233 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10234 .channel_mode = alc883_3ST_6ch_modes,
10235 .need_dac_fix = 1,
10236 .input_mux = &alc883_capture_source,
c259249f 10237 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10238 .setup = alc882_targa_setup,
10239 .init_hook = alc882_targa_automute,
ccc656ce
KY
10240 },
10241 [ALC883_TARGA_2ch_DIG] = {
c259249f 10242 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10243 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10244 alc883_targa_verbs},
ccc656ce
KY
10245 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10246 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10247 .adc_nids = alc883_adc_nids_alt,
10248 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10249 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10250 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10251 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10252 .channel_mode = alc883_3ST_2ch_modes,
10253 .input_mux = &alc883_capture_source,
c259249f 10254 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10255 .setup = alc882_targa_setup,
10256 .init_hook = alc882_targa_automute,
ccc656ce 10257 },
64a8be74 10258 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10259 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10260 alc883_chmode_mixer },
64a8be74 10261 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10262 alc883_targa_verbs },
64a8be74
DH
10263 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10264 .dac_nids = alc883_dac_nids,
10265 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10266 .adc_nids = alc883_adc_nids_rev,
10267 .capsrc_nids = alc883_capsrc_nids_rev,
10268 .dig_out_nid = ALC883_DIGOUT_NID,
10269 .dig_in_nid = ALC883_DIGIN_NID,
10270 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10271 .channel_mode = alc883_4ST_8ch_modes,
10272 .need_dac_fix = 1,
10273 .input_mux = &alc883_capture_source,
c259249f 10274 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10275 .setup = alc882_targa_setup,
10276 .init_hook = alc882_targa_automute,
64a8be74 10277 },
bab282b9 10278 [ALC883_ACER] = {
676a9b53 10279 .mixers = { alc883_base_mixer },
bab282b9
VA
10280 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10281 * and the headphone jack. Turn this on and rely on the
10282 * standard mute methods whenever the user wants to turn
10283 * these outputs off.
10284 */
10285 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10286 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10287 .dac_nids = alc883_dac_nids,
bab282b9
VA
10288 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10289 .channel_mode = alc883_3ST_2ch_modes,
10290 .input_mux = &alc883_capture_source,
10291 },
2880a867 10292 [ALC883_ACER_ASPIRE] = {
676a9b53 10293 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10294 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10295 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10296 .dac_nids = alc883_dac_nids,
10297 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10298 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10299 .channel_mode = alc883_3ST_2ch_modes,
10300 .input_mux = &alc883_capture_source,
a9fd4f3f 10301 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10302 .setup = alc883_acer_aspire_setup,
10303 .init_hook = alc_automute_amp,
d1a991a6 10304 },
5b2d1eca 10305 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 10306 .mixers = { alc888_base_mixer,
5b2d1eca
VP
10307 alc883_chmode_mixer },
10308 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10309 alc888_acer_aspire_4930g_verbs },
10310 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10311 .dac_nids = alc883_dac_nids,
10312 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10313 .adc_nids = alc883_adc_nids_rev,
10314 .capsrc_nids = alc883_capsrc_nids_rev,
10315 .dig_out_nid = ALC883_DIGOUT_NID,
10316 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10317 .channel_mode = alc883_3ST_6ch_modes,
10318 .need_dac_fix = 1,
973b8cb0 10319 .const_channel_count = 6,
5b2d1eca 10320 .num_mux_defs =
ef8ef5fb
VP
10321 ARRAY_SIZE(alc888_2_capture_sources),
10322 .input_mux = alc888_2_capture_sources,
d2fd4b09 10323 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10324 .setup = alc888_acer_aspire_4930g_setup,
10325 .init_hook = alc_automute_amp,
d2fd4b09
TV
10326 },
10327 [ALC888_ACER_ASPIRE_6530G] = {
10328 .mixers = { alc888_acer_aspire_6530_mixer },
10329 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10330 alc888_acer_aspire_6530g_verbs },
10331 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10332 .dac_nids = alc883_dac_nids,
10333 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10334 .adc_nids = alc883_adc_nids_rev,
10335 .capsrc_nids = alc883_capsrc_nids_rev,
10336 .dig_out_nid = ALC883_DIGOUT_NID,
10337 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10338 .channel_mode = alc883_3ST_2ch_modes,
10339 .num_mux_defs =
10340 ARRAY_SIZE(alc888_2_capture_sources),
10341 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 10342 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10343 .setup = alc888_acer_aspire_6530g_setup,
10344 .init_hook = alc_automute_amp,
5b2d1eca 10345 },
3b315d70 10346 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10347 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10348 alc883_chmode_mixer },
10349 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10350 alc889_acer_aspire_8930g_verbs,
10351 alc889_eapd_verbs},
3b315d70
HM
10352 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10353 .dac_nids = alc883_dac_nids,
018df418
HM
10354 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10355 .adc_nids = alc889_adc_nids,
10356 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10357 .dig_out_nid = ALC883_DIGOUT_NID,
10358 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10359 .channel_mode = alc883_3ST_6ch_modes,
10360 .need_dac_fix = 1,
10361 .const_channel_count = 6,
10362 .num_mux_defs =
018df418
HM
10363 ARRAY_SIZE(alc889_capture_sources),
10364 .input_mux = alc889_capture_sources,
3b315d70 10365 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10366 .setup = alc889_acer_aspire_8930g_setup,
10367 .init_hook = alc_automute_amp,
f5de24b0 10368#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10369 .power_hook = alc_power_eapd,
f5de24b0 10370#endif
3b315d70 10371 },
fc86f954
DK
10372 [ALC888_ACER_ASPIRE_7730G] = {
10373 .mixers = { alc883_3ST_6ch_mixer,
10374 alc883_chmode_mixer },
10375 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10376 alc888_acer_aspire_7730G_verbs },
10377 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10378 .dac_nids = alc883_dac_nids,
10379 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10380 .adc_nids = alc883_adc_nids_rev,
10381 .capsrc_nids = alc883_capsrc_nids_rev,
10382 .dig_out_nid = ALC883_DIGOUT_NID,
10383 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10384 .channel_mode = alc883_3ST_6ch_modes,
10385 .need_dac_fix = 1,
10386 .const_channel_count = 6,
10387 .input_mux = &alc883_capture_source,
10388 .unsol_event = alc_automute_amp_unsol_event,
d9477207 10389 .setup = alc888_acer_aspire_7730g_setup,
fc86f954
DK
10390 .init_hook = alc_automute_amp,
10391 },
c07584c8
TD
10392 [ALC883_MEDION] = {
10393 .mixers = { alc883_fivestack_mixer,
10394 alc883_chmode_mixer },
10395 .init_verbs = { alc883_init_verbs,
b373bdeb 10396 alc883_medion_eapd_verbs },
c07584c8
TD
10397 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10398 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10399 .adc_nids = alc883_adc_nids_alt,
10400 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10401 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10402 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10403 .channel_mode = alc883_sixstack_modes,
10404 .input_mux = &alc883_capture_source,
b373bdeb 10405 },
7ad7b218
MC
10406 [ALC883_MEDION_WIM2160] = {
10407 .mixers = { alc883_medion_wim2160_mixer },
10408 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10409 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10410 .dac_nids = alc883_dac_nids,
10411 .dig_out_nid = ALC883_DIGOUT_NID,
10412 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10413 .adc_nids = alc883_adc_nids,
10414 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10415 .channel_mode = alc883_3ST_2ch_modes,
10416 .input_mux = &alc883_capture_source,
10417 .unsol_event = alc_automute_amp_unsol_event,
10418 .setup = alc883_medion_wim2160_setup,
10419 .init_hook = alc_automute_amp,
10420 },
b373bdeb 10421 [ALC883_LAPTOP_EAPD] = {
676a9b53 10422 .mixers = { alc883_base_mixer },
b373bdeb
AN
10423 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10424 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10425 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10426 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10427 .channel_mode = alc883_3ST_2ch_modes,
10428 .input_mux = &alc883_capture_source,
10429 },
a65cc60f 10430 [ALC883_CLEVO_M540R] = {
10431 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10432 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10433 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10434 .dac_nids = alc883_dac_nids,
10435 .dig_out_nid = ALC883_DIGOUT_NID,
10436 .dig_in_nid = ALC883_DIGIN_NID,
10437 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10438 .channel_mode = alc883_3ST_6ch_clevo_modes,
10439 .need_dac_fix = 1,
10440 .input_mux = &alc883_capture_source,
10441 /* This machine has the hardware HP auto-muting, thus
10442 * we need no software mute via unsol event
10443 */
10444 },
0c4cc443
HRK
10445 [ALC883_CLEVO_M720] = {
10446 .mixers = { alc883_clevo_m720_mixer },
10447 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10448 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10449 .dac_nids = alc883_dac_nids,
10450 .dig_out_nid = ALC883_DIGOUT_NID,
10451 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10452 .channel_mode = alc883_3ST_2ch_modes,
10453 .input_mux = &alc883_capture_source,
0c4cc443 10454 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10455 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10456 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10457 },
bc9f98a9
KY
10458 [ALC883_LENOVO_101E_2ch] = {
10459 .mixers = { alc883_lenovo_101e_2ch_mixer},
10460 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10461 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10462 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10463 .adc_nids = alc883_adc_nids_alt,
10464 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10465 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10466 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10467 .channel_mode = alc883_3ST_2ch_modes,
10468 .input_mux = &alc883_lenovo_101e_capture_source,
10469 .unsol_event = alc883_lenovo_101e_unsol_event,
10470 .init_hook = alc883_lenovo_101e_all_automute,
10471 },
272a527c
KY
10472 [ALC883_LENOVO_NB0763] = {
10473 .mixers = { alc883_lenovo_nb0763_mixer },
10474 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10475 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10476 .dac_nids = alc883_dac_nids,
272a527c
KY
10477 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10478 .channel_mode = alc883_3ST_2ch_modes,
10479 .need_dac_fix = 1,
10480 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 10481 .unsol_event = alc_automute_amp_unsol_event,
dc427170 10482 .setup = alc883_lenovo_nb0763_setup,
4f5d1706 10483 .init_hook = alc_automute_amp,
272a527c
KY
10484 },
10485 [ALC888_LENOVO_MS7195_DIG] = {
10486 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10487 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10488 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10489 .dac_nids = alc883_dac_nids,
10490 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10491 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10492 .channel_mode = alc883_3ST_6ch_modes,
10493 .need_dac_fix = 1,
10494 .input_mux = &alc883_capture_source,
10495 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10496 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
10497 },
10498 [ALC883_HAIER_W66] = {
c259249f 10499 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10500 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10501 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10502 .dac_nids = alc883_dac_nids,
10503 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10504 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10505 .channel_mode = alc883_3ST_2ch_modes,
10506 .input_mux = &alc883_capture_source,
a9fd4f3f 10507 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10508 .setup = alc883_haier_w66_setup,
10509 .init_hook = alc_automute_amp,
eea6419e 10510 },
4723c022 10511 [ALC888_3ST_HP] = {
eea6419e 10512 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10513 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10514 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10515 .dac_nids = alc883_dac_nids,
4723c022
CM
10516 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10517 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10518 .need_dac_fix = 1,
10519 .input_mux = &alc883_capture_source,
a9fd4f3f 10520 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10521 .setup = alc888_3st_hp_setup,
10522 .init_hook = alc_automute_amp,
8341de60 10523 },
5795b9e6 10524 [ALC888_6ST_DELL] = {
f24dbdc6 10525 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10526 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10527 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10528 .dac_nids = alc883_dac_nids,
10529 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10530 .dig_in_nid = ALC883_DIGIN_NID,
10531 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10532 .channel_mode = alc883_sixstack_modes,
10533 .input_mux = &alc883_capture_source,
a9fd4f3f 10534 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10535 .setup = alc888_6st_dell_setup,
10536 .init_hook = alc_automute_amp,
5795b9e6 10537 },
a8848bd6
AS
10538 [ALC883_MITAC] = {
10539 .mixers = { alc883_mitac_mixer },
10540 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10541 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10542 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10543 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10544 .channel_mode = alc883_3ST_2ch_modes,
10545 .input_mux = &alc883_capture_source,
a9fd4f3f 10546 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10547 .setup = alc883_mitac_setup,
10548 .init_hook = alc_automute_amp,
a8848bd6 10549 },
fb97dc67
J
10550 [ALC883_FUJITSU_PI2515] = {
10551 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10552 .init_verbs = { alc883_init_verbs,
10553 alc883_2ch_fujitsu_pi2515_verbs},
10554 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10555 .dac_nids = alc883_dac_nids,
10556 .dig_out_nid = ALC883_DIGOUT_NID,
10557 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10558 .channel_mode = alc883_3ST_2ch_modes,
10559 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10560 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10561 .setup = alc883_2ch_fujitsu_pi2515_setup,
10562 .init_hook = alc_automute_amp,
fb97dc67 10563 },
ef8ef5fb
VP
10564 [ALC888_FUJITSU_XA3530] = {
10565 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10566 .init_verbs = { alc883_init_verbs,
10567 alc888_fujitsu_xa3530_verbs },
10568 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10569 .dac_nids = alc883_dac_nids,
10570 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10571 .adc_nids = alc883_adc_nids_rev,
10572 .capsrc_nids = alc883_capsrc_nids_rev,
10573 .dig_out_nid = ALC883_DIGOUT_NID,
10574 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10575 .channel_mode = alc888_4ST_8ch_intel_modes,
10576 .num_mux_defs =
10577 ARRAY_SIZE(alc888_2_capture_sources),
10578 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10579 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10580 .setup = alc888_fujitsu_xa3530_setup,
10581 .init_hook = alc_automute_amp,
ef8ef5fb 10582 },
e2757d5e
KY
10583 [ALC888_LENOVO_SKY] = {
10584 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10585 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10586 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10587 .dac_nids = alc883_dac_nids,
10588 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10589 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10590 .channel_mode = alc883_sixstack_modes,
10591 .need_dac_fix = 1,
10592 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10593 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10594 .setup = alc888_lenovo_sky_setup,
10595 .init_hook = alc_automute_amp,
e2757d5e
KY
10596 },
10597 [ALC888_ASUS_M90V] = {
10598 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10599 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10600 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10601 .dac_nids = alc883_dac_nids,
10602 .dig_out_nid = ALC883_DIGOUT_NID,
10603 .dig_in_nid = ALC883_DIGIN_NID,
10604 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10605 .channel_mode = alc883_3ST_6ch_modes,
10606 .need_dac_fix = 1,
10607 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10608 .unsol_event = alc_sku_unsol_event,
10609 .setup = alc883_mode2_setup,
10610 .init_hook = alc_inithook,
e2757d5e
KY
10611 },
10612 [ALC888_ASUS_EEE1601] = {
10613 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10614 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10615 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10616 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10617 .dac_nids = alc883_dac_nids,
10618 .dig_out_nid = ALC883_DIGOUT_NID,
10619 .dig_in_nid = ALC883_DIGIN_NID,
10620 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10621 .channel_mode = alc883_3ST_2ch_modes,
10622 .need_dac_fix = 1,
10623 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10624 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10625 .init_hook = alc883_eee1601_inithook,
10626 },
3ab90935
WF
10627 [ALC1200_ASUS_P5Q] = {
10628 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10629 .init_verbs = { alc883_init_verbs },
10630 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10631 .dac_nids = alc883_dac_nids,
10632 .dig_out_nid = ALC1200_DIGOUT_NID,
10633 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10634 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10635 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10636 .channel_mode = alc883_sixstack_modes,
10637 .input_mux = &alc883_capture_source,
10638 },
eb4c41d3
TS
10639 [ALC889A_MB31] = {
10640 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10641 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10642 alc880_gpio1_init_verbs },
10643 .adc_nids = alc883_adc_nids,
10644 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10645 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10646 .dac_nids = alc883_dac_nids,
10647 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10648 .channel_mode = alc889A_mb31_6ch_modes,
10649 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10650 .input_mux = &alc889A_mb31_capture_source,
10651 .dig_out_nid = ALC883_DIGOUT_NID,
10652 .unsol_event = alc889A_mb31_unsol_event,
10653 .init_hook = alc889A_mb31_automute,
10654 },
3e1647c5
GG
10655 [ALC883_SONY_VAIO_TT] = {
10656 .mixers = { alc883_vaiott_mixer },
10657 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10658 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10659 .dac_nids = alc883_dac_nids,
10660 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10661 .channel_mode = alc883_3ST_2ch_modes,
10662 .input_mux = &alc883_capture_source,
10663 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10664 .setup = alc883_vaiott_setup,
10665 .init_hook = alc_automute_amp,
3e1647c5 10666 },
9c7f852e
TI
10667};
10668
10669
4953550a
TI
10670/*
10671 * Pin config fixes
10672 */
10673enum {
954a29c8
TI
10674 PINFIX_ABIT_AW9D_MAX,
10675 PINFIX_PB_M5210,
c3d226ab 10676 PINFIX_ACER_ASPIRE_7736,
4953550a
TI
10677};
10678
f8f25ba3
TI
10679static const struct alc_fixup alc882_fixups[] = {
10680 [PINFIX_ABIT_AW9D_MAX] = {
73413b12
TI
10681 .pins = (const struct alc_pincfg[]) {
10682 { 0x15, 0x01080104 }, /* side */
10683 { 0x16, 0x01011012 }, /* rear */
10684 { 0x17, 0x01016011 }, /* clfe */
10685 { }
10686 }
f8f25ba3 10687 },
954a29c8 10688 [PINFIX_PB_M5210] = {
73413b12
TI
10689 .verbs = (const struct hda_verb[]) {
10690 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10691 {}
10692 }
954a29c8 10693 },
c3d226ab
DH
10694 [PINFIX_ACER_ASPIRE_7736] = {
10695 .sku = ALC_FIXUP_SKU_IGNORE,
10696 },
4953550a
TI
10697};
10698
f8f25ba3 10699static struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10700 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
4953550a 10701 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
c3d226ab 10702 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
4953550a
TI
10703 {}
10704};
10705
9c7f852e
TI
10706/*
10707 * BIOS auto configuration
10708 */
05f5f477
TI
10709static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10710 const struct auto_pin_cfg *cfg)
10711{
10712 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10713}
10714
4953550a 10715static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10716 hda_nid_t nid, int pin_type,
489008cd 10717 hda_nid_t dac)
9c7f852e 10718{
f12ab1e0
TI
10719 int idx;
10720
489008cd 10721 /* set as output */
f6c7e546 10722 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10723
10724 if (dac == 0x25)
9c7f852e 10725 idx = 4;
489008cd
TI
10726 else if (dac >= 0x02 && dac <= 0x05)
10727 idx = dac - 2;
f9700d5a 10728 else
489008cd 10729 return;
9c7f852e 10730 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
10731}
10732
4953550a 10733static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10734{
10735 struct alc_spec *spec = codec->spec;
10736 int i;
10737
10738 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10739 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10740 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10741 if (nid)
4953550a 10742 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 10743 spec->multiout.dac_nids[i]);
9c7f852e
TI
10744 }
10745}
10746
4953550a 10747static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10748{
10749 struct alc_spec *spec = codec->spec;
489008cd 10750 hda_nid_t pin, dac;
5855fb80 10751 int i;
9c7f852e 10752
5855fb80
TI
10753 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
10754 pin = spec->autocfg.hp_pins[i];
10755 if (!pin)
10756 break;
489008cd
TI
10757 dac = spec->multiout.hp_nid;
10758 if (!dac)
10759 dac = spec->multiout.dac_nids[0]; /* to front */
10760 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10761 }
5855fb80
TI
10762 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
10763 pin = spec->autocfg.speaker_pins[i];
10764 if (!pin)
10765 break;
489008cd
TI
10766 dac = spec->multiout.extra_out_nid[0];
10767 if (!dac)
10768 dac = spec->multiout.dac_nids[0]; /* to front */
10769 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10770 }
9c7f852e
TI
10771}
10772
4953550a 10773static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10774{
10775 struct alc_spec *spec = codec->spec;
66ceeb6b 10776 struct auto_pin_cfg *cfg = &spec->autocfg;
9c7f852e
TI
10777 int i;
10778
66ceeb6b
TI
10779 for (i = 0; i < cfg->num_inputs; i++) {
10780 hda_nid_t nid = cfg->inputs[i].pin;
30ea098f 10781 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
4953550a
TI
10782 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10783 snd_hda_codec_write(codec, nid, 0,
10784 AC_VERB_SET_AMP_GAIN_MUTE,
10785 AMP_OUT_MUTE);
10786 }
10787}
10788
10789static void alc882_auto_init_input_src(struct hda_codec *codec)
10790{
10791 struct alc_spec *spec = codec->spec;
10792 int c;
10793
10794 for (c = 0; c < spec->num_adc_nids; c++) {
10795 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10796 hda_nid_t nid = spec->capsrc_nids[c];
10797 unsigned int mux_idx;
10798 const struct hda_input_mux *imux;
10799 int conns, mute, idx, item;
10800
10801 conns = snd_hda_get_connections(codec, nid, conn_list,
10802 ARRAY_SIZE(conn_list));
10803 if (conns < 0)
10804 continue;
10805 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10806 imux = &spec->input_mux[mux_idx];
5311114d
TI
10807 if (!imux->num_items && mux_idx > 0)
10808 imux = &spec->input_mux[0];
4953550a
TI
10809 for (idx = 0; idx < conns; idx++) {
10810 /* if the current connection is the selected one,
10811 * unmute it as default - otherwise mute it
10812 */
10813 mute = AMP_IN_MUTE(idx);
10814 for (item = 0; item < imux->num_items; item++) {
10815 if (imux->items[item].index == idx) {
10816 if (spec->cur_mux[c] == item)
10817 mute = AMP_IN_UNMUTE(idx);
10818 break;
10819 }
10820 }
10821 /* check if we have a selector or mixer
10822 * we could check for the widget type instead, but
10823 * just check for Amp-In presence (in case of mixer
10824 * without amp-in there is something wrong, this
10825 * function shouldn't be used or capsrc nid is wrong)
10826 */
10827 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10828 snd_hda_codec_write(codec, nid, 0,
10829 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10830 mute);
10831 else if (mute != AMP_IN_MUTE(idx))
10832 snd_hda_codec_write(codec, nid, 0,
10833 AC_VERB_SET_CONNECT_SEL,
10834 idx);
9c7f852e
TI
10835 }
10836 }
10837}
10838
4953550a
TI
10839/* add mic boosts if needed */
10840static int alc_auto_add_mic_boost(struct hda_codec *codec)
10841{
10842 struct alc_spec *spec = codec->spec;
66ceeb6b 10843 struct auto_pin_cfg *cfg = &spec->autocfg;
5322bf27 10844 int i, err;
53e8c323 10845 int type_idx = 0;
4953550a 10846 hda_nid_t nid;
5322bf27 10847 const char *prev_label = NULL;
4953550a 10848
66ceeb6b 10849 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 10850 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
10851 break;
10852 nid = cfg->inputs[i].pin;
10853 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
5322bf27
DH
10854 const char *label;
10855 char boost_label[32];
10856
10857 label = hda_get_autocfg_input_label(codec, cfg, i);
10858 if (prev_label && !strcmp(label, prev_label))
53e8c323
TI
10859 type_idx++;
10860 else
10861 type_idx = 0;
5322bf27
DH
10862 prev_label = label;
10863
10864 snprintf(boost_label, sizeof(boost_label),
10865 "%s Boost Volume", label);
10866 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10867 boost_label, type_idx,
4953550a 10868 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
10869 if (err < 0)
10870 return err;
10871 }
4953550a
TI
10872 }
10873 return 0;
10874}
f511b01c 10875
9c7f852e 10876/* almost identical with ALC880 parser... */
4953550a 10877static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10878{
10879 struct alc_spec *spec = codec->spec;
05f5f477 10880 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 10881 int err;
9c7f852e 10882
05f5f477
TI
10883 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10884 alc882_ignore);
9c7f852e
TI
10885 if (err < 0)
10886 return err;
05f5f477
TI
10887 if (!spec->autocfg.line_outs)
10888 return 0; /* can't find valid BIOS pin config */
776e184e 10889
05f5f477
TI
10890 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10891 if (err < 0)
10892 return err;
10893 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
10894 if (err < 0)
10895 return err;
10896 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10897 "Headphone");
05f5f477
TI
10898 if (err < 0)
10899 return err;
10900 err = alc880_auto_create_extra_out(spec,
10901 spec->autocfg.speaker_pins[0],
10902 "Speaker");
10903 if (err < 0)
10904 return err;
05f5f477 10905 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10906 if (err < 0)
10907 return err;
10908
05f5f477
TI
10909 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10910
757899ac 10911 alc_auto_parse_digital(codec);
05f5f477
TI
10912
10913 if (spec->kctls.list)
10914 add_mixer(spec, spec->kctls.list);
10915
10916 add_verb(spec, alc883_auto_init_verbs);
4953550a 10917 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10918 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10919 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10920
05f5f477
TI
10921 spec->num_mux_defs = 1;
10922 spec->input_mux = &spec->private_imux[0];
10923
6227cdce 10924 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10925
10926 err = alc_auto_add_mic_boost(codec);
10927 if (err < 0)
10928 return err;
61b9b9b1 10929
776e184e 10930 return 1; /* config found */
9c7f852e
TI
10931}
10932
10933/* additional initialization for auto-configuration model */
4953550a 10934static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10935{
f6c7e546 10936 struct alc_spec *spec = codec->spec;
4953550a
TI
10937 alc882_auto_init_multi_out(codec);
10938 alc882_auto_init_hp_out(codec);
10939 alc882_auto_init_analog_input(codec);
10940 alc882_auto_init_input_src(codec);
757899ac 10941 alc_auto_init_digital(codec);
f6c7e546 10942 if (spec->unsol_event)
7fb0d78f 10943 alc_inithook(codec);
9c7f852e
TI
10944}
10945
4953550a 10946static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10947{
10948 struct alc_spec *spec;
10949 int err, board_config;
10950
10951 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10952 if (spec == NULL)
10953 return -ENOMEM;
10954
10955 codec->spec = spec;
10956
4953550a
TI
10957 switch (codec->vendor_id) {
10958 case 0x10ec0882:
10959 case 0x10ec0885:
10960 break;
10961 default:
10962 /* ALC883 and variants */
10963 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10964 break;
10965 }
2c3bf9ab 10966
4953550a
TI
10967 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10968 alc882_models,
10969 alc882_cfg_tbl);
10970
10971 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10972 board_config = snd_hda_check_board_codec_sid_config(codec,
10973 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10974
10975 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 10976 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
10977 codec->chip_name);
10978 board_config = ALC882_AUTO;
9c7f852e
TI
10979 }
10980
7fa90e87
TI
10981 if (board_config == ALC882_AUTO)
10982 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
4953550a 10983
90622917
DH
10984 alc_auto_parse_customize_define(codec);
10985
4953550a 10986 if (board_config == ALC882_AUTO) {
9c7f852e 10987 /* automatic parse from the BIOS config */
4953550a 10988 err = alc882_parse_auto_config(codec);
9c7f852e
TI
10989 if (err < 0) {
10990 alc_free(codec);
10991 return err;
f12ab1e0 10992 } else if (!err) {
9c7f852e
TI
10993 printk(KERN_INFO
10994 "hda_codec: Cannot set up configuration "
10995 "from BIOS. Using base mode...\n");
4953550a 10996 board_config = ALC882_3ST_DIG;
9c7f852e
TI
10997 }
10998 }
10999
dc1eae25 11000 if (has_cdefine_beep(codec)) {
8af2591d
TI
11001 err = snd_hda_attach_beep_device(codec, 0x1);
11002 if (err < 0) {
11003 alc_free(codec);
11004 return err;
11005 }
680cd536
KK
11006 }
11007
4953550a 11008 if (board_config != ALC882_AUTO)
e9c364c0 11009 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 11010
4953550a
TI
11011 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11012 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11013 /* FIXME: setup DAC5 */
11014 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11015 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11016
11017 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11018 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11019
4953550a 11020 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 11021 int i, j;
4953550a
TI
11022 spec->num_adc_nids = 0;
11023 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 11024 const struct hda_input_mux *imux = spec->input_mux;
4953550a 11025 hda_nid_t cap;
d11f74c6 11026 hda_nid_t items[16];
4953550a
TI
11027 hda_nid_t nid = alc882_adc_nids[i];
11028 unsigned int wcap = get_wcaps(codec, nid);
11029 /* get type */
a22d543a 11030 wcap = get_wcaps_type(wcap);
4953550a
TI
11031 if (wcap != AC_WID_AUD_IN)
11032 continue;
11033 spec->private_adc_nids[spec->num_adc_nids] = nid;
11034 err = snd_hda_get_connections(codec, nid, &cap, 1);
11035 if (err < 0)
11036 continue;
d11f74c6
TI
11037 err = snd_hda_get_connections(codec, cap, items,
11038 ARRAY_SIZE(items));
11039 if (err < 0)
11040 continue;
11041 for (j = 0; j < imux->num_items; j++)
11042 if (imux->items[j].index >= err)
11043 break;
11044 if (j < imux->num_items)
11045 continue;
4953550a
TI
11046 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11047 spec->num_adc_nids++;
61b9b9b1 11048 }
4953550a
TI
11049 spec->adc_nids = spec->private_adc_nids;
11050 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
11051 }
11052
b59bdf3b 11053 set_capture_mixer(codec);
da00c244 11054
dc1eae25 11055 if (has_cdefine_beep(codec))
da00c244 11056 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 11057
7fa90e87
TI
11058 if (board_config == ALC882_AUTO)
11059 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
11060
2134ea4f
TI
11061 spec->vmaster_nid = 0x0c;
11062
9c7f852e 11063 codec->patch_ops = alc_patch_ops;
4953550a
TI
11064 if (board_config == ALC882_AUTO)
11065 spec->init_hook = alc882_auto_init;
bf1b0225
KY
11066
11067 alc_init_jacks(codec);
cb53c626
TI
11068#ifdef CONFIG_SND_HDA_POWER_SAVE
11069 if (!spec->loopback.amplist)
4953550a 11070 spec->loopback.amplist = alc882_loopbacks;
cb53c626 11071#endif
9c7f852e
TI
11072
11073 return 0;
11074}
11075
4953550a 11076
9c7f852e
TI
11077/*
11078 * ALC262 support
11079 */
11080
11081#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11082#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11083
11084#define alc262_dac_nids alc260_dac_nids
11085#define alc262_adc_nids alc882_adc_nids
11086#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
11087#define alc262_capsrc_nids alc882_capsrc_nids
11088#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
11089
11090#define alc262_modes alc260_modes
11091#define alc262_capture_source alc882_capture_source
11092
4e555fe5
KY
11093static hda_nid_t alc262_dmic_adc_nids[1] = {
11094 /* ADC0 */
11095 0x09
11096};
11097
11098static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11099
9c7f852e
TI
11100static struct snd_kcontrol_new alc262_base_mixer[] = {
11101 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11102 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11103 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11104 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11105 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11106 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11107 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11108 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11109 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11110 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11111 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11112 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11113 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11114 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11115 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11116 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11117 { } /* end */
11118};
11119
ce875f07
TI
11120/* update HP, line and mono-out pins according to the master switch */
11121static void alc262_hp_master_update(struct hda_codec *codec)
11122{
11123 struct alc_spec *spec = codec->spec;
11124 int val = spec->master_sw;
11125
11126 /* HP & line-out */
11127 snd_hda_codec_write_cache(codec, 0x1b, 0,
11128 AC_VERB_SET_PIN_WIDGET_CONTROL,
11129 val ? PIN_HP : 0);
11130 snd_hda_codec_write_cache(codec, 0x15, 0,
11131 AC_VERB_SET_PIN_WIDGET_CONTROL,
11132 val ? PIN_HP : 0);
11133 /* mono (speaker) depending on the HP jack sense */
11134 val = val && !spec->jack_present;
11135 snd_hda_codec_write_cache(codec, 0x16, 0,
11136 AC_VERB_SET_PIN_WIDGET_CONTROL,
11137 val ? PIN_OUT : 0);
11138}
11139
11140static void alc262_hp_bpc_automute(struct hda_codec *codec)
11141{
11142 struct alc_spec *spec = codec->spec;
864f92be
WF
11143
11144 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
11145 alc262_hp_master_update(codec);
11146}
11147
11148static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
11149{
11150 if ((res >> 26) != ALC880_HP_EVENT)
11151 return;
11152 alc262_hp_bpc_automute(codec);
11153}
11154
11155static void alc262_hp_wildwest_automute(struct hda_codec *codec)
11156{
11157 struct alc_spec *spec = codec->spec;
864f92be
WF
11158
11159 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
11160 alc262_hp_master_update(codec);
11161}
11162
11163static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
11164 unsigned int res)
11165{
11166 if ((res >> 26) != ALC880_HP_EVENT)
11167 return;
11168 alc262_hp_wildwest_automute(codec);
11169}
11170
b72519b5 11171#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
11172
11173static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
11174 struct snd_ctl_elem_value *ucontrol)
11175{
11176 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11177 struct alc_spec *spec = codec->spec;
11178 int val = !!*ucontrol->value.integer.value;
11179
11180 if (val == spec->master_sw)
11181 return 0;
11182 spec->master_sw = val;
11183 alc262_hp_master_update(codec);
11184 return 1;
11185}
11186
b72519b5
TI
11187#define ALC262_HP_MASTER_SWITCH \
11188 { \
11189 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11190 .name = "Master Playback Switch", \
11191 .info = snd_ctl_boolean_mono_info, \
11192 .get = alc262_hp_master_sw_get, \
11193 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11194 }, \
11195 { \
11196 .iface = NID_MAPPING, \
11197 .name = "Master Playback Switch", \
11198 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11199 }
11200
5b0cb1d8 11201
9c7f852e 11202static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11203 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11204 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11205 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11206 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11207 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11208 HDA_OUTPUT),
11209 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11210 HDA_OUTPUT),
9c7f852e
TI
11211 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11212 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11213 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11214 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11215 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11216 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11217 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11218 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11219 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11220 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11221 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11222 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11223 { } /* end */
11224};
11225
cd7509a4 11226static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11227 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11228 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11229 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11230 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11231 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11232 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11233 HDA_OUTPUT),
11234 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11235 HDA_OUTPUT),
cd7509a4
KY
11236 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11237 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5f99f86a 11238 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11239 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11240 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11241 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11242 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11243 { } /* end */
11244};
11245
11246static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11247 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11248 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11249 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11250 { } /* end */
11251};
11252
66d2a9d6 11253/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11254static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11255{
11256 struct alc_spec *spec = codec->spec;
66d2a9d6 11257
a9fd4f3f 11258 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11259 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
11260}
11261
66d2a9d6 11262static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11263 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11264 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11265 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11266 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11267 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11268 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11269 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
66d2a9d6
KY
11270 { } /* end */
11271};
11272
11273static struct hda_verb alc262_hp_t5735_verbs[] = {
11274 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11275 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11276
11277 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11278 { }
11279};
11280
8c427226 11281static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11282 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11283 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11284 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11285 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11286 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11287 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11288 { } /* end */
11289};
11290
11291static struct hda_verb alc262_hp_rp5700_verbs[] = {
11292 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11293 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11294 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11295 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11296 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11297 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11298 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11299 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11300 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11301 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11302 {}
11303};
11304
11305static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11306 .num_items = 1,
11307 .items = {
11308 { "Line", 0x1 },
11309 },
11310};
11311
42171c17
TI
11312/* bind hp and internal speaker mute (with plug check) as master switch */
11313static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 11314{
42171c17
TI
11315 struct alc_spec *spec = codec->spec;
11316 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11317 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11318 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11319 unsigned int mute;
0724ea2a 11320
42171c17
TI
11321 /* HP */
11322 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11323 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11324 HDA_AMP_MUTE, mute);
11325 /* mute internal speaker per jack sense */
11326 if (spec->jack_present)
11327 mute = HDA_AMP_MUTE;
11328 if (line_nid)
11329 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11330 HDA_AMP_MUTE, mute);
11331 if (speaker_nid && speaker_nid != line_nid)
11332 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 11333 HDA_AMP_MUTE, mute);
42171c17
TI
11334}
11335
11336#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11337
11338static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11339 struct snd_ctl_elem_value *ucontrol)
11340{
11341 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11342 struct alc_spec *spec = codec->spec;
11343 int val = !!*ucontrol->value.integer.value;
11344
11345 if (val == spec->master_sw)
11346 return 0;
11347 spec->master_sw = val;
11348 alc262_hippo_master_update(codec);
11349 return 1;
11350}
11351
11352#define ALC262_HIPPO_MASTER_SWITCH \
11353 { \
11354 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11355 .name = "Master Playback Switch", \
11356 .info = snd_ctl_boolean_mono_info, \
11357 .get = alc262_hippo_master_sw_get, \
11358 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11359 }, \
11360 { \
11361 .iface = NID_MAPPING, \
11362 .name = "Master Playback Switch", \
11363 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11364 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11365 }
42171c17
TI
11366
11367static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11368 ALC262_HIPPO_MASTER_SWITCH,
11369 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11370 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11371 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11372 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11373 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11374 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11375 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11376 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11377 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11378 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11379 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11380 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11381 { } /* end */
11382};
11383
11384static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11385 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11386 ALC262_HIPPO_MASTER_SWITCH,
11387 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11388 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11389 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11390 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11391 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11392 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11393 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11394 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11395 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11396 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11397 { } /* end */
11398};
11399
11400/* mute/unmute internal speaker according to the hp jack and mute state */
11401static void alc262_hippo_automute(struct hda_codec *codec)
11402{
11403 struct alc_spec *spec = codec->spec;
11404 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 11405
864f92be 11406 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 11407 alc262_hippo_master_update(codec);
0724ea2a 11408}
5b31954e 11409
42171c17
TI
11410static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11411{
11412 if ((res >> 26) != ALC880_HP_EVENT)
11413 return;
11414 alc262_hippo_automute(codec);
11415}
11416
4f5d1706 11417static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11418{
11419 struct alc_spec *spec = codec->spec;
11420
11421 spec->autocfg.hp_pins[0] = 0x15;
11422 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11423}
11424
4f5d1706 11425static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11426{
11427 struct alc_spec *spec = codec->spec;
11428
11429 spec->autocfg.hp_pins[0] = 0x1b;
11430 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11431}
11432
11433
272a527c 11434static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11435 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11436 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11437 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11438 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11439 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11440 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11441 { } /* end */
11442};
11443
83c34218 11444static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11445 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11446 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11447 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11448 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11449 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11450 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11451 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11452 { } /* end */
11453};
272a527c 11454
ba340e82
TV
11455static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11456 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11457 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11458 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11459 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11460 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11461 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11462 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11463 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11464 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ba340e82
TV
11465 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11466 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11467 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
ba340e82
TV
11468 { } /* end */
11469};
11470
11471static struct hda_verb alc262_tyan_verbs[] = {
11472 /* Headphone automute */
11473 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11474 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11475 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11476
11477 /* P11 AUX_IN, white 4-pin connector */
11478 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11479 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11480 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11481 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11482
11483 {}
11484};
11485
11486/* unsolicited event for HP jack sensing */
4f5d1706 11487static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11488{
a9fd4f3f 11489 struct alc_spec *spec = codec->spec;
ba340e82 11490
a9fd4f3f
TI
11491 spec->autocfg.hp_pins[0] = 0x1b;
11492 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
11493}
11494
ba340e82 11495
9c7f852e
TI
11496#define alc262_capture_mixer alc882_capture_mixer
11497#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11498
11499/*
11500 * generic initialization of ADC, input mixers and output mixers
11501 */
11502static struct hda_verb alc262_init_verbs[] = {
11503 /*
11504 * Unmute ADC0-2 and set the default input to mic-in
11505 */
11506 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11507 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11508 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11509 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11510 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11511 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11512
cb53c626 11513 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11514 * mixer widget
f12ab1e0
TI
11515 * Note: PASD motherboards uses the Line In 2 as the input for
11516 * front panel mic (mic 2)
9c7f852e
TI
11517 */
11518 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11519 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11520 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11521 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11522 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11523 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11524
11525 /*
df694daa
KY
11526 * Set up output mixers (0x0c - 0x0e)
11527 */
11528 /* set vol=0 to output mixers */
11529 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11530 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11531 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11532 /* set up input amps for analog loopback */
11533 /* Amp Indices: DAC = 0, mixer = 1 */
11534 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11535 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11536 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11537 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11538 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11539 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11540
11541 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11542 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11543 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11544 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11545 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11546 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11547
11548 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11549 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11550 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11551 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11552 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11553
df694daa
KY
11554 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11555 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11556
df694daa
KY
11557 /* FIXME: use matrix-type input source selection */
11558 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11559 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11560 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11561 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11562 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11563 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11564 /* Input mixer2 */
11565 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11566 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11567 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11568 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11569 /* Input mixer3 */
11570 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11571 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11572 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11573 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11574
11575 { }
11576};
1da177e4 11577
4e555fe5
KY
11578static struct hda_verb alc262_eapd_verbs[] = {
11579 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11580 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11581 { }
11582};
11583
ccc656ce
KY
11584static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11585 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11586 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11587 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11588
11589 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11590 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11591 {}
11592};
11593
272a527c
KY
11594static struct hda_verb alc262_sony_unsol_verbs[] = {
11595 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11596 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11597 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11598
11599 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11600 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11601 {}
272a527c
KY
11602};
11603
4e555fe5
KY
11604static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11605 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11606 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11607 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11608 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11609 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11610 { } /* end */
11611};
11612
11613static struct hda_verb alc262_toshiba_s06_verbs[] = {
11614 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11615 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11616 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11617 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11618 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11619 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11620 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11621 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11622 {}
11623};
11624
4f5d1706 11625static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11626{
a9fd4f3f
TI
11627 struct alc_spec *spec = codec->spec;
11628
11629 spec->autocfg.hp_pins[0] = 0x15;
11630 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11631 spec->ext_mic.pin = 0x18;
11632 spec->ext_mic.mux_idx = 0;
11633 spec->int_mic.pin = 0x12;
11634 spec->int_mic.mux_idx = 9;
11635 spec->auto_mic = 1;
4e555fe5
KY
11636}
11637
e8f9ae2a
PT
11638/*
11639 * nec model
11640 * 0x15 = headphone
11641 * 0x16 = internal speaker
11642 * 0x18 = external mic
11643 */
11644
11645static struct snd_kcontrol_new alc262_nec_mixer[] = {
11646 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11647 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11648
11649 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11650 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11651 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e8f9ae2a
PT
11652
11653 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11654 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11655 { } /* end */
11656};
11657
11658static struct hda_verb alc262_nec_verbs[] = {
11659 /* Unmute Speaker */
11660 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11661
11662 /* Headphone */
11663 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11664 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11665
11666 /* External mic to headphone */
11667 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11668 /* External mic to speaker */
11669 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11670 {}
11671};
11672
834be88d
TI
11673/*
11674 * fujitsu model
5d9fab2d
TV
11675 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11676 * 0x1b = port replicator headphone out
834be88d
TI
11677 */
11678
11679#define ALC_HP_EVENT 0x37
11680
11681static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11682 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11683 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11684 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11685 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11686 {}
11687};
11688
0e31daf7
J
11689static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11690 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11691 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11692 {}
11693};
11694
e2595322
DC
11695static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11696 /* Front Mic pin: input vref at 50% */
11697 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11698 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11699 {}
11700};
11701
834be88d 11702static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11703 .num_items = 3,
834be88d
TI
11704 .items = {
11705 { "Mic", 0x0 },
28c4edb7 11706 { "Internal Mic", 0x1 },
834be88d
TI
11707 { "CD", 0x4 },
11708 },
11709};
11710
9c7f852e
TI
11711static struct hda_input_mux alc262_HP_capture_source = {
11712 .num_items = 5,
11713 .items = {
11714 { "Mic", 0x0 },
accbe498 11715 { "Front Mic", 0x1 },
9c7f852e
TI
11716 { "Line", 0x2 },
11717 { "CD", 0x4 },
11718 { "AUX IN", 0x6 },
11719 },
11720};
11721
accbe498 11722static struct hda_input_mux alc262_HP_D7000_capture_source = {
11723 .num_items = 4,
11724 .items = {
11725 { "Mic", 0x0 },
11726 { "Front Mic", 0x2 },
11727 { "Line", 0x1 },
11728 { "CD", 0x4 },
11729 },
11730};
11731
ebc7a406 11732/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11733static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11734{
11735 struct alc_spec *spec = codec->spec;
11736 unsigned int mute;
11737
f12ab1e0 11738 if (force || !spec->sense_updated) {
864f92be
WF
11739 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11740 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11741 spec->sense_updated = 1;
11742 }
ebc7a406
TI
11743 /* unmute internal speaker only if both HPs are unplugged and
11744 * master switch is on
11745 */
11746 if (spec->jack_present)
11747 mute = HDA_AMP_MUTE;
11748 else
834be88d 11749 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11750 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11751 HDA_AMP_MUTE, mute);
834be88d
TI
11752}
11753
11754/* unsolicited event for HP jack sensing */
11755static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11756 unsigned int res)
11757{
11758 if ((res >> 26) != ALC_HP_EVENT)
11759 return;
11760 alc262_fujitsu_automute(codec, 1);
11761}
11762
ebc7a406
TI
11763static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11764{
11765 alc262_fujitsu_automute(codec, 1);
11766}
11767
834be88d 11768/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11769static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11770 .ops = &snd_hda_bind_vol,
11771 .values = {
11772 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11773 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11774 0
11775 },
11776};
834be88d 11777
0e31daf7
J
11778/* mute/unmute internal speaker according to the hp jack and mute state */
11779static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11780{
11781 struct alc_spec *spec = codec->spec;
11782 unsigned int mute;
11783
11784 if (force || !spec->sense_updated) {
864f92be 11785 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11786 spec->sense_updated = 1;
11787 }
11788 if (spec->jack_present) {
11789 /* mute internal speaker */
11790 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11791 HDA_AMP_MUTE, HDA_AMP_MUTE);
11792 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11793 HDA_AMP_MUTE, HDA_AMP_MUTE);
11794 } else {
11795 /* unmute internal speaker if necessary */
11796 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11797 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11798 HDA_AMP_MUTE, mute);
11799 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11800 HDA_AMP_MUTE, mute);
11801 }
11802}
11803
11804/* unsolicited event for HP jack sensing */
11805static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11806 unsigned int res)
11807{
11808 if ((res >> 26) != ALC_HP_EVENT)
11809 return;
11810 alc262_lenovo_3000_automute(codec, 1);
11811}
11812
8de56b7d
TI
11813static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11814 int dir, int idx, long *valp)
11815{
11816 int i, change = 0;
11817
11818 for (i = 0; i < 2; i++, valp++)
11819 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11820 HDA_AMP_MUTE,
11821 *valp ? 0 : HDA_AMP_MUTE);
11822 return change;
11823}
11824
834be88d
TI
11825/* bind hp and internal speaker mute (with plug check) */
11826static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11827 struct snd_ctl_elem_value *ucontrol)
11828{
11829 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11830 long *valp = ucontrol->value.integer.value;
11831 int change;
11832
8de56b7d
TI
11833 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11834 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11835 if (change)
11836 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11837 return change;
11838}
11839
11840static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11841 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11842 {
11843 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11844 .name = "Master Playback Switch",
5e26dfd0 11845 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11846 .info = snd_hda_mixer_amp_switch_info,
11847 .get = snd_hda_mixer_amp_switch_get,
11848 .put = alc262_fujitsu_master_sw_put,
11849 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11850 },
5b0cb1d8
JK
11851 {
11852 .iface = NID_MAPPING,
11853 .name = "Master Playback Switch",
11854 .private_value = 0x1b,
11855 },
834be88d
TI
11856 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11857 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11858 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
834be88d
TI
11859 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11860 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11861 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11862 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11863 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11864 { } /* end */
11865};
11866
0e31daf7
J
11867/* bind hp and internal speaker mute (with plug check) */
11868static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11869 struct snd_ctl_elem_value *ucontrol)
11870{
11871 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11872 long *valp = ucontrol->value.integer.value;
11873 int change;
11874
8de56b7d 11875 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11876 if (change)
11877 alc262_lenovo_3000_automute(codec, 0);
11878 return change;
11879}
11880
11881static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11882 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11883 {
11884 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11885 .name = "Master Playback Switch",
5e26dfd0 11886 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11887 .info = snd_hda_mixer_amp_switch_info,
11888 .get = snd_hda_mixer_amp_switch_get,
11889 .put = alc262_lenovo_3000_master_sw_put,
11890 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11891 },
11892 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11893 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11894 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
0e31daf7
J
11895 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11896 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11897 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11898 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11899 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
0e31daf7
J
11900 { } /* end */
11901};
11902
9f99a638
HM
11903static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11904 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11905 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11906 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11907 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11908 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9f99a638
HM
11909 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11910 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11911 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9f99a638
HM
11912 { } /* end */
11913};
11914
304dcaac
TI
11915/* additional init verbs for Benq laptops */
11916static struct hda_verb alc262_EAPD_verbs[] = {
11917 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11918 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11919 {}
11920};
11921
83c34218
KY
11922static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11923 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11924 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11925
11926 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11927 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11928 {}
11929};
11930
f651b50b
TD
11931/* Samsung Q1 Ultra Vista model setup */
11932static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11933 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11934 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11935 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11936 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
11937 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11938 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
f651b50b
TD
11939 { } /* end */
11940};
11941
11942static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11943 /* output mixer */
11944 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11945 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11946 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11947 /* speaker */
11948 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11949 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11950 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11951 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11952 /* HP */
f651b50b 11953 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11954 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11955 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11956 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11957 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11958 /* internal mic */
11959 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11960 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11961 /* ADC, choose mic */
11962 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11963 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11964 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11965 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11966 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11967 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11968 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11969 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11970 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11971 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
11972 {}
11973};
11974
f651b50b
TD
11975/* mute/unmute internal speaker according to the hp jack and mute state */
11976static void alc262_ultra_automute(struct hda_codec *codec)
11977{
11978 struct alc_spec *spec = codec->spec;
11979 unsigned int mute;
f651b50b 11980
bb9f76cd
TI
11981 mute = 0;
11982 /* auto-mute only when HP is used as HP */
11983 if (!spec->cur_mux[0]) {
864f92be 11984 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
11985 if (spec->jack_present)
11986 mute = HDA_AMP_MUTE;
f651b50b 11987 }
bb9f76cd
TI
11988 /* mute/unmute internal speaker */
11989 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11990 HDA_AMP_MUTE, mute);
11991 /* mute/unmute HP */
11992 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11993 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
11994}
11995
11996/* unsolicited event for HP jack sensing */
11997static void alc262_ultra_unsol_event(struct hda_codec *codec,
11998 unsigned int res)
11999{
12000 if ((res >> 26) != ALC880_HP_EVENT)
12001 return;
12002 alc262_ultra_automute(codec);
12003}
12004
bb9f76cd
TI
12005static struct hda_input_mux alc262_ultra_capture_source = {
12006 .num_items = 2,
12007 .items = {
12008 { "Mic", 0x1 },
12009 { "Headphone", 0x7 },
12010 },
12011};
12012
12013static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12014 struct snd_ctl_elem_value *ucontrol)
12015{
12016 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12017 struct alc_spec *spec = codec->spec;
12018 int ret;
12019
54cbc9ab 12020 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
12021 if (!ret)
12022 return 0;
12023 /* reprogram the HP pin as mic or HP according to the input source */
12024 snd_hda_codec_write_cache(codec, 0x15, 0,
12025 AC_VERB_SET_PIN_WIDGET_CONTROL,
12026 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12027 alc262_ultra_automute(codec); /* mute/unmute HP */
12028 return ret;
12029}
12030
12031static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12032 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12033 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12034 {
12035 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12036 .name = "Capture Source",
54cbc9ab
TI
12037 .info = alc_mux_enum_info,
12038 .get = alc_mux_enum_get,
bb9f76cd
TI
12039 .put = alc262_ultra_mux_enum_put,
12040 },
5b0cb1d8
JK
12041 {
12042 .iface = NID_MAPPING,
12043 .name = "Capture Source",
12044 .private_value = 0x15,
12045 },
bb9f76cd
TI
12046 { } /* end */
12047};
12048
c3fc1f50
TI
12049/* We use two mixers depending on the output pin; 0x16 is a mono output
12050 * and thus it's bound with a different mixer.
12051 * This function returns which mixer amp should be used.
12052 */
12053static int alc262_check_volbit(hda_nid_t nid)
12054{
12055 if (!nid)
12056 return 0;
12057 else if (nid == 0x16)
12058 return 2;
12059 else
12060 return 1;
12061}
12062
12063static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12064 const char *pfx, int *vbits, int idx)
c3fc1f50 12065{
c3fc1f50
TI
12066 unsigned long val;
12067 int vbit;
12068
12069 vbit = alc262_check_volbit(nid);
12070 if (!vbit)
12071 return 0;
12072 if (*vbits & vbit) /* a volume control for this mixer already there */
12073 return 0;
12074 *vbits |= vbit;
c3fc1f50
TI
12075 if (vbit == 2)
12076 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12077 else
12078 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 12079 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
12080}
12081
12082static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12083 const char *pfx, int idx)
c3fc1f50 12084{
c3fc1f50
TI
12085 unsigned long val;
12086
12087 if (!nid)
12088 return 0;
c3fc1f50
TI
12089 if (nid == 0x16)
12090 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12091 else
12092 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 12093 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
12094}
12095
df694daa 12096/* add playback controls from the parsed DAC table */
f12ab1e0
TI
12097static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12098 const struct auto_pin_cfg *cfg)
df694daa 12099{
c3fc1f50
TI
12100 const char *pfx;
12101 int vbits;
033688a5 12102 int i, err;
df694daa
KY
12103
12104 spec->multiout.num_dacs = 1; /* only use one dac */
12105 spec->multiout.dac_nids = spec->private_dac_nids;
12106 spec->multiout.dac_nids[0] = 2;
12107
bcb2f0f5
TI
12108 pfx = alc_get_line_out_pfx(cfg, true);
12109 if (!pfx)
c3fc1f50 12110 pfx = "Front";
033688a5
TI
12111 for (i = 0; i < 2; i++) {
12112 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12113 if (err < 0)
12114 return err;
12115 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12116 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12117 "Speaker", i);
12118 if (err < 0)
12119 return err;
12120 }
12121 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12122 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12123 "Headphone", i);
12124 if (err < 0)
12125 return err;
12126 }
12127 }
df694daa 12128
c3fc1f50
TI
12129 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12130 alc262_check_volbit(cfg->speaker_pins[0]) |
12131 alc262_check_volbit(cfg->hp_pins[0]);
12132 if (vbits == 1 || vbits == 2)
12133 pfx = "Master"; /* only one mixer is used */
c3fc1f50 12134 vbits = 0;
033688a5
TI
12135 for (i = 0; i < 2; i++) {
12136 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12137 &vbits, i);
12138 if (err < 0)
12139 return err;
12140 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12141 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12142 "Speaker", &vbits, i);
12143 if (err < 0)
12144 return err;
12145 }
12146 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12147 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12148 "Headphone", &vbits, i);
12149 if (err < 0)
12150 return err;
12151 }
12152 }
f12ab1e0 12153 return 0;
df694daa
KY
12154}
12155
05f5f477 12156#define alc262_auto_create_input_ctls \
eaa9b3a7 12157 alc882_auto_create_input_ctls
df694daa
KY
12158
12159/*
12160 * generic initialization of ADC, input mixers and output mixers
12161 */
12162static struct hda_verb alc262_volume_init_verbs[] = {
12163 /*
12164 * Unmute ADC0-2 and set the default input to mic-in
12165 */
12166 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12167 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12168 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12169 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12170 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12171 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12172
cb53c626 12173 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 12174 * mixer widget
f12ab1e0
TI
12175 * Note: PASD motherboards uses the Line In 2 as the input for
12176 * front panel mic (mic 2)
df694daa
KY
12177 */
12178 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12179 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12180 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12181 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12182 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12183 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
12184
12185 /*
12186 * Set up output mixers (0x0c - 0x0f)
12187 */
12188 /* set vol=0 to output mixers */
12189 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12190 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12191 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 12192
df694daa
KY
12193 /* set up input amps for analog loopback */
12194 /* Amp Indices: DAC = 0, mixer = 1 */
12195 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12196 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12197 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12198 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12199 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12200 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12201
12202 /* FIXME: use matrix-type input source selection */
12203 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12204 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12205 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12206 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12207 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12208 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12209 /* Input mixer2 */
12210 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12211 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12212 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12213 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12214 /* Input mixer3 */
12215 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12216 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12217 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12218 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12219
12220 { }
12221};
12222
9c7f852e
TI
12223static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12224 /*
12225 * Unmute ADC0-2 and set the default input to mic-in
12226 */
12227 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12228 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12229 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12230 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12231 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12232 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12233
cb53c626 12234 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12235 * mixer widget
f12ab1e0
TI
12236 * Note: PASD motherboards uses the Line In 2 as the input for
12237 * front panel mic (mic 2)
9c7f852e
TI
12238 */
12239 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12240 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12241 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12242 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12243 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12244 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12245 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12246 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12247
9c7f852e
TI
12248 /*
12249 * Set up output mixers (0x0c - 0x0e)
12250 */
12251 /* set vol=0 to output mixers */
12252 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12253 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12254 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12255
12256 /* set up input amps for analog loopback */
12257 /* Amp Indices: DAC = 0, mixer = 1 */
12258 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12259 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12260 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12261 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12262 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12263 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12264
ce875f07 12265 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12266 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12267 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12268
12269 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12270 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12271
12272 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12273 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12274
12275 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12276 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12277 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12278 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12279 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12280
0e4835c1 12281 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12282 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12283 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12284 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12285 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12286 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12287
12288
12289 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12290 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12291 /* Input mixer1: only unmute Mic */
9c7f852e 12292 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12293 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12294 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12295 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12296 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12297 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12298 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12299 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12300 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12301 /* Input mixer2 */
12302 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12303 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12304 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12305 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12306 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12307 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12308 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12309 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12310 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12311 /* Input mixer3 */
12312 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12313 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12314 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12315 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12316 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12317 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12318 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12319 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12320 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12321
ce875f07
TI
12322 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12323
9c7f852e
TI
12324 { }
12325};
12326
cd7509a4
KY
12327static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12328 /*
12329 * Unmute ADC0-2 and set the default input to mic-in
12330 */
12331 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12332 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12333 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12334 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12335 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12336 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12337
cb53c626 12338 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12339 * mixer widget
12340 * Note: PASD motherboards uses the Line In 2 as the input for front
12341 * panel mic (mic 2)
12342 */
12343 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12344 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12345 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12346 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12347 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12348 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12349 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12350 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12351 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12352 /*
12353 * Set up output mixers (0x0c - 0x0e)
12354 */
12355 /* set vol=0 to output mixers */
12356 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12357 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12358 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12359
12360 /* set up input amps for analog loopback */
12361 /* Amp Indices: DAC = 0, mixer = 1 */
12362 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12363 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12364 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12365 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12366 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12367 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12368
12369
12370 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12371 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12372 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12373 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12374 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12375 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12376 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12377
12378 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12379 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12380
12381 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12382 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12383
12384 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12385 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12386 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12387 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12388 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12389 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12390
12391 /* FIXME: use matrix-type input source selection */
12392 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12393 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12394 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12395 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12396 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12397 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12398 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12399 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12400 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12401 /* Input mixer2 */
12402 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12403 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12404 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12405 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12406 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12407 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12408 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12409 /* Input mixer3 */
12410 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12411 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12412 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12413 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12414 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12415 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12416 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12417
ce875f07
TI
12418 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12419
cd7509a4
KY
12420 { }
12421};
12422
9f99a638
HM
12423static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12424
12425 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12426 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12427 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12428
12429 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12430 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12431 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12432 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12433
12434 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12435 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12436 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12437 {}
12438};
12439
18675e42
TI
12440/*
12441 * Pin config fixes
12442 */
12443enum {
12444 PINFIX_FSC_H270,
12445};
12446
12447static const struct alc_fixup alc262_fixups[] = {
12448 [PINFIX_FSC_H270] = {
12449 .pins = (const struct alc_pincfg[]) {
12450 { 0x14, 0x99130110 }, /* speaker */
12451 { 0x15, 0x0221142f }, /* front HP */
12452 { 0x1b, 0x0121141f }, /* rear HP */
12453 { }
12454 }
12455 },
12456 [PINFIX_PB_M5210] = {
12457 .verbs = (const struct hda_verb[]) {
12458 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
12459 {}
12460 }
12461 },
12462};
12463
12464static struct snd_pci_quirk alc262_fixup_tbl[] = {
12465 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12466 {}
12467};
12468
9f99a638 12469
cb53c626
TI
12470#ifdef CONFIG_SND_HDA_POWER_SAVE
12471#define alc262_loopbacks alc880_loopbacks
12472#endif
12473
def319f9 12474/* pcm configuration: identical with ALC880 */
df694daa
KY
12475#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12476#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12477#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12478#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12479
12480/*
12481 * BIOS auto configuration
12482 */
12483static int alc262_parse_auto_config(struct hda_codec *codec)
12484{
12485 struct alc_spec *spec = codec->spec;
12486 int err;
12487 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12488
f12ab1e0
TI
12489 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12490 alc262_ignore);
12491 if (err < 0)
df694daa 12492 return err;
e64f14f4 12493 if (!spec->autocfg.line_outs) {
0852d7a6 12494 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12495 spec->multiout.max_channels = 2;
12496 spec->no_analog = 1;
12497 goto dig_only;
12498 }
df694daa 12499 return 0; /* can't find valid BIOS pin config */
e64f14f4 12500 }
f12ab1e0
TI
12501 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12502 if (err < 0)
12503 return err;
05f5f477 12504 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12505 if (err < 0)
df694daa
KY
12506 return err;
12507
12508 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12509
e64f14f4 12510 dig_only:
757899ac 12511 alc_auto_parse_digital(codec);
df694daa 12512
603c4019 12513 if (spec->kctls.list)
d88897ea 12514 add_mixer(spec, spec->kctls.list);
df694daa 12515
d88897ea 12516 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12517 spec->num_mux_defs = 1;
61b9b9b1 12518 spec->input_mux = &spec->private_imux[0];
df694daa 12519
776e184e
TI
12520 err = alc_auto_add_mic_boost(codec);
12521 if (err < 0)
12522 return err;
12523
6227cdce 12524 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12525
df694daa
KY
12526 return 1;
12527}
12528
12529#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12530#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12531#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12532#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12533
12534
12535/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12536static void alc262_auto_init(struct hda_codec *codec)
df694daa 12537{
f6c7e546 12538 struct alc_spec *spec = codec->spec;
df694daa
KY
12539 alc262_auto_init_multi_out(codec);
12540 alc262_auto_init_hp_out(codec);
12541 alc262_auto_init_analog_input(codec);
f511b01c 12542 alc262_auto_init_input_src(codec);
757899ac 12543 alc_auto_init_digital(codec);
f6c7e546 12544 if (spec->unsol_event)
7fb0d78f 12545 alc_inithook(codec);
df694daa
KY
12546}
12547
12548/*
12549 * configuration and preset
12550 */
f5fcc13c
TI
12551static const char *alc262_models[ALC262_MODEL_LAST] = {
12552 [ALC262_BASIC] = "basic",
12553 [ALC262_HIPPO] = "hippo",
12554 [ALC262_HIPPO_1] = "hippo_1",
12555 [ALC262_FUJITSU] = "fujitsu",
12556 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12557 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12558 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12559 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12560 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12561 [ALC262_BENQ_T31] = "benq-t31",
12562 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12563 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12564 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12565 [ALC262_ULTRA] = "ultra",
0e31daf7 12566 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12567 [ALC262_NEC] = "nec",
ba340e82 12568 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12569 [ALC262_AUTO] = "auto",
12570};
12571
12572static struct snd_pci_quirk alc262_cfg_tbl[] = {
12573 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12574 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12575 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12576 ALC262_HP_BPC),
12577 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12578 ALC262_HP_BPC),
53eff7e1
TI
12579 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12580 ALC262_HP_BPC),
cd7509a4 12581 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12582 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12583 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12584 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12585 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12586 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12587 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12588 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12589 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12590 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12591 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12592 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12593 ALC262_HP_TC_T5735),
8c427226 12594 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12595 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12596 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12597 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12598 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12599 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12600 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12601 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12602#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12603 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12604 ALC262_SONY_ASSAMD),
c5b5165c 12605#endif
36ca6e13 12606 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12607 ALC262_TOSHIBA_RX1),
80ffe869 12608 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12609 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12610 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12611 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12612 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12613 ALC262_ULTRA),
3e420e78 12614 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12615 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12616 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12617 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12618 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12619 {}
12620};
12621
12622static struct alc_config_preset alc262_presets[] = {
12623 [ALC262_BASIC] = {
12624 .mixers = { alc262_base_mixer },
12625 .init_verbs = { alc262_init_verbs },
12626 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12627 .dac_nids = alc262_dac_nids,
12628 .hp_nid = 0x03,
12629 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12630 .channel_mode = alc262_modes,
a3bcba38 12631 .input_mux = &alc262_capture_source,
df694daa 12632 },
ccc656ce 12633 [ALC262_HIPPO] = {
42171c17 12634 .mixers = { alc262_hippo_mixer },
6732bd0d 12635 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12636 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12637 .dac_nids = alc262_dac_nids,
12638 .hp_nid = 0x03,
12639 .dig_out_nid = ALC262_DIGOUT_NID,
12640 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12641 .channel_mode = alc262_modes,
12642 .input_mux = &alc262_capture_source,
12643 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12644 .setup = alc262_hippo_setup,
12645 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12646 },
12647 [ALC262_HIPPO_1] = {
12648 .mixers = { alc262_hippo1_mixer },
12649 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12650 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12651 .dac_nids = alc262_dac_nids,
12652 .hp_nid = 0x02,
12653 .dig_out_nid = ALC262_DIGOUT_NID,
12654 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12655 .channel_mode = alc262_modes,
12656 .input_mux = &alc262_capture_source,
42171c17 12657 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12658 .setup = alc262_hippo1_setup,
12659 .init_hook = alc262_hippo_automute,
ccc656ce 12660 },
834be88d
TI
12661 [ALC262_FUJITSU] = {
12662 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12663 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12664 alc262_fujitsu_unsol_verbs },
834be88d
TI
12665 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12666 .dac_nids = alc262_dac_nids,
12667 .hp_nid = 0x03,
12668 .dig_out_nid = ALC262_DIGOUT_NID,
12669 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12670 .channel_mode = alc262_modes,
12671 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12672 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12673 .init_hook = alc262_fujitsu_init_hook,
834be88d 12674 },
9c7f852e
TI
12675 [ALC262_HP_BPC] = {
12676 .mixers = { alc262_HP_BPC_mixer },
12677 .init_verbs = { alc262_HP_BPC_init_verbs },
12678 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12679 .dac_nids = alc262_dac_nids,
12680 .hp_nid = 0x03,
12681 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12682 .channel_mode = alc262_modes,
12683 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12684 .unsol_event = alc262_hp_bpc_unsol_event,
12685 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12686 },
cd7509a4
KY
12687 [ALC262_HP_BPC_D7000_WF] = {
12688 .mixers = { alc262_HP_BPC_WildWest_mixer },
12689 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12690 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12691 .dac_nids = alc262_dac_nids,
12692 .hp_nid = 0x03,
12693 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12694 .channel_mode = alc262_modes,
accbe498 12695 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12696 .unsol_event = alc262_hp_wildwest_unsol_event,
12697 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12698 },
cd7509a4
KY
12699 [ALC262_HP_BPC_D7000_WL] = {
12700 .mixers = { alc262_HP_BPC_WildWest_mixer,
12701 alc262_HP_BPC_WildWest_option_mixer },
12702 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12703 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12704 .dac_nids = alc262_dac_nids,
12705 .hp_nid = 0x03,
12706 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12707 .channel_mode = alc262_modes,
accbe498 12708 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12709 .unsol_event = alc262_hp_wildwest_unsol_event,
12710 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12711 },
66d2a9d6
KY
12712 [ALC262_HP_TC_T5735] = {
12713 .mixers = { alc262_hp_t5735_mixer },
12714 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12715 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12716 .dac_nids = alc262_dac_nids,
12717 .hp_nid = 0x03,
12718 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12719 .channel_mode = alc262_modes,
12720 .input_mux = &alc262_capture_source,
dc99be47 12721 .unsol_event = alc_sku_unsol_event,
4f5d1706 12722 .setup = alc262_hp_t5735_setup,
dc99be47 12723 .init_hook = alc_inithook,
8c427226
KY
12724 },
12725 [ALC262_HP_RP5700] = {
12726 .mixers = { alc262_hp_rp5700_mixer },
12727 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12728 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12729 .dac_nids = alc262_dac_nids,
12730 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12731 .channel_mode = alc262_modes,
12732 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12733 },
304dcaac
TI
12734 [ALC262_BENQ_ED8] = {
12735 .mixers = { alc262_base_mixer },
12736 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12737 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12738 .dac_nids = alc262_dac_nids,
12739 .hp_nid = 0x03,
12740 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12741 .channel_mode = alc262_modes,
12742 .input_mux = &alc262_capture_source,
f12ab1e0 12743 },
272a527c
KY
12744 [ALC262_SONY_ASSAMD] = {
12745 .mixers = { alc262_sony_mixer },
12746 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12747 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12748 .dac_nids = alc262_dac_nids,
12749 .hp_nid = 0x02,
12750 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12751 .channel_mode = alc262_modes,
12752 .input_mux = &alc262_capture_source,
12753 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12754 .setup = alc262_hippo_setup,
12755 .init_hook = alc262_hippo_automute,
83c34218
KY
12756 },
12757 [ALC262_BENQ_T31] = {
12758 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12759 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12760 alc_hp15_unsol_verbs },
83c34218
KY
12761 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12762 .dac_nids = alc262_dac_nids,
12763 .hp_nid = 0x03,
12764 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12765 .channel_mode = alc262_modes,
12766 .input_mux = &alc262_capture_source,
12767 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12768 .setup = alc262_hippo_setup,
12769 .init_hook = alc262_hippo_automute,
ea1fb29a 12770 },
f651b50b 12771 [ALC262_ULTRA] = {
f9e336f6
TI
12772 .mixers = { alc262_ultra_mixer },
12773 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12774 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12775 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12776 .dac_nids = alc262_dac_nids,
f651b50b
TD
12777 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12778 .channel_mode = alc262_modes,
12779 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12780 .adc_nids = alc262_adc_nids, /* ADC0 */
12781 .capsrc_nids = alc262_capsrc_nids,
12782 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12783 .unsol_event = alc262_ultra_unsol_event,
12784 .init_hook = alc262_ultra_automute,
12785 },
0e31daf7
J
12786 [ALC262_LENOVO_3000] = {
12787 .mixers = { alc262_lenovo_3000_mixer },
12788 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12789 alc262_lenovo_3000_unsol_verbs,
12790 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12791 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12792 .dac_nids = alc262_dac_nids,
12793 .hp_nid = 0x03,
12794 .dig_out_nid = ALC262_DIGOUT_NID,
12795 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12796 .channel_mode = alc262_modes,
12797 .input_mux = &alc262_fujitsu_capture_source,
12798 .unsol_event = alc262_lenovo_3000_unsol_event,
12799 },
e8f9ae2a
PT
12800 [ALC262_NEC] = {
12801 .mixers = { alc262_nec_mixer },
12802 .init_verbs = { alc262_nec_verbs },
12803 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12804 .dac_nids = alc262_dac_nids,
12805 .hp_nid = 0x03,
12806 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12807 .channel_mode = alc262_modes,
12808 .input_mux = &alc262_capture_source,
12809 },
4e555fe5
KY
12810 [ALC262_TOSHIBA_S06] = {
12811 .mixers = { alc262_toshiba_s06_mixer },
12812 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12813 alc262_eapd_verbs },
12814 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12815 .capsrc_nids = alc262_dmic_capsrc_nids,
12816 .dac_nids = alc262_dac_nids,
12817 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12818 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12819 .dig_out_nid = ALC262_DIGOUT_NID,
12820 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12821 .channel_mode = alc262_modes,
4f5d1706
TI
12822 .unsol_event = alc_sku_unsol_event,
12823 .setup = alc262_toshiba_s06_setup,
12824 .init_hook = alc_inithook,
4e555fe5 12825 },
9f99a638
HM
12826 [ALC262_TOSHIBA_RX1] = {
12827 .mixers = { alc262_toshiba_rx1_mixer },
12828 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12829 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12830 .dac_nids = alc262_dac_nids,
12831 .hp_nid = 0x03,
12832 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12833 .channel_mode = alc262_modes,
12834 .input_mux = &alc262_capture_source,
12835 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12836 .setup = alc262_hippo_setup,
12837 .init_hook = alc262_hippo_automute,
9f99a638 12838 },
ba340e82
TV
12839 [ALC262_TYAN] = {
12840 .mixers = { alc262_tyan_mixer },
12841 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12842 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12843 .dac_nids = alc262_dac_nids,
12844 .hp_nid = 0x02,
12845 .dig_out_nid = ALC262_DIGOUT_NID,
12846 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12847 .channel_mode = alc262_modes,
12848 .input_mux = &alc262_capture_source,
a9fd4f3f 12849 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12850 .setup = alc262_tyan_setup,
12851 .init_hook = alc_automute_amp,
ba340e82 12852 },
df694daa
KY
12853};
12854
12855static int patch_alc262(struct hda_codec *codec)
12856{
12857 struct alc_spec *spec;
12858 int board_config;
12859 int err;
12860
dc041e0b 12861 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12862 if (spec == NULL)
12863 return -ENOMEM;
12864
12865 codec->spec = spec;
12866#if 0
f12ab1e0
TI
12867 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12868 * under-run
12869 */
df694daa
KY
12870 {
12871 int tmp;
12872 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12873 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12874 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12875 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12876 }
12877#endif
da00c244 12878 alc_auto_parse_customize_define(codec);
df694daa 12879
2c3bf9ab
TI
12880 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12881
f5fcc13c
TI
12882 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12883 alc262_models,
12884 alc262_cfg_tbl);
cd7509a4 12885
f5fcc13c 12886 if (board_config < 0) {
9a11f1aa
TI
12887 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12888 codec->chip_name);
df694daa
KY
12889 board_config = ALC262_AUTO;
12890 }
12891
18675e42
TI
12892 if (board_config == ALC262_AUTO)
12893 alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 1);
12894
df694daa
KY
12895 if (board_config == ALC262_AUTO) {
12896 /* automatic parse from the BIOS config */
12897 err = alc262_parse_auto_config(codec);
12898 if (err < 0) {
12899 alc_free(codec);
12900 return err;
f12ab1e0 12901 } else if (!err) {
9c7f852e
TI
12902 printk(KERN_INFO
12903 "hda_codec: Cannot set up configuration "
12904 "from BIOS. Using base mode...\n");
df694daa
KY
12905 board_config = ALC262_BASIC;
12906 }
12907 }
12908
dc1eae25 12909 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12910 err = snd_hda_attach_beep_device(codec, 0x1);
12911 if (err < 0) {
12912 alc_free(codec);
12913 return err;
12914 }
680cd536
KK
12915 }
12916
df694daa 12917 if (board_config != ALC262_AUTO)
e9c364c0 12918 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12919
df694daa
KY
12920 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12921 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12922
df694daa
KY
12923 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12924 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12925
f12ab1e0 12926 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12927 int i;
12928 /* check whether the digital-mic has to be supported */
12929 for (i = 0; i < spec->input_mux->num_items; i++) {
12930 if (spec->input_mux->items[i].index >= 9)
12931 break;
12932 }
12933 if (i < spec->input_mux->num_items) {
12934 /* use only ADC0 */
12935 spec->adc_nids = alc262_dmic_adc_nids;
12936 spec->num_adc_nids = 1;
12937 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12938 } else {
8c927b4a
TI
12939 /* all analog inputs */
12940 /* check whether NID 0x07 is valid */
12941 unsigned int wcap = get_wcaps(codec, 0x07);
12942
12943 /* get type */
a22d543a 12944 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12945 if (wcap != AC_WID_AUD_IN) {
12946 spec->adc_nids = alc262_adc_nids_alt;
12947 spec->num_adc_nids =
12948 ARRAY_SIZE(alc262_adc_nids_alt);
12949 spec->capsrc_nids = alc262_capsrc_nids_alt;
12950 } else {
12951 spec->adc_nids = alc262_adc_nids;
12952 spec->num_adc_nids =
12953 ARRAY_SIZE(alc262_adc_nids);
12954 spec->capsrc_nids = alc262_capsrc_nids;
12955 }
df694daa
KY
12956 }
12957 }
e64f14f4 12958 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12959 set_capture_mixer(codec);
dc1eae25 12960 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 12961 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12962
18675e42
TI
12963 if (board_config == ALC262_AUTO)
12964 alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 0);
12965
2134ea4f
TI
12966 spec->vmaster_nid = 0x0c;
12967
df694daa
KY
12968 codec->patch_ops = alc_patch_ops;
12969 if (board_config == ALC262_AUTO)
ae6b813a 12970 spec->init_hook = alc262_auto_init;
bf1b0225
KY
12971
12972 alc_init_jacks(codec);
cb53c626
TI
12973#ifdef CONFIG_SND_HDA_POWER_SAVE
12974 if (!spec->loopback.amplist)
12975 spec->loopback.amplist = alc262_loopbacks;
12976#endif
ea1fb29a 12977
df694daa
KY
12978 return 0;
12979}
12980
a361d84b
KY
12981/*
12982 * ALC268 channel source setting (2 channel)
12983 */
12984#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12985#define alc268_modes alc260_modes
ea1fb29a 12986
a361d84b
KY
12987static hda_nid_t alc268_dac_nids[2] = {
12988 /* front, hp */
12989 0x02, 0x03
12990};
12991
12992static hda_nid_t alc268_adc_nids[2] = {
12993 /* ADC0-1 */
12994 0x08, 0x07
12995};
12996
12997static hda_nid_t alc268_adc_nids_alt[1] = {
12998 /* ADC0 */
12999 0x08
13000};
13001
e1406348
TI
13002static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13003
a361d84b
KY
13004static struct snd_kcontrol_new alc268_base_mixer[] = {
13005 /* output mixer control */
13006 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13007 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13008 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13009 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13010 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13011 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13012 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
a361d84b
KY
13013 { }
13014};
13015
42171c17
TI
13016static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13017 /* output mixer control */
13018 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13019 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13020 ALC262_HIPPO_MASTER_SWITCH,
5f99f86a
DH
13021 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13022 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13023 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
42171c17
TI
13024 { }
13025};
13026
aef9d318
TI
13027/* bind Beep switches of both NID 0x0f and 0x10 */
13028static struct hda_bind_ctls alc268_bind_beep_sw = {
13029 .ops = &snd_hda_bind_sw,
13030 .values = {
13031 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13032 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13033 0
13034 },
13035};
13036
13037static struct snd_kcontrol_new alc268_beep_mixer[] = {
13038 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13039 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13040 { }
13041};
13042
d1a991a6
KY
13043static struct hda_verb alc268_eapd_verbs[] = {
13044 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13045 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13046 { }
13047};
13048
d273809e 13049/* Toshiba specific */
d273809e
TI
13050static struct hda_verb alc268_toshiba_verbs[] = {
13051 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13052 { } /* end */
13053};
13054
13055/* Acer specific */
889c4395 13056/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
13057static struct hda_bind_ctls alc268_acer_bind_master_vol = {
13058 .ops = &snd_hda_bind_vol,
13059 .values = {
13060 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13061 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13062 0
13063 },
13064};
13065
889c4395
TI
13066/* mute/unmute internal speaker according to the hp jack and mute state */
13067static void alc268_acer_automute(struct hda_codec *codec, int force)
13068{
13069 struct alc_spec *spec = codec->spec;
13070 unsigned int mute;
13071
13072 if (force || !spec->sense_updated) {
864f92be 13073 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
13074 spec->sense_updated = 1;
13075 }
13076 if (spec->jack_present)
13077 mute = HDA_AMP_MUTE; /* mute internal speaker */
13078 else /* unmute internal speaker if necessary */
13079 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13080 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13081 HDA_AMP_MUTE, mute);
13082}
13083
13084
13085/* bind hp and internal speaker mute (with plug check) */
13086static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
13087 struct snd_ctl_elem_value *ucontrol)
13088{
13089 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
13090 long *valp = ucontrol->value.integer.value;
13091 int change;
13092
8de56b7d 13093 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
13094 if (change)
13095 alc268_acer_automute(codec, 0);
13096 return change;
13097}
d273809e 13098
8ef355da
KY
13099static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13100 /* output mixer control */
13101 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13102 {
13103 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13104 .name = "Master Playback Switch",
5e26dfd0 13105 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
13106 .info = snd_hda_mixer_amp_switch_info,
13107 .get = snd_hda_mixer_amp_switch_get,
13108 .put = alc268_acer_master_sw_put,
13109 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13110 },
13111 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13112 { }
13113};
13114
d273809e
TI
13115static struct snd_kcontrol_new alc268_acer_mixer[] = {
13116 /* output mixer control */
13117 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13118 {
13119 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13120 .name = "Master Playback Switch",
5e26dfd0 13121 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
13122 .info = snd_hda_mixer_amp_switch_info,
13123 .get = snd_hda_mixer_amp_switch_get,
13124 .put = alc268_acer_master_sw_put,
13125 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13126 },
5f99f86a
DH
13127 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13128 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13129 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
d273809e
TI
13130 { }
13131};
13132
c238b4f4
TI
13133static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13134 /* output mixer control */
13135 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13136 {
13137 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13138 .name = "Master Playback Switch",
5e26dfd0 13139 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
13140 .info = snd_hda_mixer_amp_switch_info,
13141 .get = snd_hda_mixer_amp_switch_get,
13142 .put = alc268_acer_master_sw_put,
13143 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13144 },
5f99f86a
DH
13145 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13146 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
c238b4f4
TI
13147 { }
13148};
13149
8ef355da
KY
13150static struct hda_verb alc268_acer_aspire_one_verbs[] = {
13151 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13152 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13153 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13154 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13155 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13156 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13157 { }
13158};
13159
d273809e 13160static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13161 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13162 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13163 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13164 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13165 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13166 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13167 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13168 { }
13169};
13170
13171/* unsolicited event for HP jack sensing */
42171c17 13172#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
13173#define alc268_toshiba_setup alc262_hippo_setup
13174#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
13175
13176static void alc268_acer_unsol_event(struct hda_codec *codec,
13177 unsigned int res)
13178{
889c4395 13179 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
13180 return;
13181 alc268_acer_automute(codec, 1);
13182}
13183
889c4395
TI
13184static void alc268_acer_init_hook(struct hda_codec *codec)
13185{
13186 alc268_acer_automute(codec, 1);
13187}
13188
8ef355da
KY
13189/* toggle speaker-output according to the hp-jack state */
13190static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
13191{
13192 unsigned int present;
13193 unsigned char bits;
13194
864f92be 13195 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13196 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 13197 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 13198 HDA_AMP_MUTE, bits);
8ef355da 13199 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 13200 HDA_AMP_MUTE, bits);
8ef355da
KY
13201}
13202
8ef355da
KY
13203static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
13204 unsigned int res)
13205{
4f5d1706
TI
13206 switch (res >> 26) {
13207 case ALC880_HP_EVENT:
8ef355da 13208 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
13209 break;
13210 case ALC880_MIC_EVENT:
13211 alc_mic_automute(codec);
13212 break;
13213 }
13214}
13215
13216static void alc268_acer_lc_setup(struct hda_codec *codec)
13217{
13218 struct alc_spec *spec = codec->spec;
13219 spec->ext_mic.pin = 0x18;
13220 spec->ext_mic.mux_idx = 0;
13221 spec->int_mic.pin = 0x12;
13222 spec->int_mic.mux_idx = 6;
13223 spec->auto_mic = 1;
8ef355da
KY
13224}
13225
13226static void alc268_acer_lc_init_hook(struct hda_codec *codec)
13227{
13228 alc268_aspire_one_speaker_automute(codec);
4f5d1706 13229 alc_mic_automute(codec);
8ef355da
KY
13230}
13231
3866f0b0
TI
13232static struct snd_kcontrol_new alc268_dell_mixer[] = {
13233 /* output mixer control */
13234 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13235 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13236 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13237 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13238 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13239 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
3866f0b0
TI
13240 { }
13241};
13242
13243static struct hda_verb alc268_dell_verbs[] = {
13244 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13245 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13246 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 13247 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
13248 { }
13249};
13250
13251/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 13252static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 13253{
a9fd4f3f 13254 struct alc_spec *spec = codec->spec;
3866f0b0 13255
a9fd4f3f
TI
13256 spec->autocfg.hp_pins[0] = 0x15;
13257 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13258 spec->ext_mic.pin = 0x18;
13259 spec->ext_mic.mux_idx = 0;
13260 spec->int_mic.pin = 0x19;
13261 spec->int_mic.mux_idx = 1;
13262 spec->auto_mic = 1;
3866f0b0
TI
13263}
13264
eb5a6621
HRK
13265static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13266 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13267 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13268 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13269 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13270 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13271 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
5f99f86a
DH
13272 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13273 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
eb5a6621
HRK
13274 { }
13275};
13276
13277static struct hda_verb alc267_quanta_il1_verbs[] = {
13278 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13279 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13280 { }
13281};
13282
4f5d1706 13283static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 13284{
a9fd4f3f 13285 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
13286 spec->autocfg.hp_pins[0] = 0x15;
13287 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13288 spec->ext_mic.pin = 0x18;
13289 spec->ext_mic.mux_idx = 0;
13290 spec->int_mic.pin = 0x19;
13291 spec->int_mic.mux_idx = 1;
13292 spec->auto_mic = 1;
eb5a6621
HRK
13293}
13294
a361d84b
KY
13295/*
13296 * generic initialization of ADC, input mixers and output mixers
13297 */
13298static struct hda_verb alc268_base_init_verbs[] = {
13299 /* Unmute DAC0-1 and set vol = 0 */
13300 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 13301 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13302
13303 /*
13304 * Set up output mixers (0x0c - 0x0e)
13305 */
13306 /* set vol=0 to output mixers */
13307 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13308 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13309
13310 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13311 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13312
13313 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13314 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13315 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13316 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13317 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13318 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13319 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13320 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13321
13322 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13323 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13324 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13325 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13326 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13327
13328 /* set PCBEEP vol = 0, mute connections */
13329 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13330 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13331 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13332
a9b3aa8a 13333 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13334
a9b3aa8a
JZ
13335 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13336 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13337 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13338 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13339
a361d84b
KY
13340 { }
13341};
13342
13343/*
13344 * generic initialization of ADC, input mixers and output mixers
13345 */
13346static struct hda_verb alc268_volume_init_verbs[] = {
13347 /* set output DAC */
4cfb91c6
TI
13348 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13349 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13350
13351 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13352 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13353 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13354 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13355 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13356
a361d84b 13357 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13358 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13359 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13360
13361 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13362 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13363
aef9d318
TI
13364 /* set PCBEEP vol = 0, mute connections */
13365 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13366 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13367 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13368
13369 { }
13370};
13371
fdbc6626
TI
13372static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13373 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13374 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13375 { } /* end */
13376};
13377
a361d84b
KY
13378static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13379 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13380 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13381 _DEFINE_CAPSRC(1),
a361d84b
KY
13382 { } /* end */
13383};
13384
13385static struct snd_kcontrol_new alc268_capture_mixer[] = {
13386 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13387 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13388 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13389 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13390 _DEFINE_CAPSRC(2),
a361d84b
KY
13391 { } /* end */
13392};
13393
13394static struct hda_input_mux alc268_capture_source = {
13395 .num_items = 4,
13396 .items = {
13397 { "Mic", 0x0 },
13398 { "Front Mic", 0x1 },
13399 { "Line", 0x2 },
13400 { "CD", 0x3 },
13401 },
13402};
13403
0ccb541c 13404static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13405 .num_items = 3,
13406 .items = {
13407 { "Mic", 0x0 },
13408 { "Internal Mic", 0x1 },
13409 { "Line", 0x2 },
13410 },
13411};
13412
13413static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13414 .num_items = 3,
13415 .items = {
13416 { "Mic", 0x0 },
13417 { "Internal Mic", 0x6 },
13418 { "Line", 0x2 },
13419 },
13420};
13421
86c53bd2
JW
13422#ifdef CONFIG_SND_DEBUG
13423static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13424 /* Volume widgets */
13425 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13426 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13427 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13428 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13429 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13430 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13431 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13432 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13433 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13434 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13435 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13436 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13437 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13438 /* The below appears problematic on some hardwares */
13439 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13440 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13441 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13442 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13443 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13444
13445 /* Modes for retasking pin widgets */
13446 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13447 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13448 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13449 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13450
13451 /* Controls for GPIO pins, assuming they are configured as outputs */
13452 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13453 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13454 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13455 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13456
13457 /* Switches to allow the digital SPDIF output pin to be enabled.
13458 * The ALC268 does not have an SPDIF input.
13459 */
13460 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13461
13462 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13463 * this output to turn on an external amplifier.
13464 */
13465 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13466 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13467
13468 { } /* end */
13469};
13470#endif
13471
a361d84b
KY
13472/* create input playback/capture controls for the given pin */
13473static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13474 const char *ctlname, int idx)
13475{
3f3b7c1a 13476 hda_nid_t dac;
a361d84b
KY
13477 int err;
13478
3f3b7c1a
TI
13479 switch (nid) {
13480 case 0x14:
13481 case 0x16:
13482 dac = 0x02;
13483 break;
13484 case 0x15:
b08b1637
TI
13485 case 0x1a: /* ALC259/269 only */
13486 case 0x1b: /* ALC259/269 only */
531d8791 13487 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13488 dac = 0x03;
13489 break;
13490 default:
c7a9434d
TI
13491 snd_printd(KERN_WARNING "hda_codec: "
13492 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13493 return 0;
13494 }
13495 if (spec->multiout.dac_nids[0] != dac &&
13496 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13497 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13498 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13499 HDA_OUTPUT));
13500 if (err < 0)
13501 return err;
3f3b7c1a
TI
13502 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13503 }
13504
3f3b7c1a 13505 if (nid != 0x16)
0afe5f89 13506 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13507 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13508 else /* mono */
0afe5f89 13509 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13510 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13511 if (err < 0)
13512 return err;
13513 return 0;
13514}
13515
13516/* add playback controls from the parsed DAC table */
13517static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13518 const struct auto_pin_cfg *cfg)
13519{
13520 hda_nid_t nid;
13521 int err;
13522
a361d84b 13523 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13524
13525 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13526 if (nid) {
13527 const char *name;
13528 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13529 name = "Speaker";
13530 else
13531 name = "Front";
13532 err = alc268_new_analog_output(spec, nid, name, 0);
13533 if (err < 0)
13534 return err;
13535 }
a361d84b
KY
13536
13537 nid = cfg->speaker_pins[0];
13538 if (nid == 0x1d) {
0afe5f89 13539 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13540 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13541 if (err < 0)
13542 return err;
7bfb9c03 13543 } else if (nid) {
3f3b7c1a
TI
13544 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13545 if (err < 0)
13546 return err;
a361d84b
KY
13547 }
13548 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13549 if (nid) {
13550 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13551 if (err < 0)
13552 return err;
13553 }
a361d84b
KY
13554
13555 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13556 if (nid == 0x16) {
0afe5f89 13557 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13558 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13559 if (err < 0)
13560 return err;
13561 }
ea1fb29a 13562 return 0;
a361d84b
KY
13563}
13564
13565/* create playback/capture controls for input pins */
05f5f477 13566static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13567 const struct auto_pin_cfg *cfg)
13568{
05f5f477 13569 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13570}
13571
e9af4f36
TI
13572static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13573 hda_nid_t nid, int pin_type)
13574{
13575 int idx;
13576
13577 alc_set_pin_output(codec, nid, pin_type);
13578 if (nid == 0x14 || nid == 0x16)
13579 idx = 0;
13580 else
13581 idx = 1;
13582 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13583}
13584
13585static void alc268_auto_init_multi_out(struct hda_codec *codec)
13586{
13587 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13588 int i;
13589
13590 for (i = 0; i < spec->autocfg.line_outs; i++) {
13591 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13592 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13593 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13594 }
13595}
13596
13597static void alc268_auto_init_hp_out(struct hda_codec *codec)
13598{
13599 struct alc_spec *spec = codec->spec;
13600 hda_nid_t pin;
e1ca7b4e 13601 int i;
e9af4f36 13602
e1ca7b4e
TI
13603 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13604 pin = spec->autocfg.hp_pins[i];
e9af4f36 13605 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13606 }
13607 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13608 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13609 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13610 }
13611 if (spec->autocfg.mono_out_pin)
13612 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13613 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36
TI
13614}
13615
a361d84b
KY
13616static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13617{
13618 struct alc_spec *spec = codec->spec;
13619 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13620 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13621 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13622 unsigned int dac_vol1, dac_vol2;
13623
e9af4f36 13624 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13625 snd_hda_codec_write(codec, speaker_nid, 0,
13626 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13627 /* mute mixer inputs from 0x1d */
a361d84b
KY
13628 snd_hda_codec_write(codec, 0x0f, 0,
13629 AC_VERB_SET_AMP_GAIN_MUTE,
13630 AMP_IN_UNMUTE(1));
13631 snd_hda_codec_write(codec, 0x10, 0,
13632 AC_VERB_SET_AMP_GAIN_MUTE,
13633 AMP_IN_UNMUTE(1));
13634 } else {
e9af4f36 13635 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13636 snd_hda_codec_write(codec, 0x0f, 0,
13637 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13638 snd_hda_codec_write(codec, 0x10, 0,
13639 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13640 }
13641
13642 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13643 if (line_nid == 0x14)
a361d84b
KY
13644 dac_vol2 = AMP_OUT_ZERO;
13645 else if (line_nid == 0x15)
13646 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13647 if (hp_nid == 0x14)
a361d84b
KY
13648 dac_vol2 = AMP_OUT_ZERO;
13649 else if (hp_nid == 0x15)
13650 dac_vol1 = AMP_OUT_ZERO;
13651 if (line_nid != 0x16 || hp_nid != 0x16 ||
13652 spec->autocfg.line_out_pins[1] != 0x16 ||
13653 spec->autocfg.line_out_pins[2] != 0x16)
13654 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13655
13656 snd_hda_codec_write(codec, 0x02, 0,
13657 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13658 snd_hda_codec_write(codec, 0x03, 0,
13659 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13660}
13661
def319f9 13662/* pcm configuration: identical with ALC880 */
a361d84b
KY
13663#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13664#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13665#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13666#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13667
13668/*
13669 * BIOS auto configuration
13670 */
13671static int alc268_parse_auto_config(struct hda_codec *codec)
13672{
13673 struct alc_spec *spec = codec->spec;
13674 int err;
13675 static hda_nid_t alc268_ignore[] = { 0 };
13676
13677 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13678 alc268_ignore);
13679 if (err < 0)
13680 return err;
7e0e44d4
TI
13681 if (!spec->autocfg.line_outs) {
13682 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13683 spec->multiout.max_channels = 2;
13684 spec->no_analog = 1;
13685 goto dig_only;
13686 }
a361d84b 13687 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13688 }
a361d84b
KY
13689 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13690 if (err < 0)
13691 return err;
05f5f477 13692 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13693 if (err < 0)
13694 return err;
13695
13696 spec->multiout.max_channels = 2;
13697
7e0e44d4 13698 dig_only:
a361d84b 13699 /* digital only support output */
757899ac 13700 alc_auto_parse_digital(codec);
603c4019 13701 if (spec->kctls.list)
d88897ea 13702 add_mixer(spec, spec->kctls.list);
a361d84b 13703
892981ff 13704 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13705 add_mixer(spec, alc268_beep_mixer);
aef9d318 13706
d88897ea 13707 add_verb(spec, alc268_volume_init_verbs);
5908589f 13708 spec->num_mux_defs = 2;
61b9b9b1 13709 spec->input_mux = &spec->private_imux[0];
a361d84b 13710
776e184e
TI
13711 err = alc_auto_add_mic_boost(codec);
13712 if (err < 0)
13713 return err;
13714
6227cdce 13715 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13716
a361d84b
KY
13717 return 1;
13718}
13719
a361d84b
KY
13720#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13721
13722/* init callback for auto-configuration model -- overriding the default init */
13723static void alc268_auto_init(struct hda_codec *codec)
13724{
f6c7e546 13725 struct alc_spec *spec = codec->spec;
a361d84b
KY
13726 alc268_auto_init_multi_out(codec);
13727 alc268_auto_init_hp_out(codec);
13728 alc268_auto_init_mono_speaker_out(codec);
13729 alc268_auto_init_analog_input(codec);
757899ac 13730 alc_auto_init_digital(codec);
f6c7e546 13731 if (spec->unsol_event)
7fb0d78f 13732 alc_inithook(codec);
a361d84b
KY
13733}
13734
13735/*
13736 * configuration and preset
13737 */
13738static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13739 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13740 [ALC268_3ST] = "3stack",
983f8ae4 13741 [ALC268_TOSHIBA] = "toshiba",
d273809e 13742 [ALC268_ACER] = "acer",
c238b4f4 13743 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13744 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13745 [ALC268_DELL] = "dell",
f12462c5 13746 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13747#ifdef CONFIG_SND_DEBUG
13748 [ALC268_TEST] = "test",
13749#endif
a361d84b
KY
13750 [ALC268_AUTO] = "auto",
13751};
13752
13753static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13754 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13755 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13756 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13757 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13758 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13759 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13760 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13761 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13762 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13763 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13764 /* almost compatible with toshiba but with optional digital outs;
13765 * auto-probing seems working fine
13766 */
8871e5b9 13767 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13768 ALC268_AUTO),
a361d84b 13769 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13770 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13771 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13772 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13773 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13774 {}
13775};
13776
3abf2f36
TI
13777/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13778static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13779 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13780 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13781 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13782 ALC268_TOSHIBA),
13783 {}
13784};
13785
a361d84b 13786static struct alc_config_preset alc268_presets[] = {
eb5a6621 13787 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13788 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13789 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13790 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13791 alc267_quanta_il1_verbs },
13792 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13793 .dac_nids = alc268_dac_nids,
13794 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13795 .adc_nids = alc268_adc_nids_alt,
13796 .hp_nid = 0x03,
13797 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13798 .channel_mode = alc268_modes,
4f5d1706
TI
13799 .unsol_event = alc_sku_unsol_event,
13800 .setup = alc267_quanta_il1_setup,
13801 .init_hook = alc_inithook,
eb5a6621 13802 },
a361d84b 13803 [ALC268_3ST] = {
aef9d318
TI
13804 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13805 alc268_beep_mixer },
a361d84b
KY
13806 .init_verbs = { alc268_base_init_verbs },
13807 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13808 .dac_nids = alc268_dac_nids,
13809 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13810 .adc_nids = alc268_adc_nids_alt,
e1406348 13811 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13812 .hp_nid = 0x03,
13813 .dig_out_nid = ALC268_DIGOUT_NID,
13814 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13815 .channel_mode = alc268_modes,
13816 .input_mux = &alc268_capture_source,
13817 },
d1a991a6 13818 [ALC268_TOSHIBA] = {
42171c17 13819 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13820 alc268_beep_mixer },
d273809e
TI
13821 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13822 alc268_toshiba_verbs },
d1a991a6
KY
13823 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13824 .dac_nids = alc268_dac_nids,
13825 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13826 .adc_nids = alc268_adc_nids_alt,
e1406348 13827 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13828 .hp_nid = 0x03,
13829 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13830 .channel_mode = alc268_modes,
13831 .input_mux = &alc268_capture_source,
d273809e 13832 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13833 .setup = alc268_toshiba_setup,
13834 .init_hook = alc268_toshiba_automute,
d273809e
TI
13835 },
13836 [ALC268_ACER] = {
432fd133 13837 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13838 alc268_beep_mixer },
d273809e
TI
13839 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13840 alc268_acer_verbs },
13841 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13842 .dac_nids = alc268_dac_nids,
13843 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13844 .adc_nids = alc268_adc_nids_alt,
e1406348 13845 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13846 .hp_nid = 0x02,
13847 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13848 .channel_mode = alc268_modes,
0ccb541c 13849 .input_mux = &alc268_acer_capture_source,
d273809e 13850 .unsol_event = alc268_acer_unsol_event,
889c4395 13851 .init_hook = alc268_acer_init_hook,
d1a991a6 13852 },
c238b4f4
TI
13853 [ALC268_ACER_DMIC] = {
13854 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13855 alc268_beep_mixer },
13856 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13857 alc268_acer_verbs },
13858 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13859 .dac_nids = alc268_dac_nids,
13860 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13861 .adc_nids = alc268_adc_nids_alt,
13862 .capsrc_nids = alc268_capsrc_nids,
13863 .hp_nid = 0x02,
13864 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13865 .channel_mode = alc268_modes,
13866 .input_mux = &alc268_acer_dmic_capture_source,
13867 .unsol_event = alc268_acer_unsol_event,
13868 .init_hook = alc268_acer_init_hook,
13869 },
8ef355da
KY
13870 [ALC268_ACER_ASPIRE_ONE] = {
13871 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13872 alc268_beep_mixer,
fdbc6626 13873 alc268_capture_nosrc_mixer },
8ef355da
KY
13874 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13875 alc268_acer_aspire_one_verbs },
13876 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13877 .dac_nids = alc268_dac_nids,
13878 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13879 .adc_nids = alc268_adc_nids_alt,
13880 .capsrc_nids = alc268_capsrc_nids,
13881 .hp_nid = 0x03,
13882 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13883 .channel_mode = alc268_modes,
8ef355da 13884 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13885 .setup = alc268_acer_lc_setup,
8ef355da
KY
13886 .init_hook = alc268_acer_lc_init_hook,
13887 },
3866f0b0 13888 [ALC268_DELL] = {
fdbc6626
TI
13889 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13890 alc268_capture_nosrc_mixer },
3866f0b0
TI
13891 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13892 alc268_dell_verbs },
13893 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13894 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13895 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13896 .adc_nids = alc268_adc_nids_alt,
13897 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13898 .hp_nid = 0x02,
13899 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13900 .channel_mode = alc268_modes,
a9fd4f3f 13901 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13902 .setup = alc268_dell_setup,
13903 .init_hook = alc_inithook,
3866f0b0 13904 },
f12462c5 13905 [ALC268_ZEPTO] = {
aef9d318
TI
13906 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13907 alc268_beep_mixer },
f12462c5
MT
13908 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13909 alc268_toshiba_verbs },
13910 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13911 .dac_nids = alc268_dac_nids,
13912 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13913 .adc_nids = alc268_adc_nids_alt,
e1406348 13914 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13915 .hp_nid = 0x03,
13916 .dig_out_nid = ALC268_DIGOUT_NID,
13917 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13918 .channel_mode = alc268_modes,
13919 .input_mux = &alc268_capture_source,
4f5d1706
TI
13920 .setup = alc268_toshiba_setup,
13921 .init_hook = alc268_toshiba_automute,
f12462c5 13922 },
86c53bd2
JW
13923#ifdef CONFIG_SND_DEBUG
13924 [ALC268_TEST] = {
13925 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13926 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13927 alc268_volume_init_verbs },
13928 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13929 .dac_nids = alc268_dac_nids,
13930 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13931 .adc_nids = alc268_adc_nids_alt,
e1406348 13932 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13933 .hp_nid = 0x03,
13934 .dig_out_nid = ALC268_DIGOUT_NID,
13935 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13936 .channel_mode = alc268_modes,
13937 .input_mux = &alc268_capture_source,
13938 },
13939#endif
a361d84b
KY
13940};
13941
13942static int patch_alc268(struct hda_codec *codec)
13943{
13944 struct alc_spec *spec;
13945 int board_config;
22971e3a 13946 int i, has_beep, err;
a361d84b 13947
ef86f581 13948 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13949 if (spec == NULL)
13950 return -ENOMEM;
13951
13952 codec->spec = spec;
13953
13954 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13955 alc268_models,
13956 alc268_cfg_tbl);
13957
3abf2f36
TI
13958 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13959 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13960 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13961
a361d84b 13962 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13963 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13964 codec->chip_name);
a361d84b
KY
13965 board_config = ALC268_AUTO;
13966 }
13967
13968 if (board_config == ALC268_AUTO) {
13969 /* automatic parse from the BIOS config */
13970 err = alc268_parse_auto_config(codec);
13971 if (err < 0) {
13972 alc_free(codec);
13973 return err;
13974 } else if (!err) {
13975 printk(KERN_INFO
13976 "hda_codec: Cannot set up configuration "
13977 "from BIOS. Using base mode...\n");
13978 board_config = ALC268_3ST;
13979 }
13980 }
13981
13982 if (board_config != ALC268_AUTO)
e9c364c0 13983 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 13984
a361d84b
KY
13985 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13986 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 13987 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 13988
a361d84b
KY
13989 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13990
22971e3a
TI
13991 has_beep = 0;
13992 for (i = 0; i < spec->num_mixers; i++) {
13993 if (spec->mixers[i] == alc268_beep_mixer) {
13994 has_beep = 1;
13995 break;
13996 }
13997 }
13998
13999 if (has_beep) {
14000 err = snd_hda_attach_beep_device(codec, 0x1);
14001 if (err < 0) {
14002 alc_free(codec);
14003 return err;
14004 }
14005 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14006 /* override the amp caps for beep generator */
14007 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
14008 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14009 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14010 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14011 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 14012 }
aef9d318 14013
7e0e44d4 14014 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
14015 /* check whether NID 0x07 is valid */
14016 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 14017 int i;
3866f0b0 14018
defb5ab2 14019 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 14020 /* get type */
a22d543a 14021 wcap = get_wcaps_type(wcap);
fdbc6626
TI
14022 if (spec->auto_mic ||
14023 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
14024 spec->adc_nids = alc268_adc_nids_alt;
14025 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
14026 if (spec->auto_mic)
14027 fixup_automic_adc(codec);
fdbc6626
TI
14028 if (spec->auto_mic || spec->input_mux->num_items == 1)
14029 add_mixer(spec, alc268_capture_nosrc_mixer);
14030 else
14031 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
14032 } else {
14033 spec->adc_nids = alc268_adc_nids;
14034 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 14035 add_mixer(spec, alc268_capture_mixer);
a361d84b 14036 }
85860c06
TI
14037 /* set default input source */
14038 for (i = 0; i < spec->num_adc_nids; i++)
14039 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
14040 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
14041 i < spec->num_mux_defs ?
14042 spec->input_mux[i].items[0].index :
85860c06 14043 spec->input_mux->items[0].index);
a361d84b 14044 }
2134ea4f
TI
14045
14046 spec->vmaster_nid = 0x02;
14047
a361d84b
KY
14048 codec->patch_ops = alc_patch_ops;
14049 if (board_config == ALC268_AUTO)
14050 spec->init_hook = alc268_auto_init;
ea1fb29a 14051
bf1b0225
KY
14052 alc_init_jacks(codec);
14053
a361d84b
KY
14054 return 0;
14055}
14056
f6a92248
KY
14057/*
14058 * ALC269 channel source setting (2 channel)
14059 */
14060#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14061
14062#define alc269_dac_nids alc260_dac_nids
14063
14064static hda_nid_t alc269_adc_nids[1] = {
14065 /* ADC1 */
f53281e6
KY
14066 0x08,
14067};
14068
e01bf509
TI
14069static hda_nid_t alc269_capsrc_nids[1] = {
14070 0x23,
14071};
14072
84898e87
KY
14073static hda_nid_t alc269vb_adc_nids[1] = {
14074 /* ADC1 */
14075 0x09,
14076};
14077
14078static hda_nid_t alc269vb_capsrc_nids[1] = {
14079 0x22,
14080};
14081
6694635d
TI
14082static hda_nid_t alc269_adc_candidates[] = {
14083 0x08, 0x09, 0x07,
14084};
e01bf509 14085
f6a92248
KY
14086#define alc269_modes alc260_modes
14087#define alc269_capture_source alc880_lg_lw_capture_source
14088
14089static struct snd_kcontrol_new alc269_base_mixer[] = {
14090 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14091 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14092 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14093 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14094 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14095 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14096 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f6a92248
KY
14097 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14098 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14099 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f6a92248
KY
14100 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14101 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14102 { } /* end */
14103};
14104
60db6b53
KY
14105static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14106 /* output mixer control */
14107 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14108 {
14109 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14110 .name = "Master Playback Switch",
5e26dfd0 14111 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
14112 .info = snd_hda_mixer_amp_switch_info,
14113 .get = snd_hda_mixer_amp_switch_get,
14114 .put = alc268_acer_master_sw_put,
14115 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14116 },
14117 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14118 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14119 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
60db6b53
KY
14120 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14121 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14122 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
60db6b53
KY
14123 { }
14124};
14125
64154835
TV
14126static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14127 /* output mixer control */
14128 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14129 {
14130 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14131 .name = "Master Playback Switch",
5e26dfd0 14132 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14133 .info = snd_hda_mixer_amp_switch_info,
14134 .get = snd_hda_mixer_amp_switch_get,
14135 .put = alc268_acer_master_sw_put,
14136 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14137 },
14138 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14139 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14140 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64154835
TV
14141 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14142 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14143 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
64154835
TV
14144 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14145 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
5f99f86a 14146 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
64154835
TV
14147 { }
14148};
14149
84898e87 14150static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14151 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14152 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14153 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14154 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14155 { } /* end */
14156};
14157
84898e87
KY
14158static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14159 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14160 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14161 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14162 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14163 { } /* end */
14164};
14165
fe3eb0a7
KY
14166static struct snd_kcontrol_new alc269_asus_mixer[] = {
14167 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14168 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14169 { } /* end */
14170};
14171
f53281e6 14172/* capture mixer elements */
84898e87
KY
14173static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14174 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14175 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a
DH
14176 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14177 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14178 { } /* end */
14179};
14180
14181static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14182 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14183 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a 14184 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
26f5df26
TI
14185 { } /* end */
14186};
14187
84898e87
KY
14188static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14189 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14190 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a
DH
14191 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14192 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14193 { } /* end */
14194};
14195
14196static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14197 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14198 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a 14199 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
84898e87
KY
14200 { } /* end */
14201};
14202
26f5df26 14203/* FSC amilo */
84898e87 14204#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14205
60db6b53
KY
14206static struct hda_verb alc269_quanta_fl1_verbs[] = {
14207 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14208 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14209 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14210 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14211 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14212 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14213 { }
14214};
f6a92248 14215
64154835
TV
14216static struct hda_verb alc269_lifebook_verbs[] = {
14217 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14218 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14219 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14220 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14221 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14222 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14223 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14224 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14225 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14226 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14227 { }
14228};
14229
60db6b53
KY
14230/* toggle speaker-output according to the hp-jack state */
14231static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14232{
14233 unsigned int present;
14234 unsigned char bits;
f6a92248 14235
864f92be 14236 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 14237 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 14238 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14239 HDA_AMP_MUTE, bits);
60db6b53 14240 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14241 HDA_AMP_MUTE, bits);
f6a92248 14242
60db6b53
KY
14243 snd_hda_codec_write(codec, 0x20, 0,
14244 AC_VERB_SET_COEF_INDEX, 0x0c);
14245 snd_hda_codec_write(codec, 0x20, 0,
14246 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 14247
60db6b53
KY
14248 snd_hda_codec_write(codec, 0x20, 0,
14249 AC_VERB_SET_COEF_INDEX, 0x0c);
14250 snd_hda_codec_write(codec, 0x20, 0,
14251 AC_VERB_SET_PROC_COEF, 0x480);
14252}
f6a92248 14253
64154835
TV
14254/* toggle speaker-output according to the hp-jacks state */
14255static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
14256{
14257 unsigned int present;
14258 unsigned char bits;
14259
14260 /* Check laptop headphone socket */
864f92be 14261 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
14262
14263 /* Check port replicator headphone socket */
864f92be 14264 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 14265
5dbd5ec6 14266 bits = present ? HDA_AMP_MUTE : 0;
64154835 14267 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14268 HDA_AMP_MUTE, bits);
64154835 14269 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14270 HDA_AMP_MUTE, bits);
64154835
TV
14271
14272 snd_hda_codec_write(codec, 0x20, 0,
14273 AC_VERB_SET_COEF_INDEX, 0x0c);
14274 snd_hda_codec_write(codec, 0x20, 0,
14275 AC_VERB_SET_PROC_COEF, 0x680);
14276
14277 snd_hda_codec_write(codec, 0x20, 0,
14278 AC_VERB_SET_COEF_INDEX, 0x0c);
14279 snd_hda_codec_write(codec, 0x20, 0,
14280 AC_VERB_SET_PROC_COEF, 0x480);
14281}
14282
64154835
TV
14283static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14284{
14285 unsigned int present_laptop;
14286 unsigned int present_dock;
14287
864f92be
WF
14288 present_laptop = snd_hda_jack_detect(codec, 0x18);
14289 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14290
14291 /* Laptop mic port overrides dock mic port, design decision */
14292 if (present_dock)
14293 snd_hda_codec_write(codec, 0x23, 0,
14294 AC_VERB_SET_CONNECT_SEL, 0x3);
14295 if (present_laptop)
14296 snd_hda_codec_write(codec, 0x23, 0,
14297 AC_VERB_SET_CONNECT_SEL, 0x0);
14298 if (!present_dock && !present_laptop)
14299 snd_hda_codec_write(codec, 0x23, 0,
14300 AC_VERB_SET_CONNECT_SEL, 0x1);
14301}
14302
60db6b53
KY
14303static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14304 unsigned int res)
14305{
4f5d1706
TI
14306 switch (res >> 26) {
14307 case ALC880_HP_EVENT:
60db6b53 14308 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14309 break;
14310 case ALC880_MIC_EVENT:
14311 alc_mic_automute(codec);
14312 break;
14313 }
60db6b53 14314}
f6a92248 14315
64154835
TV
14316static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14317 unsigned int res)
14318{
14319 if ((res >> 26) == ALC880_HP_EVENT)
14320 alc269_lifebook_speaker_automute(codec);
14321 if ((res >> 26) == ALC880_MIC_EVENT)
14322 alc269_lifebook_mic_autoswitch(codec);
14323}
14324
4f5d1706
TI
14325static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14326{
14327 struct alc_spec *spec = codec->spec;
20645d70
TI
14328 spec->autocfg.hp_pins[0] = 0x15;
14329 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14330 spec->ext_mic.pin = 0x18;
14331 spec->ext_mic.mux_idx = 0;
14332 spec->int_mic.pin = 0x19;
14333 spec->int_mic.mux_idx = 1;
14334 spec->auto_mic = 1;
14335}
14336
60db6b53
KY
14337static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14338{
14339 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14340 alc_mic_automute(codec);
60db6b53 14341}
f6a92248 14342
64154835
TV
14343static void alc269_lifebook_init_hook(struct hda_codec *codec)
14344{
14345 alc269_lifebook_speaker_automute(codec);
14346 alc269_lifebook_mic_autoswitch(codec);
14347}
14348
84898e87 14349static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14350 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14351 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14352 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14353 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14354 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14355 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14356 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14357 {}
14358};
14359
84898e87 14360static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14361 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14362 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14363 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14364 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14365 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14366 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14367 {}
14368};
14369
84898e87
KY
14370static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14371 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14372 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14373 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14374 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14375 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14376 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14377 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14378 {}
14379};
14380
14381static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14382 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14383 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14384 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14385 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14386 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14387 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14388 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14389 {}
14390};
14391
fe3eb0a7
KY
14392static struct hda_verb alc271_acer_dmic_verbs[] = {
14393 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14394 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14395 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14396 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14397 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14398 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14399 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14400 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14401 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14402 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14403 { }
14404};
14405
f53281e6
KY
14406/* toggle speaker-output according to the hp-jack state */
14407static void alc269_speaker_automute(struct hda_codec *codec)
14408{
ebb83eeb
KY
14409 struct alc_spec *spec = codec->spec;
14410 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 14411 unsigned int present;
60db6b53 14412 unsigned char bits;
f53281e6 14413
ebb83eeb 14414 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 14415 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 14416 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14417 HDA_AMP_MUTE, bits);
f53281e6 14418 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14419 HDA_AMP_MUTE, bits);
bf1b0225 14420 alc_report_jack(codec, nid);
f53281e6
KY
14421}
14422
f53281e6 14423/* unsolicited event for HP jack sensing */
84898e87 14424static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 14425 unsigned int res)
f53281e6 14426{
4f5d1706
TI
14427 switch (res >> 26) {
14428 case ALC880_HP_EVENT:
f53281e6 14429 alc269_speaker_automute(codec);
4f5d1706
TI
14430 break;
14431 case ALC880_MIC_EVENT:
14432 alc_mic_automute(codec);
14433 break;
14434 }
f53281e6
KY
14435}
14436
226b1ec8 14437static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14438{
4f5d1706 14439 struct alc_spec *spec = codec->spec;
20645d70
TI
14440 spec->autocfg.hp_pins[0] = 0x15;
14441 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14442 spec->ext_mic.pin = 0x18;
14443 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14444 spec->int_mic.pin = 0x19;
14445 spec->int_mic.mux_idx = 1;
4f5d1706 14446 spec->auto_mic = 1;
f53281e6
KY
14447}
14448
226b1ec8 14449static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14450{
14451 struct alc_spec *spec = codec->spec;
20645d70
TI
14452 spec->autocfg.hp_pins[0] = 0x15;
14453 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
14454 spec->ext_mic.pin = 0x18;
14455 spec->ext_mic.mux_idx = 0;
14456 spec->int_mic.pin = 0x12;
226b1ec8 14457 spec->int_mic.mux_idx = 5;
84898e87
KY
14458 spec->auto_mic = 1;
14459}
14460
226b1ec8 14461static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14462{
4f5d1706 14463 struct alc_spec *spec = codec->spec;
226b1ec8 14464 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14465 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14466 spec->ext_mic.pin = 0x18;
14467 spec->ext_mic.mux_idx = 0;
14468 spec->int_mic.pin = 0x19;
14469 spec->int_mic.mux_idx = 1;
14470 spec->auto_mic = 1;
f53281e6
KY
14471}
14472
226b1ec8
KY
14473static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14474{
14475 struct alc_spec *spec = codec->spec;
14476 spec->autocfg.hp_pins[0] = 0x21;
14477 spec->autocfg.speaker_pins[0] = 0x14;
14478 spec->ext_mic.pin = 0x18;
14479 spec->ext_mic.mux_idx = 0;
14480 spec->int_mic.pin = 0x12;
14481 spec->int_mic.mux_idx = 6;
14482 spec->auto_mic = 1;
14483}
14484
84898e87 14485static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
14486{
14487 alc269_speaker_automute(codec);
4f5d1706 14488 alc_mic_automute(codec);
f53281e6
KY
14489}
14490
60db6b53
KY
14491/*
14492 * generic initialization of ADC, input mixers and output mixers
14493 */
14494static struct hda_verb alc269_init_verbs[] = {
14495 /*
14496 * Unmute ADC0 and set the default input to mic-in
14497 */
84898e87 14498 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14499
14500 /*
84898e87 14501 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14502 */
14503 /* set vol=0 to output mixers */
14504 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14505 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14506
14507 /* set up input amps for analog loopback */
14508 /* Amp Indices: DAC = 0, mixer = 1 */
14509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14510 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14511 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14512 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14513 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14514 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14515
14516 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14517 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14518 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14519 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14520 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14521 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14522 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14523
14524 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14525 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14526
84898e87
KY
14527 /* FIXME: use Mux-type input source selection */
14528 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14529 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14530 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14531
84898e87
KY
14532 /* set EAPD */
14533 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14534 { }
14535};
14536
14537static struct hda_verb alc269vb_init_verbs[] = {
14538 /*
14539 * Unmute ADC0 and set the default input to mic-in
14540 */
14541 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14542
14543 /*
14544 * Set up output mixers (0x02 - 0x03)
14545 */
14546 /* set vol=0 to output mixers */
14547 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14548 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14549
14550 /* set up input amps for analog loopback */
14551 /* Amp Indices: DAC = 0, mixer = 1 */
14552 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14553 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14554 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14555 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14556 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14557 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14558
14559 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14560 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14561 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14562 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14563 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14564 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14565 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14566
14567 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14568 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14569
14570 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14571 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14572 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14573 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14574
14575 /* set EAPD */
14576 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14577 { }
14578};
14579
9d0b71b1
TI
14580#define alc269_auto_create_multi_out_ctls \
14581 alc268_auto_create_multi_out_ctls
05f5f477
TI
14582#define alc269_auto_create_input_ctls \
14583 alc268_auto_create_input_ctls
f6a92248
KY
14584
14585#ifdef CONFIG_SND_HDA_POWER_SAVE
14586#define alc269_loopbacks alc880_loopbacks
14587#endif
14588
def319f9 14589/* pcm configuration: identical with ALC880 */
f6a92248
KY
14590#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14591#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14592#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14593#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14594
f03d3115
TI
14595static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14596 .substreams = 1,
14597 .channels_min = 2,
14598 .channels_max = 8,
14599 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14600 /* NID is set in alc_build_pcms */
14601 .ops = {
14602 .open = alc880_playback_pcm_open,
14603 .prepare = alc880_playback_pcm_prepare,
14604 .cleanup = alc880_playback_pcm_cleanup
14605 },
14606};
14607
14608static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14609 .substreams = 1,
14610 .channels_min = 2,
14611 .channels_max = 2,
14612 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14613 /* NID is set in alc_build_pcms */
14614};
14615
ad35879a
TI
14616#ifdef CONFIG_SND_HDA_POWER_SAVE
14617static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14618{
14619 switch (codec->subsystem_id) {
14620 case 0x103c1586:
14621 return 1;
14622 }
14623 return 0;
14624}
14625
14626static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14627{
14628 /* update mute-LED according to the speaker mute state */
14629 if (nid == 0x01 || nid == 0x14) {
14630 int pinval;
14631 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14632 HDA_AMP_MUTE)
14633 pinval = 0x24;
14634 else
14635 pinval = 0x20;
14636 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14637 snd_hda_codec_update_cache(codec, 0x19, 0,
14638 AC_VERB_SET_PIN_WIDGET_CONTROL,
14639 pinval);
ad35879a
TI
14640 }
14641 return alc_check_power_status(codec, nid);
14642}
14643#endif /* CONFIG_SND_HDA_POWER_SAVE */
14644
840b64c0
TI
14645static int alc275_setup_dual_adc(struct hda_codec *codec)
14646{
14647 struct alc_spec *spec = codec->spec;
14648
14649 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14650 return 0;
14651 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14652 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14653 if (spec->ext_mic.pin <= 0x12) {
14654 spec->private_adc_nids[0] = 0x08;
14655 spec->private_adc_nids[1] = 0x11;
14656 spec->private_capsrc_nids[0] = 0x23;
14657 spec->private_capsrc_nids[1] = 0x22;
14658 } else {
14659 spec->private_adc_nids[0] = 0x11;
14660 spec->private_adc_nids[1] = 0x08;
14661 spec->private_capsrc_nids[0] = 0x22;
14662 spec->private_capsrc_nids[1] = 0x23;
14663 }
14664 spec->adc_nids = spec->private_adc_nids;
14665 spec->capsrc_nids = spec->private_capsrc_nids;
14666 spec->num_adc_nids = 2;
14667 spec->dual_adc_switch = 1;
14668 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14669 spec->adc_nids[0], spec->adc_nids[1]);
14670 return 1;
14671 }
14672 return 0;
14673}
14674
d433a678
TI
14675/* different alc269-variants */
14676enum {
14677 ALC269_TYPE_NORMAL,
48c88e82 14678 ALC269_TYPE_ALC258,
d433a678 14679 ALC269_TYPE_ALC259,
48c88e82
KY
14680 ALC269_TYPE_ALC269VB,
14681 ALC269_TYPE_ALC270,
d433a678
TI
14682 ALC269_TYPE_ALC271X,
14683};
14684
f6a92248
KY
14685/*
14686 * BIOS auto configuration
14687 */
14688static int alc269_parse_auto_config(struct hda_codec *codec)
14689{
14690 struct alc_spec *spec = codec->spec;
cfb9fb55 14691 int err;
f6a92248
KY
14692 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14693
14694 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14695 alc269_ignore);
14696 if (err < 0)
14697 return err;
14698
14699 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14700 if (err < 0)
14701 return err;
f3550d1b
TI
14702 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14703 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14704 else
14705 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14706 0x22, 0);
f6a92248
KY
14707 if (err < 0)
14708 return err;
14709
14710 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14711
757899ac 14712 alc_auto_parse_digital(codec);
f6a92248 14713
603c4019 14714 if (spec->kctls.list)
d88897ea 14715 add_mixer(spec, spec->kctls.list);
f6a92248 14716
d433a678 14717 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
84898e87 14718 add_verb(spec, alc269vb_init_verbs);
6227cdce 14719 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14720 } else {
14721 add_verb(spec, alc269_init_verbs);
6227cdce 14722 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14723 }
14724
f6a92248 14725 spec->num_mux_defs = 1;
61b9b9b1 14726 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14727
14728 if (!alc275_setup_dual_adc(codec))
14729 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14730 sizeof(alc269_adc_candidates));
6694635d 14731
e01bf509 14732 /* set default input source */
840b64c0 14733 if (!spec->dual_adc_switch)
748cce43
TI
14734 select_or_unmute_capsrc(codec, spec->capsrc_nids[0],
14735 spec->input_mux->items[0].index);
f6a92248
KY
14736
14737 err = alc_auto_add_mic_boost(codec);
14738 if (err < 0)
14739 return err;
14740
7e0e44d4 14741 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14742 set_capture_mixer(codec);
f53281e6 14743
f6a92248
KY
14744 return 1;
14745}
14746
e9af4f36
TI
14747#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14748#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14749#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14750
14751
14752/* init callback for auto-configuration model -- overriding the default init */
14753static void alc269_auto_init(struct hda_codec *codec)
14754{
f6c7e546 14755 struct alc_spec *spec = codec->spec;
f6a92248
KY
14756 alc269_auto_init_multi_out(codec);
14757 alc269_auto_init_hp_out(codec);
14758 alc269_auto_init_analog_input(codec);
757899ac 14759 alc_auto_init_digital(codec);
f6c7e546 14760 if (spec->unsol_event)
7fb0d78f 14761 alc_inithook(codec);
f6a92248
KY
14762}
14763
0ec33d1f
TI
14764#ifdef SND_HDA_NEEDS_RESUME
14765static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14766{
14767 int val = alc_read_coef_idx(codec, 0x04);
14768 if (power_up)
14769 val |= 1 << 11;
14770 else
14771 val &= ~(1 << 11);
14772 alc_write_coef_idx(codec, 0x04, val);
14773}
14774
977ddd6b
KY
14775#ifdef CONFIG_SND_HDA_POWER_SAVE
14776static int alc269_suspend(struct hda_codec *codec, pm_message_t state)
14777{
14778 struct alc_spec *spec = codec->spec;
977ddd6b 14779
0ec33d1f
TI
14780 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14781 alc269_toggle_power_output(codec, 0);
977ddd6b 14782 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14783 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14784 msleep(150);
14785 }
14786
14787 alc_shutup(codec);
14788 if (spec && spec->power_hook)
14789 spec->power_hook(codec);
14790 return 0;
14791}
0ec33d1f
TI
14792#endif /* CONFIG_SND_HDA_POWER_SAVE */
14793
977ddd6b
KY
14794static int alc269_resume(struct hda_codec *codec)
14795{
977ddd6b 14796 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14797 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14798 msleep(150);
14799 }
14800
14801 codec->patch_ops.init(codec);
14802
14803 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14804 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14805 msleep(200);
14806 }
14807
0ec33d1f
TI
14808 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14809 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14810
14811 snd_hda_codec_resume_amp(codec);
14812 snd_hda_codec_resume_cache(codec);
9e5341b9 14813 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14814 return 0;
14815}
0ec33d1f 14816#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14817
ff818c24
TI
14818enum {
14819 ALC269_FIXUP_SONY_VAIO,
2785591a 14820 ALC275_FIX_SONY_VAIO_GPIO2,
145a902b 14821 ALC269_FIXUP_DELL_M101Z,
022c92be 14822 ALC269_FIXUP_SKU_IGNORE,
ac612407 14823 ALC269_FIXUP_ASUS_G73JW,
ff818c24
TI
14824};
14825
ff818c24
TI
14826static const struct alc_fixup alc269_fixups[] = {
14827 [ALC269_FIXUP_SONY_VAIO] = {
73413b12
TI
14828 .verbs = (const struct hda_verb[]) {
14829 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14830 {}
14831 }
ff818c24 14832 },
2785591a
KY
14833 [ALC275_FIX_SONY_VAIO_GPIO2] = {
14834 .verbs = (const struct hda_verb[]) {
14835 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14836 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14837 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14838 { }
14839 }
14840 },
145a902b
DH
14841 [ALC269_FIXUP_DELL_M101Z] = {
14842 .verbs = (const struct hda_verb[]) {
14843 /* Enables internal speaker */
14844 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14845 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14846 {}
14847 }
14848 },
022c92be 14849 [ALC269_FIXUP_SKU_IGNORE] = {
fe67b240
DH
14850 .sku = ALC_FIXUP_SKU_IGNORE,
14851 },
ac612407
DH
14852 [ALC269_FIXUP_ASUS_G73JW] = {
14853 .pins = (const struct alc_pincfg[]) {
14854 { 0x17, 0x99130111 }, /* subwoofer */
14855 { }
14856 }
14857 },
ff818c24
TI
14858};
14859
14860static struct snd_pci_quirk alc269_fixup_tbl[] = {
2785591a
KY
14861 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2),
14862 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2),
14863 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2),
abdd8f51 14864 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14865 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
022c92be
DH
14866 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14867 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
ac612407 14868 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
ff818c24
TI
14869 {}
14870};
14871
14872
f6a92248
KY
14873/*
14874 * configuration and preset
14875 */
14876static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14877 [ALC269_BASIC] = "basic",
2922c9af 14878 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14879 [ALC269_AMIC] = "laptop-amic",
14880 [ALC269_DMIC] = "laptop-dmic",
64154835 14881 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14882 [ALC269_LIFEBOOK] = "lifebook",
14883 [ALC269_AUTO] = "auto",
f6a92248
KY
14884};
14885
14886static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14887 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14888 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14889 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14890 ALC269_AMIC),
14891 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14892 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14893 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14894 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14895 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14896 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14897 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14898 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14899 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14900 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14901 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14902 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14903 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14904 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14905 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14906 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14907 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14908 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14909 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14910 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14911 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14912 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14913 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14914 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14915 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14916 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14917 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14918 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14919 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14920 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14921 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14922 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14923 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14924 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14925 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14926 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14927 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14928 ALC269_DMIC),
60db6b53 14929 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14930 ALC269_DMIC),
14931 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14932 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14933 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14934 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14935 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14936 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14937 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14938 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14939 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14940 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14941 {}
14942};
14943
14944static struct alc_config_preset alc269_presets[] = {
14945 [ALC269_BASIC] = {
f9e336f6 14946 .mixers = { alc269_base_mixer },
f6a92248
KY
14947 .init_verbs = { alc269_init_verbs },
14948 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14949 .dac_nids = alc269_dac_nids,
14950 .hp_nid = 0x03,
14951 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14952 .channel_mode = alc269_modes,
14953 .input_mux = &alc269_capture_source,
14954 },
60db6b53
KY
14955 [ALC269_QUANTA_FL1] = {
14956 .mixers = { alc269_quanta_fl1_mixer },
14957 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14958 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14959 .dac_nids = alc269_dac_nids,
14960 .hp_nid = 0x03,
14961 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14962 .channel_mode = alc269_modes,
14963 .input_mux = &alc269_capture_source,
14964 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 14965 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
14966 .init_hook = alc269_quanta_fl1_init_hook,
14967 },
84898e87
KY
14968 [ALC269_AMIC] = {
14969 .mixers = { alc269_laptop_mixer },
14970 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 14971 .init_verbs = { alc269_init_verbs,
84898e87 14972 alc269_laptop_amic_init_verbs },
f53281e6
KY
14973 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14974 .dac_nids = alc269_dac_nids,
14975 .hp_nid = 0x03,
14976 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14977 .channel_mode = alc269_modes,
84898e87
KY
14978 .unsol_event = alc269_laptop_unsol_event,
14979 .setup = alc269_laptop_amic_setup,
14980 .init_hook = alc269_laptop_inithook,
f53281e6 14981 },
84898e87
KY
14982 [ALC269_DMIC] = {
14983 .mixers = { alc269_laptop_mixer },
14984 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 14985 .init_verbs = { alc269_init_verbs,
84898e87
KY
14986 alc269_laptop_dmic_init_verbs },
14987 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14988 .dac_nids = alc269_dac_nids,
14989 .hp_nid = 0x03,
14990 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14991 .channel_mode = alc269_modes,
14992 .unsol_event = alc269_laptop_unsol_event,
14993 .setup = alc269_laptop_dmic_setup,
14994 .init_hook = alc269_laptop_inithook,
14995 },
14996 [ALC269VB_AMIC] = {
14997 .mixers = { alc269vb_laptop_mixer },
14998 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14999 .init_verbs = { alc269vb_init_verbs,
15000 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
15001 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15002 .dac_nids = alc269_dac_nids,
15003 .hp_nid = 0x03,
15004 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15005 .channel_mode = alc269_modes,
84898e87 15006 .unsol_event = alc269_laptop_unsol_event,
226b1ec8 15007 .setup = alc269vb_laptop_amic_setup,
84898e87
KY
15008 .init_hook = alc269_laptop_inithook,
15009 },
15010 [ALC269VB_DMIC] = {
15011 .mixers = { alc269vb_laptop_mixer },
15012 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15013 .init_verbs = { alc269vb_init_verbs,
15014 alc269vb_laptop_dmic_init_verbs },
15015 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15016 .dac_nids = alc269_dac_nids,
15017 .hp_nid = 0x03,
15018 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15019 .channel_mode = alc269_modes,
15020 .unsol_event = alc269_laptop_unsol_event,
15021 .setup = alc269vb_laptop_dmic_setup,
15022 .init_hook = alc269_laptop_inithook,
f53281e6 15023 },
26f5df26 15024 [ALC269_FUJITSU] = {
45bdd1c1 15025 .mixers = { alc269_fujitsu_mixer },
84898e87 15026 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 15027 .init_verbs = { alc269_init_verbs,
84898e87 15028 alc269_laptop_dmic_init_verbs },
26f5df26
TI
15029 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15030 .dac_nids = alc269_dac_nids,
15031 .hp_nid = 0x03,
15032 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15033 .channel_mode = alc269_modes,
84898e87
KY
15034 .unsol_event = alc269_laptop_unsol_event,
15035 .setup = alc269_laptop_dmic_setup,
15036 .init_hook = alc269_laptop_inithook,
26f5df26 15037 },
64154835
TV
15038 [ALC269_LIFEBOOK] = {
15039 .mixers = { alc269_lifebook_mixer },
15040 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15041 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15042 .dac_nids = alc269_dac_nids,
15043 .hp_nid = 0x03,
15044 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15045 .channel_mode = alc269_modes,
15046 .input_mux = &alc269_capture_source,
15047 .unsol_event = alc269_lifebook_unsol_event,
15048 .init_hook = alc269_lifebook_init_hook,
15049 },
fe3eb0a7
KY
15050 [ALC271_ACER] = {
15051 .mixers = { alc269_asus_mixer },
15052 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15053 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15054 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15055 .dac_nids = alc269_dac_nids,
15056 .adc_nids = alc262_dmic_adc_nids,
15057 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15058 .capsrc_nids = alc262_dmic_capsrc_nids,
15059 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15060 .channel_mode = alc269_modes,
15061 .input_mux = &alc269_capture_source,
15062 .dig_out_nid = ALC880_DIGOUT_NID,
15063 .unsol_event = alc_sku_unsol_event,
15064 .setup = alc269vb_laptop_dmic_setup,
15065 .init_hook = alc_inithook,
15066 },
f6a92248
KY
15067};
15068
977ddd6b
KY
15069static int alc269_fill_coef(struct hda_codec *codec)
15070{
15071 int val;
15072
15073 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15074 alc_write_coef_idx(codec, 0xf, 0x960b);
15075 alc_write_coef_idx(codec, 0xe, 0x8817);
15076 }
15077
15078 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15079 alc_write_coef_idx(codec, 0xf, 0x960b);
15080 alc_write_coef_idx(codec, 0xe, 0x8814);
15081 }
15082
15083 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15084 val = alc_read_coef_idx(codec, 0x04);
15085 /* Power up output pin */
15086 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15087 }
15088
15089 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15090 val = alc_read_coef_idx(codec, 0xd);
15091 if ((val & 0x0c00) >> 10 != 0x1) {
15092 /* Capless ramp up clock control */
15093 alc_write_coef_idx(codec, 0xd, val | 1<<10);
15094 }
15095 val = alc_read_coef_idx(codec, 0x17);
15096 if ((val & 0x01c0) >> 6 != 0x4) {
15097 /* Class D power on reset */
15098 alc_write_coef_idx(codec, 0x17, val | 1<<7);
15099 }
15100 }
15101 return 0;
15102}
15103
f6a92248
KY
15104static int patch_alc269(struct hda_codec *codec)
15105{
15106 struct alc_spec *spec;
48c88e82 15107 int board_config, coef;
f6a92248
KY
15108 int err;
15109
15110 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15111 if (spec == NULL)
15112 return -ENOMEM;
15113
15114 codec->spec = spec;
15115
da00c244
KY
15116 alc_auto_parse_customize_define(codec);
15117
c793bec5
KY
15118 if (codec->vendor_id == 0x10ec0269) {
15119 coef = alc_read_coef_idx(codec, 0);
15120 if ((coef & 0x00f0) == 0x0010) {
15121 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15122 spec->cdefine.platform_type == 1) {
15123 alc_codec_rename(codec, "ALC271X");
15124 spec->codec_variant = ALC269_TYPE_ALC271X;
15125 } else if ((coef & 0xf000) == 0x1000) {
15126 spec->codec_variant = ALC269_TYPE_ALC270;
15127 } else if ((coef & 0xf000) == 0x2000) {
15128 alc_codec_rename(codec, "ALC259");
15129 spec->codec_variant = ALC269_TYPE_ALC259;
15130 } else if ((coef & 0xf000) == 0x3000) {
15131 alc_codec_rename(codec, "ALC258");
15132 spec->codec_variant = ALC269_TYPE_ALC258;
15133 } else {
15134 alc_codec_rename(codec, "ALC269VB");
15135 spec->codec_variant = ALC269_TYPE_ALC269VB;
15136 }
15137 } else
15138 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15139 alc269_fill_coef(codec);
15140 }
977ddd6b 15141
f6a92248
KY
15142 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15143 alc269_models,
15144 alc269_cfg_tbl);
15145
15146 if (board_config < 0) {
9a11f1aa
TI
15147 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15148 codec->chip_name);
f6a92248
KY
15149 board_config = ALC269_AUTO;
15150 }
15151
ff818c24
TI
15152 if (board_config == ALC269_AUTO)
15153 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
15154
f6a92248
KY
15155 if (board_config == ALC269_AUTO) {
15156 /* automatic parse from the BIOS config */
15157 err = alc269_parse_auto_config(codec);
15158 if (err < 0) {
15159 alc_free(codec);
15160 return err;
15161 } else if (!err) {
15162 printk(KERN_INFO
15163 "hda_codec: Cannot set up configuration "
15164 "from BIOS. Using base mode...\n");
15165 board_config = ALC269_BASIC;
15166 }
15167 }
15168
dc1eae25 15169 if (has_cdefine_beep(codec)) {
8af2591d
TI
15170 err = snd_hda_attach_beep_device(codec, 0x1);
15171 if (err < 0) {
15172 alc_free(codec);
15173 return err;
15174 }
680cd536
KK
15175 }
15176
f6a92248 15177 if (board_config != ALC269_AUTO)
e9c364c0 15178 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15179
84898e87 15180 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15181 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15182 * fix the sample rate of analog I/O to 44.1kHz
15183 */
15184 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15185 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15186 } else if (spec->dual_adc_switch) {
15187 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15188 /* switch ADC dynamically */
15189 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15190 } else {
15191 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15192 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15193 }
f6a92248
KY
15194 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15195 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15196
6694635d 15197 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
1657cbd8 15198 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
6694635d
TI
15199 spec->adc_nids = alc269_adc_nids;
15200 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15201 spec->capsrc_nids = alc269_capsrc_nids;
15202 } else {
15203 spec->adc_nids = alc269vb_adc_nids;
15204 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15205 spec->capsrc_nids = alc269vb_capsrc_nids;
15206 }
84898e87
KY
15207 }
15208
f9e336f6 15209 if (!spec->cap_mixer)
b59bdf3b 15210 set_capture_mixer(codec);
dc1eae25 15211 if (has_cdefine_beep(codec))
da00c244 15212 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15213
ff818c24
TI
15214 if (board_config == ALC269_AUTO)
15215 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
15216
100d5eb3
TI
15217 spec->vmaster_nid = 0x02;
15218
f6a92248 15219 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15220#ifdef CONFIG_SND_HDA_POWER_SAVE
15221 codec->patch_ops.suspend = alc269_suspend;
15222#endif
15223#ifdef SND_HDA_NEEDS_RESUME
15224 codec->patch_ops.resume = alc269_resume;
15225#endif
f6a92248
KY
15226 if (board_config == ALC269_AUTO)
15227 spec->init_hook = alc269_auto_init;
bf1b0225
KY
15228
15229 alc_init_jacks(codec);
f6a92248
KY
15230#ifdef CONFIG_SND_HDA_POWER_SAVE
15231 if (!spec->loopback.amplist)
15232 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15233 if (alc269_mic2_for_mute_led(codec))
15234 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15235#endif
15236
15237 return 0;
15238}
15239
df694daa
KY
15240/*
15241 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15242 */
15243
15244/*
15245 * set the path ways for 2 channel output
15246 * need to set the codec line out and mic 1 pin widgets to inputs
15247 */
15248static struct hda_verb alc861_threestack_ch2_init[] = {
15249 /* set pin widget 1Ah (line in) for input */
15250 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15251 /* set pin widget 18h (mic1/2) for input, for mic also enable
15252 * the vref
15253 */
df694daa
KY
15254 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15255
9c7f852e
TI
15256 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15257#if 0
15258 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15259 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15260#endif
df694daa
KY
15261 { } /* end */
15262};
15263/*
15264 * 6ch mode
15265 * need to set the codec line out and mic 1 pin widgets to outputs
15266 */
15267static struct hda_verb alc861_threestack_ch6_init[] = {
15268 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15269 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15270 /* set pin widget 18h (mic1) for output (CLFE)*/
15271 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15272
15273 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15274 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15275
9c7f852e
TI
15276 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15277#if 0
15278 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15279 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15280#endif
df694daa
KY
15281 { } /* end */
15282};
15283
15284static struct hda_channel_mode alc861_threestack_modes[2] = {
15285 { 2, alc861_threestack_ch2_init },
15286 { 6, alc861_threestack_ch6_init },
15287};
22309c3e
TI
15288/* Set mic1 as input and unmute the mixer */
15289static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15290 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15291 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15292 { } /* end */
15293};
15294/* Set mic1 as output and mute mixer */
15295static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15296 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15297 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15298 { } /* end */
15299};
15300
15301static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15302 { 2, alc861_uniwill_m31_ch2_init },
15303 { 4, alc861_uniwill_m31_ch4_init },
15304};
df694daa 15305
7cdbff94
MD
15306/* Set mic1 and line-in as input and unmute the mixer */
15307static struct hda_verb alc861_asus_ch2_init[] = {
15308 /* set pin widget 1Ah (line in) for input */
15309 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15310 /* set pin widget 18h (mic1/2) for input, for mic also enable
15311 * the vref
15312 */
7cdbff94
MD
15313 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15314
15315 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15316#if 0
15317 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15318 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15319#endif
15320 { } /* end */
15321};
15322/* Set mic1 nad line-in as output and mute mixer */
15323static struct hda_verb alc861_asus_ch6_init[] = {
15324 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15325 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15326 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15327 /* set pin widget 18h (mic1) for output (CLFE)*/
15328 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15329 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15330 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15331 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15332
15333 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15334#if 0
15335 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15336 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15337#endif
15338 { } /* end */
15339};
15340
15341static struct hda_channel_mode alc861_asus_modes[2] = {
15342 { 2, alc861_asus_ch2_init },
15343 { 6, alc861_asus_ch6_init },
15344};
15345
df694daa
KY
15346/* patch-ALC861 */
15347
15348static struct snd_kcontrol_new alc861_base_mixer[] = {
15349 /* output mixer control */
15350 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15351 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15352 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15353 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15354 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15355
15356 /*Input mixer control */
15357 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15358 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15359 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15360 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15361 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15362 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15363 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15364 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15365 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15366 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15367
df694daa
KY
15368 { } /* end */
15369};
15370
15371static struct snd_kcontrol_new alc861_3ST_mixer[] = {
15372 /* output mixer control */
15373 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15374 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15375 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15376 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15377 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15378
15379 /* Input mixer control */
15380 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15381 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15382 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15383 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15384 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15385 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15386 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15387 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15388 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15389 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15390
df694daa
KY
15391 {
15392 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15393 .name = "Channel Mode",
15394 .info = alc_ch_mode_info,
15395 .get = alc_ch_mode_get,
15396 .put = alc_ch_mode_put,
15397 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15398 },
15399 { } /* end */
a53d1aec
TD
15400};
15401
d1d985f0 15402static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15403 /* output mixer control */
15404 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15405 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15406 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15407
a53d1aec 15408 { } /* end */
f12ab1e0 15409};
a53d1aec 15410
22309c3e
TI
15411static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15412 /* output mixer control */
15413 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15414 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15415 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15416 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15417 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15418
15419 /* Input mixer control */
15420 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15421 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15422 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15423 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15424 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15425 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15426 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15427 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15428 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15429 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15430
22309c3e
TI
15431 {
15432 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15433 .name = "Channel Mode",
15434 .info = alc_ch_mode_info,
15435 .get = alc_ch_mode_get,
15436 .put = alc_ch_mode_put,
15437 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15438 },
15439 { } /* end */
f12ab1e0 15440};
7cdbff94
MD
15441
15442static struct snd_kcontrol_new alc861_asus_mixer[] = {
15443 /* output mixer control */
15444 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15445 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15446 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15447 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15448 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15449
15450 /* Input mixer control */
15451 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15452 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15453 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15454 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15455 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15456 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15457 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15458 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15459 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15460 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15461
7cdbff94
MD
15462 {
15463 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15464 .name = "Channel Mode",
15465 .info = alc_ch_mode_info,
15466 .get = alc_ch_mode_get,
15467 .put = alc_ch_mode_put,
15468 .private_value = ARRAY_SIZE(alc861_asus_modes),
15469 },
15470 { }
56bb0cab
TI
15471};
15472
15473/* additional mixer */
d1d985f0 15474static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15475 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15476 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15477 { }
15478};
7cdbff94 15479
df694daa
KY
15480/*
15481 * generic initialization of ADC, input mixers and output mixers
15482 */
15483static struct hda_verb alc861_base_init_verbs[] = {
15484 /*
15485 * Unmute ADC0 and set the default input to mic-in
15486 */
15487 /* port-A for surround (rear panel) */
15488 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15489 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15490 /* port-B for mic-in (rear panel) with vref */
15491 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15492 /* port-C for line-in (rear panel) */
15493 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15494 /* port-D for Front */
15495 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15496 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15497 /* port-E for HP out (front panel) */
15498 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15499 /* route front PCM to HP */
9dece1d7 15500 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15501 /* port-F for mic-in (front panel) with vref */
15502 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15503 /* port-G for CLFE (rear panel) */
15504 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15505 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15506 /* port-H for side (rear panel) */
15507 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15508 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15509 /* CD-in */
15510 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15511 /* route front mic to ADC1*/
15512 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15513 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15514
df694daa
KY
15515 /* Unmute DAC0~3 & spdif out*/
15516 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15517 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15518 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15519 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15520 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15521
df694daa
KY
15522 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15523 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15524 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15525 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15526 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15527
df694daa
KY
15528 /* Unmute Stereo Mixer 15 */
15529 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15530 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15531 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15532 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15533
15534 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15535 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15536 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15537 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15538 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15539 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15540 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15541 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15542 /* hp used DAC 3 (Front) */
15543 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15544 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15545
15546 { }
15547};
15548
15549static struct hda_verb alc861_threestack_init_verbs[] = {
15550 /*
15551 * Unmute ADC0 and set the default input to mic-in
15552 */
15553 /* port-A for surround (rear panel) */
15554 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15555 /* port-B for mic-in (rear panel) with vref */
15556 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15557 /* port-C for line-in (rear panel) */
15558 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15559 /* port-D for Front */
15560 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15561 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15562 /* port-E for HP out (front panel) */
15563 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15564 /* route front PCM to HP */
9dece1d7 15565 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15566 /* port-F for mic-in (front panel) with vref */
15567 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15568 /* port-G for CLFE (rear panel) */
15569 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15570 /* port-H for side (rear panel) */
15571 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15572 /* CD-in */
15573 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15574 /* route front mic to ADC1*/
15575 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15576 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15577 /* Unmute DAC0~3 & spdif out*/
15578 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15579 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15580 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15581 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15582 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15583
df694daa
KY
15584 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15585 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15586 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15587 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15588 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15589
df694daa
KY
15590 /* Unmute Stereo Mixer 15 */
15591 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15592 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15593 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15594 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15595
15596 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15597 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15598 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15599 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15600 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15601 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15602 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15603 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15604 /* hp used DAC 3 (Front) */
15605 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15606 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15607 { }
15608};
22309c3e
TI
15609
15610static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15611 /*
15612 * Unmute ADC0 and set the default input to mic-in
15613 */
15614 /* port-A for surround (rear panel) */
15615 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15616 /* port-B for mic-in (rear panel) with vref */
15617 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15618 /* port-C for line-in (rear panel) */
15619 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15620 /* port-D for Front */
15621 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15622 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15623 /* port-E for HP out (front panel) */
f12ab1e0
TI
15624 /* this has to be set to VREF80 */
15625 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15626 /* route front PCM to HP */
9dece1d7 15627 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15628 /* port-F for mic-in (front panel) with vref */
15629 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15630 /* port-G for CLFE (rear panel) */
15631 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15632 /* port-H for side (rear panel) */
15633 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15634 /* CD-in */
15635 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15636 /* route front mic to ADC1*/
15637 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15638 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15639 /* Unmute DAC0~3 & spdif out*/
15640 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15641 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15642 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15643 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15644 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15645
22309c3e
TI
15646 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15647 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15648 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15649 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15650 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15651
22309c3e
TI
15652 /* Unmute Stereo Mixer 15 */
15653 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15654 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15655 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15656 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15657
15658 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15659 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15660 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15661 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15662 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15663 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15664 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15665 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15666 /* hp used DAC 3 (Front) */
15667 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15668 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15669 { }
15670};
15671
7cdbff94
MD
15672static struct hda_verb alc861_asus_init_verbs[] = {
15673 /*
15674 * Unmute ADC0 and set the default input to mic-in
15675 */
f12ab1e0
TI
15676 /* port-A for surround (rear panel)
15677 * according to codec#0 this is the HP jack
15678 */
7cdbff94
MD
15679 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15680 /* route front PCM to HP */
15681 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15682 /* port-B for mic-in (rear panel) with vref */
15683 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15684 /* port-C for line-in (rear panel) */
15685 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15686 /* port-D for Front */
15687 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15688 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15689 /* port-E for HP out (front panel) */
f12ab1e0
TI
15690 /* this has to be set to VREF80 */
15691 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15692 /* route front PCM to HP */
9dece1d7 15693 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15694 /* port-F for mic-in (front panel) with vref */
15695 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15696 /* port-G for CLFE (rear panel) */
15697 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15698 /* port-H for side (rear panel) */
15699 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15700 /* CD-in */
15701 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15702 /* route front mic to ADC1*/
15703 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15704 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15705 /* Unmute DAC0~3 & spdif out*/
15706 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15707 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15708 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15709 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15710 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15711 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15712 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15713 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15714 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15715 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15716
7cdbff94
MD
15717 /* Unmute Stereo Mixer 15 */
15718 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15719 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15720 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15721 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15722
15723 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15724 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15725 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15726 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15727 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15728 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15729 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15730 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15731 /* hp used DAC 3 (Front) */
15732 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15733 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15734 { }
15735};
15736
56bb0cab
TI
15737/* additional init verbs for ASUS laptops */
15738static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15739 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15740 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15741 { }
15742};
7cdbff94 15743
df694daa
KY
15744/*
15745 * generic initialization of ADC, input mixers and output mixers
15746 */
15747static struct hda_verb alc861_auto_init_verbs[] = {
15748 /*
15749 * Unmute ADC0 and set the default input to mic-in
15750 */
f12ab1e0 15751 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15752 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15753
df694daa
KY
15754 /* Unmute DAC0~3 & spdif out*/
15755 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15756 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15757 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15758 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15759 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15760
df694daa
KY
15761 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15762 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15763 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15764 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15765 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15766
df694daa
KY
15767 /* Unmute Stereo Mixer 15 */
15768 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15769 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15770 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15771 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15772
1c20930a
TI
15773 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15774 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15775 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15776 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15777 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15778 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15779 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15780 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15781
15782 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15783 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15784 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15785 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15786 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15787 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15788 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15789 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15790
f12ab1e0 15791 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15792
15793 { }
15794};
15795
a53d1aec
TD
15796static struct hda_verb alc861_toshiba_init_verbs[] = {
15797 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15798
a53d1aec
TD
15799 { }
15800};
15801
15802/* toggle speaker-output according to the hp-jack state */
15803static void alc861_toshiba_automute(struct hda_codec *codec)
15804{
864f92be 15805 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15806
47fd830a
TI
15807 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15808 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15809 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15810 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15811}
15812
15813static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15814 unsigned int res)
15815{
a53d1aec
TD
15816 if ((res >> 26) == ALC880_HP_EVENT)
15817 alc861_toshiba_automute(codec);
15818}
15819
def319f9 15820/* pcm configuration: identical with ALC880 */
df694daa
KY
15821#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15822#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15823#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15824#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15825
15826
15827#define ALC861_DIGOUT_NID 0x07
15828
15829static struct hda_channel_mode alc861_8ch_modes[1] = {
15830 { 8, NULL }
15831};
15832
15833static hda_nid_t alc861_dac_nids[4] = {
15834 /* front, surround, clfe, side */
15835 0x03, 0x06, 0x05, 0x04
15836};
15837
9c7f852e
TI
15838static hda_nid_t alc660_dac_nids[3] = {
15839 /* front, clfe, surround */
15840 0x03, 0x05, 0x06
15841};
15842
df694daa
KY
15843static hda_nid_t alc861_adc_nids[1] = {
15844 /* ADC0-2 */
15845 0x08,
15846};
15847
15848static struct hda_input_mux alc861_capture_source = {
15849 .num_items = 5,
15850 .items = {
15851 { "Mic", 0x0 },
15852 { "Front Mic", 0x3 },
15853 { "Line", 0x1 },
15854 { "CD", 0x4 },
15855 { "Mixer", 0x5 },
15856 },
15857};
15858
1c20930a
TI
15859static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15860{
15861 struct alc_spec *spec = codec->spec;
15862 hda_nid_t mix, srcs[5];
15863 int i, j, num;
15864
15865 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15866 return 0;
15867 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15868 if (num < 0)
15869 return 0;
15870 for (i = 0; i < num; i++) {
15871 unsigned int type;
a22d543a 15872 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15873 if (type != AC_WID_AUD_OUT)
15874 continue;
15875 for (j = 0; j < spec->multiout.num_dacs; j++)
15876 if (spec->multiout.dac_nids[j] == srcs[i])
15877 break;
15878 if (j >= spec->multiout.num_dacs)
15879 return srcs[i];
15880 }
15881 return 0;
15882}
15883
df694daa 15884/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15885static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15886 const struct auto_pin_cfg *cfg)
df694daa 15887{
1c20930a 15888 struct alc_spec *spec = codec->spec;
df694daa 15889 int i;
1c20930a 15890 hda_nid_t nid, dac;
df694daa
KY
15891
15892 spec->multiout.dac_nids = spec->private_dac_nids;
15893 for (i = 0; i < cfg->line_outs; i++) {
15894 nid = cfg->line_out_pins[i];
1c20930a
TI
15895 dac = alc861_look_for_dac(codec, nid);
15896 if (!dac)
15897 continue;
15898 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15899 }
df694daa
KY
15900 return 0;
15901}
15902
bcb2f0f5
TI
15903static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15904 hda_nid_t nid, int idx, unsigned int chs)
1c20930a 15905{
bcb2f0f5 15906 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
1c20930a
TI
15907 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15908}
15909
bcb2f0f5
TI
15910#define alc861_create_out_sw(codec, pfx, nid, chs) \
15911 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15912
df694daa 15913/* add playback controls from the parsed DAC table */
1c20930a 15914static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15915 const struct auto_pin_cfg *cfg)
15916{
1c20930a 15917 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
15918 static const char *chname[4] = {
15919 "Front", "Surround", NULL /*CLFE*/, "Side"
15920 };
bcb2f0f5 15921 const char *pfx = alc_get_line_out_pfx(cfg, true);
df694daa 15922 hda_nid_t nid;
1c20930a
TI
15923 int i, err;
15924
df694daa
KY
15925 for (i = 0; i < cfg->line_outs; i++) {
15926 nid = spec->multiout.dac_nids[i];
f12ab1e0 15927 if (!nid)
df694daa 15928 continue;
bcb2f0f5 15929 if (!pfx && i == 2) {
df694daa 15930 /* Center/LFE */
1c20930a 15931 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15932 if (err < 0)
df694daa 15933 return err;
1c20930a 15934 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15935 if (err < 0)
df694daa
KY
15936 return err;
15937 } else {
bcb2f0f5
TI
15938 const char *name = pfx;
15939 if (!name)
15940 name = chname[i];
15941 err = __alc861_create_out_sw(codec, name, nid, i, 3);
f12ab1e0 15942 if (err < 0)
df694daa
KY
15943 return err;
15944 }
15945 }
15946 return 0;
15947}
15948
1c20930a 15949static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 15950{
1c20930a 15951 struct alc_spec *spec = codec->spec;
df694daa
KY
15952 int err;
15953 hda_nid_t nid;
15954
f12ab1e0 15955 if (!pin)
df694daa
KY
15956 return 0;
15957
15958 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
15959 nid = alc861_look_for_dac(codec, pin);
15960 if (nid) {
15961 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15962 if (err < 0)
15963 return err;
15964 spec->multiout.hp_nid = nid;
15965 }
df694daa
KY
15966 }
15967 return 0;
15968}
15969
15970/* create playback/capture controls for input pins */
05f5f477 15971static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 15972 const struct auto_pin_cfg *cfg)
df694daa 15973{
05f5f477 15974 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
15975}
15976
f12ab1e0
TI
15977static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15978 hda_nid_t nid,
1c20930a 15979 int pin_type, hda_nid_t dac)
df694daa 15980{
1c20930a
TI
15981 hda_nid_t mix, srcs[5];
15982 int i, num;
15983
564c5bea
JL
15984 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15985 pin_type);
1c20930a 15986 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 15987 AMP_OUT_UNMUTE);
1c20930a
TI
15988 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15989 return;
15990 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15991 if (num < 0)
15992 return;
15993 for (i = 0; i < num; i++) {
15994 unsigned int mute;
15995 if (srcs[i] == dac || srcs[i] == 0x15)
15996 mute = AMP_IN_UNMUTE(i);
15997 else
15998 mute = AMP_IN_MUTE(i);
15999 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16000 mute);
16001 }
df694daa
KY
16002}
16003
16004static void alc861_auto_init_multi_out(struct hda_codec *codec)
16005{
16006 struct alc_spec *spec = codec->spec;
16007 int i;
16008
16009 for (i = 0; i < spec->autocfg.line_outs; i++) {
16010 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16011 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 16012 if (nid)
baba8ee9 16013 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 16014 spec->multiout.dac_nids[i]);
df694daa
KY
16015 }
16016}
16017
16018static void alc861_auto_init_hp_out(struct hda_codec *codec)
16019{
16020 struct alc_spec *spec = codec->spec;
df694daa 16021
15870f05
TI
16022 if (spec->autocfg.hp_outs)
16023 alc861_auto_set_output_and_unmute(codec,
16024 spec->autocfg.hp_pins[0],
16025 PIN_HP,
1c20930a 16026 spec->multiout.hp_nid);
15870f05
TI
16027 if (spec->autocfg.speaker_outs)
16028 alc861_auto_set_output_and_unmute(codec,
16029 spec->autocfg.speaker_pins[0],
16030 PIN_OUT,
1c20930a 16031 spec->multiout.dac_nids[0]);
df694daa
KY
16032}
16033
16034static void alc861_auto_init_analog_input(struct hda_codec *codec)
16035{
16036 struct alc_spec *spec = codec->spec;
66ceeb6b 16037 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
16038 int i;
16039
66ceeb6b
TI
16040 for (i = 0; i < cfg->num_inputs; i++) {
16041 hda_nid_t nid = cfg->inputs[i].pin;
23f0c048 16042 if (nid >= 0x0c && nid <= 0x11)
30ea098f 16043 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
df694daa
KY
16044 }
16045}
16046
16047/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
16048/* return 1 if successful, 0 if the proper config is not found,
16049 * or a negative error code
16050 */
df694daa
KY
16051static int alc861_parse_auto_config(struct hda_codec *codec)
16052{
16053 struct alc_spec *spec = codec->spec;
16054 int err;
16055 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16056
f12ab1e0
TI
16057 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16058 alc861_ignore);
16059 if (err < 0)
df694daa 16060 return err;
f12ab1e0 16061 if (!spec->autocfg.line_outs)
df694daa
KY
16062 return 0; /* can't find valid BIOS pin config */
16063
1c20930a 16064 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
16065 if (err < 0)
16066 return err;
1c20930a 16067 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
16068 if (err < 0)
16069 return err;
1c20930a 16070 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
16071 if (err < 0)
16072 return err;
05f5f477 16073 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16074 if (err < 0)
df694daa
KY
16075 return err;
16076
16077 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16078
757899ac 16079 alc_auto_parse_digital(codec);
df694daa 16080
603c4019 16081 if (spec->kctls.list)
d88897ea 16082 add_mixer(spec, spec->kctls.list);
df694daa 16083
d88897ea 16084 add_verb(spec, alc861_auto_init_verbs);
df694daa 16085
a1e8d2da 16086 spec->num_mux_defs = 1;
61b9b9b1 16087 spec->input_mux = &spec->private_imux[0];
df694daa
KY
16088
16089 spec->adc_nids = alc861_adc_nids;
16090 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 16091 set_capture_mixer(codec);
df694daa 16092
6227cdce 16093 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 16094
df694daa
KY
16095 return 1;
16096}
16097
ae6b813a
TI
16098/* additional initialization for auto-configuration model */
16099static void alc861_auto_init(struct hda_codec *codec)
df694daa 16100{
f6c7e546 16101 struct alc_spec *spec = codec->spec;
df694daa
KY
16102 alc861_auto_init_multi_out(codec);
16103 alc861_auto_init_hp_out(codec);
16104 alc861_auto_init_analog_input(codec);
757899ac 16105 alc_auto_init_digital(codec);
f6c7e546 16106 if (spec->unsol_event)
7fb0d78f 16107 alc_inithook(codec);
df694daa
KY
16108}
16109
cb53c626
TI
16110#ifdef CONFIG_SND_HDA_POWER_SAVE
16111static struct hda_amp_list alc861_loopbacks[] = {
16112 { 0x15, HDA_INPUT, 0 },
16113 { 0x15, HDA_INPUT, 1 },
16114 { 0x15, HDA_INPUT, 2 },
16115 { 0x15, HDA_INPUT, 3 },
16116 { } /* end */
16117};
16118#endif
16119
df694daa
KY
16120
16121/*
16122 * configuration and preset
16123 */
f5fcc13c
TI
16124static const char *alc861_models[ALC861_MODEL_LAST] = {
16125 [ALC861_3ST] = "3stack",
16126 [ALC660_3ST] = "3stack-660",
16127 [ALC861_3ST_DIG] = "3stack-dig",
16128 [ALC861_6ST_DIG] = "6stack-dig",
16129 [ALC861_UNIWILL_M31] = "uniwill-m31",
16130 [ALC861_TOSHIBA] = "toshiba",
16131 [ALC861_ASUS] = "asus",
16132 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16133 [ALC861_AUTO] = "auto",
16134};
16135
16136static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 16137 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
16138 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16139 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16140 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 16141 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 16142 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16143 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16144 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16145 * Any other models that need this preset?
16146 */
16147 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16148 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16149 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16150 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16151 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16152 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16153 /* FIXME: the below seems conflict */
16154 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16155 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16156 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16157 {}
16158};
16159
16160static struct alc_config_preset alc861_presets[] = {
16161 [ALC861_3ST] = {
16162 .mixers = { alc861_3ST_mixer },
16163 .init_verbs = { alc861_threestack_init_verbs },
16164 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16165 .dac_nids = alc861_dac_nids,
16166 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16167 .channel_mode = alc861_threestack_modes,
4e195a7b 16168 .need_dac_fix = 1,
df694daa
KY
16169 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16170 .adc_nids = alc861_adc_nids,
16171 .input_mux = &alc861_capture_source,
16172 },
16173 [ALC861_3ST_DIG] = {
16174 .mixers = { alc861_base_mixer },
16175 .init_verbs = { alc861_threestack_init_verbs },
16176 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16177 .dac_nids = alc861_dac_nids,
16178 .dig_out_nid = ALC861_DIGOUT_NID,
16179 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16180 .channel_mode = alc861_threestack_modes,
4e195a7b 16181 .need_dac_fix = 1,
df694daa
KY
16182 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16183 .adc_nids = alc861_adc_nids,
16184 .input_mux = &alc861_capture_source,
16185 },
16186 [ALC861_6ST_DIG] = {
16187 .mixers = { alc861_base_mixer },
16188 .init_verbs = { alc861_base_init_verbs },
16189 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16190 .dac_nids = alc861_dac_nids,
16191 .dig_out_nid = ALC861_DIGOUT_NID,
16192 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16193 .channel_mode = alc861_8ch_modes,
16194 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16195 .adc_nids = alc861_adc_nids,
16196 .input_mux = &alc861_capture_source,
16197 },
9c7f852e
TI
16198 [ALC660_3ST] = {
16199 .mixers = { alc861_3ST_mixer },
16200 .init_verbs = { alc861_threestack_init_verbs },
16201 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16202 .dac_nids = alc660_dac_nids,
16203 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16204 .channel_mode = alc861_threestack_modes,
4e195a7b 16205 .need_dac_fix = 1,
9c7f852e
TI
16206 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16207 .adc_nids = alc861_adc_nids,
16208 .input_mux = &alc861_capture_source,
16209 },
22309c3e
TI
16210 [ALC861_UNIWILL_M31] = {
16211 .mixers = { alc861_uniwill_m31_mixer },
16212 .init_verbs = { alc861_uniwill_m31_init_verbs },
16213 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16214 .dac_nids = alc861_dac_nids,
16215 .dig_out_nid = ALC861_DIGOUT_NID,
16216 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16217 .channel_mode = alc861_uniwill_m31_modes,
16218 .need_dac_fix = 1,
16219 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16220 .adc_nids = alc861_adc_nids,
16221 .input_mux = &alc861_capture_source,
16222 },
a53d1aec
TD
16223 [ALC861_TOSHIBA] = {
16224 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16225 .init_verbs = { alc861_base_init_verbs,
16226 alc861_toshiba_init_verbs },
a53d1aec
TD
16227 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16228 .dac_nids = alc861_dac_nids,
16229 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16230 .channel_mode = alc883_3ST_2ch_modes,
16231 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16232 .adc_nids = alc861_adc_nids,
16233 .input_mux = &alc861_capture_source,
16234 .unsol_event = alc861_toshiba_unsol_event,
16235 .init_hook = alc861_toshiba_automute,
16236 },
7cdbff94
MD
16237 [ALC861_ASUS] = {
16238 .mixers = { alc861_asus_mixer },
16239 .init_verbs = { alc861_asus_init_verbs },
16240 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16241 .dac_nids = alc861_dac_nids,
16242 .dig_out_nid = ALC861_DIGOUT_NID,
16243 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16244 .channel_mode = alc861_asus_modes,
16245 .need_dac_fix = 1,
16246 .hp_nid = 0x06,
16247 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16248 .adc_nids = alc861_adc_nids,
16249 .input_mux = &alc861_capture_source,
16250 },
56bb0cab
TI
16251 [ALC861_ASUS_LAPTOP] = {
16252 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16253 .init_verbs = { alc861_asus_init_verbs,
16254 alc861_asus_laptop_init_verbs },
16255 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16256 .dac_nids = alc861_dac_nids,
16257 .dig_out_nid = ALC861_DIGOUT_NID,
16258 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16259 .channel_mode = alc883_3ST_2ch_modes,
16260 .need_dac_fix = 1,
16261 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16262 .adc_nids = alc861_adc_nids,
16263 .input_mux = &alc861_capture_source,
16264 },
16265};
df694daa 16266
cfc9b06f
TI
16267/* Pin config fixes */
16268enum {
16269 PINFIX_FSC_AMILO_PI1505,
16270};
16271
cfc9b06f
TI
16272static const struct alc_fixup alc861_fixups[] = {
16273 [PINFIX_FSC_AMILO_PI1505] = {
73413b12
TI
16274 .pins = (const struct alc_pincfg[]) {
16275 { 0x0b, 0x0221101f }, /* HP */
16276 { 0x0f, 0x90170310 }, /* speaker */
16277 { }
16278 }
cfc9b06f
TI
16279 },
16280};
16281
16282static struct snd_pci_quirk alc861_fixup_tbl[] = {
16283 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16284 {}
16285};
df694daa
KY
16286
16287static int patch_alc861(struct hda_codec *codec)
16288{
16289 struct alc_spec *spec;
16290 int board_config;
16291 int err;
16292
dc041e0b 16293 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16294 if (spec == NULL)
16295 return -ENOMEM;
16296
f12ab1e0 16297 codec->spec = spec;
df694daa 16298
f5fcc13c
TI
16299 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16300 alc861_models,
16301 alc861_cfg_tbl);
9c7f852e 16302
f5fcc13c 16303 if (board_config < 0) {
9a11f1aa
TI
16304 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16305 codec->chip_name);
df694daa
KY
16306 board_config = ALC861_AUTO;
16307 }
16308
7fa90e87
TI
16309 if (board_config == ALC861_AUTO)
16310 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
cfc9b06f 16311
df694daa
KY
16312 if (board_config == ALC861_AUTO) {
16313 /* automatic parse from the BIOS config */
16314 err = alc861_parse_auto_config(codec);
16315 if (err < 0) {
16316 alc_free(codec);
16317 return err;
f12ab1e0 16318 } else if (!err) {
9c7f852e
TI
16319 printk(KERN_INFO
16320 "hda_codec: Cannot set up configuration "
16321 "from BIOS. Using base mode...\n");
df694daa
KY
16322 board_config = ALC861_3ST_DIG;
16323 }
16324 }
16325
680cd536
KK
16326 err = snd_hda_attach_beep_device(codec, 0x23);
16327 if (err < 0) {
16328 alc_free(codec);
16329 return err;
16330 }
16331
df694daa 16332 if (board_config != ALC861_AUTO)
e9c364c0 16333 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16334
df694daa
KY
16335 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16336 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16337
df694daa
KY
16338 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16339 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16340
c7a8eb10
TI
16341 if (!spec->cap_mixer)
16342 set_capture_mixer(codec);
45bdd1c1
TI
16343 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16344
2134ea4f
TI
16345 spec->vmaster_nid = 0x03;
16346
7fa90e87
TI
16347 if (board_config == ALC861_AUTO)
16348 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
16349
df694daa 16350 codec->patch_ops = alc_patch_ops;
c97259df 16351 if (board_config == ALC861_AUTO) {
ae6b813a 16352 spec->init_hook = alc861_auto_init;
c97259df
DC
16353#ifdef CONFIG_SND_HDA_POWER_SAVE
16354 spec->power_hook = alc_power_eapd;
16355#endif
16356 }
cb53c626
TI
16357#ifdef CONFIG_SND_HDA_POWER_SAVE
16358 if (!spec->loopback.amplist)
16359 spec->loopback.amplist = alc861_loopbacks;
16360#endif
ea1fb29a 16361
1da177e4
LT
16362 return 0;
16363}
16364
f32610ed
JS
16365/*
16366 * ALC861-VD support
16367 *
16368 * Based on ALC882
16369 *
16370 * In addition, an independent DAC
16371 */
16372#define ALC861VD_DIGOUT_NID 0x06
16373
16374static hda_nid_t alc861vd_dac_nids[4] = {
16375 /* front, surr, clfe, side surr */
16376 0x02, 0x03, 0x04, 0x05
16377};
16378
16379/* dac_nids for ALC660vd are in a different order - according to
16380 * Realtek's driver.
def319f9 16381 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16382 * of ALC660vd codecs, but for now there is only 3stack mixer
16383 * - and it is the same as in 861vd.
16384 * adc_nids in ALC660vd are (is) the same as in 861vd
16385 */
16386static hda_nid_t alc660vd_dac_nids[3] = {
16387 /* front, rear, clfe, rear_surr */
16388 0x02, 0x04, 0x03
16389};
16390
16391static hda_nid_t alc861vd_adc_nids[1] = {
16392 /* ADC0 */
16393 0x09,
16394};
16395
e1406348
TI
16396static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16397
f32610ed
JS
16398/* input MUX */
16399/* FIXME: should be a matrix-type input source selection */
16400static struct hda_input_mux alc861vd_capture_source = {
16401 .num_items = 4,
16402 .items = {
16403 { "Mic", 0x0 },
16404 { "Front Mic", 0x1 },
16405 { "Line", 0x2 },
16406 { "CD", 0x4 },
16407 },
16408};
16409
272a527c 16410static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16411 .num_items = 2,
272a527c 16412 .items = {
8607f7c4 16413 { "Mic", 0x0 },
28c4edb7 16414 { "Internal Mic", 0x1 },
272a527c
KY
16415 },
16416};
16417
d1a991a6
KY
16418static struct hda_input_mux alc861vd_hp_capture_source = {
16419 .num_items = 2,
16420 .items = {
16421 { "Front Mic", 0x0 },
16422 { "ATAPI Mic", 0x1 },
16423 },
16424};
16425
f32610ed
JS
16426/*
16427 * 2ch mode
16428 */
16429static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16430 { 2, NULL }
16431};
16432
16433/*
16434 * 6ch mode
16435 */
16436static struct hda_verb alc861vd_6stack_ch6_init[] = {
16437 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16438 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16439 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16440 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16441 { } /* end */
16442};
16443
16444/*
16445 * 8ch mode
16446 */
16447static struct hda_verb alc861vd_6stack_ch8_init[] = {
16448 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16449 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16450 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16451 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16452 { } /* end */
16453};
16454
16455static struct hda_channel_mode alc861vd_6stack_modes[2] = {
16456 { 6, alc861vd_6stack_ch6_init },
16457 { 8, alc861vd_6stack_ch8_init },
16458};
16459
16460static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16461 {
16462 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16463 .name = "Channel Mode",
16464 .info = alc_ch_mode_info,
16465 .get = alc_ch_mode_get,
16466 .put = alc_ch_mode_put,
16467 },
16468 { } /* end */
16469};
16470
f32610ed
JS
16471/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16472 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16473 */
16474static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16475 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16476 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16477
16478 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16479 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16480
16481 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16482 HDA_OUTPUT),
16483 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16484 HDA_OUTPUT),
16485 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16486 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16487
16488 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16489 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16490
16491 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16492
5f99f86a 16493 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16494 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16495 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16496
5f99f86a 16497 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16498 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16499 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16500
16501 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16502 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16503
16504 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16505 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16506
f32610ed
JS
16507 { } /* end */
16508};
16509
16510static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16511 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16512 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16513
16514 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16515
5f99f86a 16516 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16517 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16518 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16519
5f99f86a 16520 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16521 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16522 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16523
16524 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16525 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16526
16527 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16528 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16529
f32610ed
JS
16530 { } /* end */
16531};
16532
bdd148a3
KY
16533static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16534 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16535 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16536 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16537
16538 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16539
5f99f86a 16540 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3
KY
16541 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16542 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16543
5f99f86a 16544 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
bdd148a3
KY
16545 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16546 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16547
16548 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16549 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16550
16551 { } /* end */
16552};
16553
b419f346 16554/* Pin assignment: Speaker=0x14, HP = 0x15,
8607f7c4 16555 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
16556 */
16557static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16558 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16559 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16560 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16561 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
5f99f86a 16562 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8607f7c4
DH
16563 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16564 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 16565 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
16566 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16567 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16568 { } /* end */
16569};
16570
d1a991a6
KY
16571/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16572 * Front Mic=0x18, ATAPI Mic = 0x19,
16573 */
16574static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16575 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16576 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16577 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16578 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16579 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16580 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16581 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16582 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16583
d1a991a6
KY
16584 { } /* end */
16585};
16586
f32610ed
JS
16587/*
16588 * generic initialization of ADC, input mixers and output mixers
16589 */
16590static struct hda_verb alc861vd_volume_init_verbs[] = {
16591 /*
16592 * Unmute ADC0 and set the default input to mic-in
16593 */
16594 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16595 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16596
16597 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16598 * the analog-loopback mixer widget
16599 */
16600 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16601 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16602 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16603 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16604 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16605 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16606
16607 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16608 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16609 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16610 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16611 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16612
16613 /*
16614 * Set up output mixers (0x02 - 0x05)
16615 */
16616 /* set vol=0 to output mixers */
16617 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16618 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16619 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16620 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16621
16622 /* set up input amps for analog loopback */
16623 /* Amp Indices: DAC = 0, mixer = 1 */
16624 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16625 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16626 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16627 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16628 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16629 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16630 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16631 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16632
16633 { }
16634};
16635
16636/*
16637 * 3-stack pin configuration:
16638 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16639 */
16640static struct hda_verb alc861vd_3stack_init_verbs[] = {
16641 /*
16642 * Set pin mode and muting
16643 */
16644 /* set front pin widgets 0x14 for output */
16645 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16646 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16647 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16648
16649 /* Mic (rear) pin: input vref at 80% */
16650 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16651 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16652 /* Front Mic pin: input vref at 80% */
16653 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16654 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16655 /* Line In pin: input */
16656 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16657 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16658 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16659 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16660 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16661 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16662 /* CD pin widget for input */
16663 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16664
16665 { }
16666};
16667
16668/*
16669 * 6-stack pin configuration:
16670 */
16671static struct hda_verb alc861vd_6stack_init_verbs[] = {
16672 /*
16673 * Set pin mode and muting
16674 */
16675 /* set front pin widgets 0x14 for output */
16676 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16677 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16678 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16679
16680 /* Rear Pin: output 1 (0x0d) */
16681 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16682 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16683 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16684 /* CLFE Pin: output 2 (0x0e) */
16685 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16686 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16687 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16688 /* Side Pin: output 3 (0x0f) */
16689 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16690 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16691 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16692
16693 /* Mic (rear) pin: input vref at 80% */
16694 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16695 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16696 /* Front Mic pin: input vref at 80% */
16697 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16698 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16699 /* Line In pin: input */
16700 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16701 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16702 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16703 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16704 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16705 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16706 /* CD pin widget for input */
16707 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16708
16709 { }
16710};
16711
bdd148a3
KY
16712static struct hda_verb alc861vd_eapd_verbs[] = {
16713 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16714 { }
16715};
16716
f9423e7a
KY
16717static struct hda_verb alc660vd_eapd_verbs[] = {
16718 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16719 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16720 { }
16721};
16722
bdd148a3
KY
16723static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16724 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16725 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16726 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16727 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16728 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16729 {}
16730};
16731
4f5d1706 16732static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16733{
a9fd4f3f 16734 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16735 spec->autocfg.hp_pins[0] = 0x1b;
16736 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
16737}
16738
16739static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16740{
a9fd4f3f 16741 alc_automute_amp(codec);
eeb43387 16742 alc88x_simple_mic_automute(codec);
bdd148a3
KY
16743}
16744
16745static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16746 unsigned int res)
16747{
16748 switch (res >> 26) {
bdd148a3 16749 case ALC880_MIC_EVENT:
eeb43387 16750 alc88x_simple_mic_automute(codec);
bdd148a3 16751 break;
a9fd4f3f
TI
16752 default:
16753 alc_automute_amp_unsol_event(codec, res);
16754 break;
bdd148a3
KY
16755 }
16756}
16757
272a527c
KY
16758static struct hda_verb alc861vd_dallas_verbs[] = {
16759 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16760 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16761 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16762 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16763
16764 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16765 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16766 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16767 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16768 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16769 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16770 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16771 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16772
272a527c
KY
16773 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16774 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16775 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16776 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16777 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16778 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16779 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16780 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16781
16782 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16783 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16784 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16785 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16786 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16787 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16788 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16789 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16790
16791 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16792 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16793 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16794 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16795
16796 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16797 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16798 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16799
16800 { } /* end */
16801};
16802
16803/* toggle speaker-output according to the hp-jack state */
4f5d1706 16804static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16805{
a9fd4f3f 16806 struct alc_spec *spec = codec->spec;
272a527c 16807
a9fd4f3f
TI
16808 spec->autocfg.hp_pins[0] = 0x15;
16809 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
16810}
16811
cb53c626
TI
16812#ifdef CONFIG_SND_HDA_POWER_SAVE
16813#define alc861vd_loopbacks alc880_loopbacks
16814#endif
16815
def319f9 16816/* pcm configuration: identical with ALC880 */
f32610ed
JS
16817#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16818#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16819#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16820#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16821
16822/*
16823 * configuration and preset
16824 */
16825static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
16826 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16827 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16828 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16829 [ALC861VD_3ST] = "3stack",
16830 [ALC861VD_3ST_DIG] = "3stack-digout",
16831 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16832 [ALC861VD_LENOVO] = "lenovo",
272a527c 16833 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16834 [ALC861VD_HP] = "hp",
f32610ed
JS
16835 [ALC861VD_AUTO] = "auto",
16836};
16837
16838static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16839 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16840 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16841 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16842 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16843 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16844 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16845 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16846 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16847 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16848 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16849 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16850 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16851 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16852 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16853 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16854 {}
16855};
16856
16857static struct alc_config_preset alc861vd_presets[] = {
16858 [ALC660VD_3ST] = {
16859 .mixers = { alc861vd_3st_mixer },
16860 .init_verbs = { alc861vd_volume_init_verbs,
16861 alc861vd_3stack_init_verbs },
16862 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16863 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16864 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16865 .channel_mode = alc861vd_3stack_2ch_modes,
16866 .input_mux = &alc861vd_capture_source,
16867 },
6963f84c
MC
16868 [ALC660VD_3ST_DIG] = {
16869 .mixers = { alc861vd_3st_mixer },
16870 .init_verbs = { alc861vd_volume_init_verbs,
16871 alc861vd_3stack_init_verbs },
16872 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16873 .dac_nids = alc660vd_dac_nids,
16874 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16875 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16876 .channel_mode = alc861vd_3stack_2ch_modes,
16877 .input_mux = &alc861vd_capture_source,
16878 },
f32610ed
JS
16879 [ALC861VD_3ST] = {
16880 .mixers = { alc861vd_3st_mixer },
16881 .init_verbs = { alc861vd_volume_init_verbs,
16882 alc861vd_3stack_init_verbs },
16883 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16884 .dac_nids = alc861vd_dac_nids,
16885 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16886 .channel_mode = alc861vd_3stack_2ch_modes,
16887 .input_mux = &alc861vd_capture_source,
16888 },
16889 [ALC861VD_3ST_DIG] = {
16890 .mixers = { alc861vd_3st_mixer },
16891 .init_verbs = { alc861vd_volume_init_verbs,
16892 alc861vd_3stack_init_verbs },
16893 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16894 .dac_nids = alc861vd_dac_nids,
16895 .dig_out_nid = ALC861VD_DIGOUT_NID,
16896 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16897 .channel_mode = alc861vd_3stack_2ch_modes,
16898 .input_mux = &alc861vd_capture_source,
16899 },
16900 [ALC861VD_6ST_DIG] = {
16901 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16902 .init_verbs = { alc861vd_volume_init_verbs,
16903 alc861vd_6stack_init_verbs },
16904 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16905 .dac_nids = alc861vd_dac_nids,
16906 .dig_out_nid = ALC861VD_DIGOUT_NID,
16907 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16908 .channel_mode = alc861vd_6stack_modes,
16909 .input_mux = &alc861vd_capture_source,
16910 },
bdd148a3
KY
16911 [ALC861VD_LENOVO] = {
16912 .mixers = { alc861vd_lenovo_mixer },
16913 .init_verbs = { alc861vd_volume_init_verbs,
16914 alc861vd_3stack_init_verbs,
16915 alc861vd_eapd_verbs,
16916 alc861vd_lenovo_unsol_verbs },
16917 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16918 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16919 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16920 .channel_mode = alc861vd_3stack_2ch_modes,
16921 .input_mux = &alc861vd_capture_source,
16922 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16923 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16924 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16925 },
272a527c
KY
16926 [ALC861VD_DALLAS] = {
16927 .mixers = { alc861vd_dallas_mixer },
16928 .init_verbs = { alc861vd_dallas_verbs },
16929 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16930 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16931 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16932 .channel_mode = alc861vd_3stack_2ch_modes,
16933 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 16934 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16935 .setup = alc861vd_dallas_setup,
16936 .init_hook = alc_automute_amp,
d1a991a6
KY
16937 },
16938 [ALC861VD_HP] = {
16939 .mixers = { alc861vd_hp_mixer },
16940 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16941 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16942 .dac_nids = alc861vd_dac_nids,
d1a991a6 16943 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
16944 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16945 .channel_mode = alc861vd_3stack_2ch_modes,
16946 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 16947 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16948 .setup = alc861vd_dallas_setup,
16949 .init_hook = alc_automute_amp,
ea1fb29a 16950 },
13c94744
TI
16951 [ALC660VD_ASUS_V1S] = {
16952 .mixers = { alc861vd_lenovo_mixer },
16953 .init_verbs = { alc861vd_volume_init_verbs,
16954 alc861vd_3stack_init_verbs,
16955 alc861vd_eapd_verbs,
16956 alc861vd_lenovo_unsol_verbs },
16957 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16958 .dac_nids = alc660vd_dac_nids,
16959 .dig_out_nid = ALC861VD_DIGOUT_NID,
16960 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16961 .channel_mode = alc861vd_3stack_2ch_modes,
16962 .input_mux = &alc861vd_capture_source,
16963 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16964 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16965 .init_hook = alc861vd_lenovo_init_hook,
13c94744 16966 },
f32610ed
JS
16967};
16968
16969/*
16970 * BIOS auto configuration
16971 */
05f5f477
TI
16972static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16973 const struct auto_pin_cfg *cfg)
16974{
7167594a 16975 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
05f5f477
TI
16976}
16977
16978
f32610ed
JS
16979static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
16980 hda_nid_t nid, int pin_type, int dac_idx)
16981{
f6c7e546 16982 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
16983}
16984
16985static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
16986{
16987 struct alc_spec *spec = codec->spec;
16988 int i;
16989
16990 for (i = 0; i <= HDA_SIDE; i++) {
16991 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16992 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
16993 if (nid)
16994 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 16995 pin_type, i);
f32610ed
JS
16996 }
16997}
16998
16999
17000static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17001{
17002 struct alc_spec *spec = codec->spec;
17003 hda_nid_t pin;
17004
17005 pin = spec->autocfg.hp_pins[0];
def319f9 17006 if (pin) /* connect to front and use dac 0 */
f32610ed 17007 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
17008 pin = spec->autocfg.speaker_pins[0];
17009 if (pin)
17010 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
17011}
17012
f32610ed
JS
17013#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17014
17015static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17016{
17017 struct alc_spec *spec = codec->spec;
66ceeb6b 17018 struct auto_pin_cfg *cfg = &spec->autocfg;
f32610ed
JS
17019 int i;
17020
66ceeb6b
TI
17021 for (i = 0; i < cfg->num_inputs; i++) {
17022 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 17023 if (alc_is_input_pin(codec, nid)) {
30ea098f 17024 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
17025 if (nid != ALC861VD_PIN_CD_NID &&
17026 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
17027 snd_hda_codec_write(codec, nid, 0,
17028 AC_VERB_SET_AMP_GAIN_MUTE,
17029 AMP_OUT_MUTE);
17030 }
17031 }
17032}
17033
f511b01c
TI
17034#define alc861vd_auto_init_input_src alc882_auto_init_input_src
17035
f32610ed
JS
17036#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17037#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17038
17039/* add playback controls from the parsed DAC table */
17040/* Based on ALC880 version. But ALC861VD has separate,
17041 * different NIDs for mute/unmute switch and volume control */
17042static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17043 const struct auto_pin_cfg *cfg)
17044{
f32610ed 17045 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
bcb2f0f5 17046 const char *pfx = alc_get_line_out_pfx(cfg, true);
f32610ed
JS
17047 hda_nid_t nid_v, nid_s;
17048 int i, err;
17049
17050 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 17051 if (!spec->multiout.dac_nids[i])
f32610ed
JS
17052 continue;
17053 nid_v = alc861vd_idx_to_mixer_vol(
17054 alc880_dac_to_idx(
17055 spec->multiout.dac_nids[i]));
17056 nid_s = alc861vd_idx_to_mixer_switch(
17057 alc880_dac_to_idx(
17058 spec->multiout.dac_nids[i]));
17059
bcb2f0f5 17060 if (!pfx && i == 2) {
f32610ed 17061 /* Center/LFE */
0afe5f89
TI
17062 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17063 "Center",
f12ab1e0
TI
17064 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17065 HDA_OUTPUT));
17066 if (err < 0)
f32610ed 17067 return err;
0afe5f89
TI
17068 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17069 "LFE",
f12ab1e0
TI
17070 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17071 HDA_OUTPUT));
17072 if (err < 0)
f32610ed 17073 return err;
0afe5f89
TI
17074 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17075 "Center",
f12ab1e0
TI
17076 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17077 HDA_INPUT));
17078 if (err < 0)
f32610ed 17079 return err;
0afe5f89
TI
17080 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17081 "LFE",
f12ab1e0
TI
17082 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17083 HDA_INPUT));
17084 if (err < 0)
f32610ed
JS
17085 return err;
17086 } else {
bcb2f0f5
TI
17087 const char *name = pfx;
17088 if (!name)
17089 name = chname[i];
17090 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17091 name, i,
f12ab1e0
TI
17092 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17093 HDA_OUTPUT));
17094 if (err < 0)
f32610ed 17095 return err;
bcb2f0f5
TI
17096 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17097 name, i,
bdd148a3 17098 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
17099 HDA_INPUT));
17100 if (err < 0)
f32610ed
JS
17101 return err;
17102 }
17103 }
17104 return 0;
17105}
17106
17107/* add playback controls for speaker and HP outputs */
17108/* Based on ALC880 version. But ALC861VD has separate,
17109 * different NIDs for mute/unmute switch and volume control */
17110static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17111 hda_nid_t pin, const char *pfx)
17112{
17113 hda_nid_t nid_v, nid_s;
17114 int err;
f32610ed 17115
f12ab1e0 17116 if (!pin)
f32610ed
JS
17117 return 0;
17118
17119 if (alc880_is_fixed_pin(pin)) {
17120 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17121 /* specify the DAC as the extra output */
f12ab1e0 17122 if (!spec->multiout.hp_nid)
f32610ed
JS
17123 spec->multiout.hp_nid = nid_v;
17124 else
17125 spec->multiout.extra_out_nid[0] = nid_v;
17126 /* control HP volume/switch on the output mixer amp */
17127 nid_v = alc861vd_idx_to_mixer_vol(
17128 alc880_fixed_pin_idx(pin));
17129 nid_s = alc861vd_idx_to_mixer_switch(
17130 alc880_fixed_pin_idx(pin));
17131
0afe5f89 17132 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17133 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17134 if (err < 0)
f32610ed 17135 return err;
0afe5f89 17136 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17137 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17138 if (err < 0)
f32610ed
JS
17139 return err;
17140 } else if (alc880_is_multi_pin(pin)) {
17141 /* set manual connection */
17142 /* we have only a switch on HP-out PIN */
0afe5f89 17143 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17144 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17145 if (err < 0)
f32610ed
JS
17146 return err;
17147 }
17148 return 0;
17149}
17150
17151/* parse the BIOS configuration and set up the alc_spec
17152 * return 1 if successful, 0 if the proper config is not found,
17153 * or a negative error code
17154 * Based on ALC880 version - had to change it to override
17155 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17156static int alc861vd_parse_auto_config(struct hda_codec *codec)
17157{
17158 struct alc_spec *spec = codec->spec;
17159 int err;
17160 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17161
f12ab1e0
TI
17162 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17163 alc861vd_ignore);
17164 if (err < 0)
f32610ed 17165 return err;
f12ab1e0 17166 if (!spec->autocfg.line_outs)
f32610ed
JS
17167 return 0; /* can't find valid BIOS pin config */
17168
f12ab1e0
TI
17169 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17170 if (err < 0)
17171 return err;
17172 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17173 if (err < 0)
17174 return err;
17175 err = alc861vd_auto_create_extra_out(spec,
17176 spec->autocfg.speaker_pins[0],
17177 "Speaker");
17178 if (err < 0)
17179 return err;
17180 err = alc861vd_auto_create_extra_out(spec,
17181 spec->autocfg.hp_pins[0],
17182 "Headphone");
17183 if (err < 0)
17184 return err;
05f5f477 17185 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17186 if (err < 0)
f32610ed
JS
17187 return err;
17188
17189 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17190
757899ac 17191 alc_auto_parse_digital(codec);
f32610ed 17192
603c4019 17193 if (spec->kctls.list)
d88897ea 17194 add_mixer(spec, spec->kctls.list);
f32610ed 17195
d88897ea 17196 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
17197
17198 spec->num_mux_defs = 1;
61b9b9b1 17199 spec->input_mux = &spec->private_imux[0];
f32610ed 17200
776e184e
TI
17201 err = alc_auto_add_mic_boost(codec);
17202 if (err < 0)
17203 return err;
17204
6227cdce 17205 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17206
f32610ed
JS
17207 return 1;
17208}
17209
17210/* additional initialization for auto-configuration model */
17211static void alc861vd_auto_init(struct hda_codec *codec)
17212{
f6c7e546 17213 struct alc_spec *spec = codec->spec;
f32610ed
JS
17214 alc861vd_auto_init_multi_out(codec);
17215 alc861vd_auto_init_hp_out(codec);
17216 alc861vd_auto_init_analog_input(codec);
f511b01c 17217 alc861vd_auto_init_input_src(codec);
757899ac 17218 alc_auto_init_digital(codec);
f6c7e546 17219 if (spec->unsol_event)
7fb0d78f 17220 alc_inithook(codec);
f32610ed
JS
17221}
17222
f8f25ba3
TI
17223enum {
17224 ALC660VD_FIX_ASUS_GPIO1
17225};
17226
17227/* reset GPIO1 */
f8f25ba3
TI
17228static const struct alc_fixup alc861vd_fixups[] = {
17229 [ALC660VD_FIX_ASUS_GPIO1] = {
73413b12
TI
17230 .verbs = (const struct hda_verb[]) {
17231 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17232 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17233 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17234 { }
17235 }
f8f25ba3
TI
17236 },
17237};
17238
17239static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17240 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17241 {}
17242};
17243
f32610ed
JS
17244static int patch_alc861vd(struct hda_codec *codec)
17245{
17246 struct alc_spec *spec;
17247 int err, board_config;
17248
17249 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17250 if (spec == NULL)
17251 return -ENOMEM;
17252
17253 codec->spec = spec;
17254
17255 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17256 alc861vd_models,
17257 alc861vd_cfg_tbl);
17258
17259 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17260 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17261 codec->chip_name);
f32610ed
JS
17262 board_config = ALC861VD_AUTO;
17263 }
17264
7fa90e87
TI
17265 if (board_config == ALC861VD_AUTO)
17266 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
f8f25ba3 17267
f32610ed
JS
17268 if (board_config == ALC861VD_AUTO) {
17269 /* automatic parse from the BIOS config */
17270 err = alc861vd_parse_auto_config(codec);
17271 if (err < 0) {
17272 alc_free(codec);
17273 return err;
f12ab1e0 17274 } else if (!err) {
f32610ed
JS
17275 printk(KERN_INFO
17276 "hda_codec: Cannot set up configuration "
17277 "from BIOS. Using base mode...\n");
17278 board_config = ALC861VD_3ST;
17279 }
17280 }
17281
680cd536
KK
17282 err = snd_hda_attach_beep_device(codec, 0x23);
17283 if (err < 0) {
17284 alc_free(codec);
17285 return err;
17286 }
17287
f32610ed 17288 if (board_config != ALC861VD_AUTO)
e9c364c0 17289 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17290
2f893286 17291 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17292 /* always turn on EAPD */
d88897ea 17293 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17294 }
17295
f32610ed
JS
17296 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17297 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17298
f32610ed
JS
17299 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17300 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17301
dd704698
TI
17302 if (!spec->adc_nids) {
17303 spec->adc_nids = alc861vd_adc_nids;
17304 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17305 }
17306 if (!spec->capsrc_nids)
17307 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17308
b59bdf3b 17309 set_capture_mixer(codec);
45bdd1c1 17310 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17311
2134ea4f
TI
17312 spec->vmaster_nid = 0x02;
17313
7fa90e87
TI
17314 if (board_config == ALC861VD_AUTO)
17315 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
17316
f32610ed
JS
17317 codec->patch_ops = alc_patch_ops;
17318
17319 if (board_config == ALC861VD_AUTO)
17320 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
17321#ifdef CONFIG_SND_HDA_POWER_SAVE
17322 if (!spec->loopback.amplist)
17323 spec->loopback.amplist = alc861vd_loopbacks;
17324#endif
f32610ed
JS
17325
17326 return 0;
17327}
17328
bc9f98a9
KY
17329/*
17330 * ALC662 support
17331 *
17332 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17333 * configuration. Each pin widget can choose any input DACs and a mixer.
17334 * Each ADC is connected from a mixer of all inputs. This makes possible
17335 * 6-channel independent captures.
17336 *
17337 * In addition, an independent DAC for the multi-playback (not used in this
17338 * driver yet).
17339 */
17340#define ALC662_DIGOUT_NID 0x06
17341#define ALC662_DIGIN_NID 0x0a
17342
17343static hda_nid_t alc662_dac_nids[4] = {
17344 /* front, rear, clfe, rear_surr */
17345 0x02, 0x03, 0x04
17346};
17347
622e84cd
KY
17348static hda_nid_t alc272_dac_nids[2] = {
17349 0x02, 0x03
17350};
17351
b59bdf3b 17352static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17353 /* ADC1-2 */
b59bdf3b 17354 0x09, 0x08
bc9f98a9 17355};
e1406348 17356
622e84cd
KY
17357static hda_nid_t alc272_adc_nids[1] = {
17358 /* ADC1-2 */
17359 0x08,
17360};
17361
b59bdf3b 17362static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
17363static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17364
e1406348 17365
bc9f98a9
KY
17366/* input MUX */
17367/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
17368static struct hda_input_mux alc662_capture_source = {
17369 .num_items = 4,
17370 .items = {
17371 { "Mic", 0x0 },
17372 { "Front Mic", 0x1 },
17373 { "Line", 0x2 },
17374 { "CD", 0x4 },
17375 },
17376};
17377
17378static struct hda_input_mux alc662_lenovo_101e_capture_source = {
17379 .num_items = 2,
17380 .items = {
17381 { "Mic", 0x1 },
17382 { "Line", 0x2 },
17383 },
17384};
291702f0 17385
6dda9f4a
KY
17386static struct hda_input_mux alc663_capture_source = {
17387 .num_items = 3,
17388 .items = {
17389 { "Mic", 0x0 },
17390 { "Front Mic", 0x1 },
17391 { "Line", 0x2 },
17392 },
17393};
17394
4f5d1706 17395#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
17396static struct hda_input_mux alc272_nc10_capture_source = {
17397 .num_items = 16,
17398 .items = {
17399 { "Autoselect Mic", 0x0 },
17400 { "Internal Mic", 0x1 },
17401 { "In-0x02", 0x2 },
17402 { "In-0x03", 0x3 },
17403 { "In-0x04", 0x4 },
17404 { "In-0x05", 0x5 },
17405 { "In-0x06", 0x6 },
17406 { "In-0x07", 0x7 },
17407 { "In-0x08", 0x8 },
17408 { "In-0x09", 0x9 },
17409 { "In-0x0a", 0x0a },
17410 { "In-0x0b", 0x0b },
17411 { "In-0x0c", 0x0c },
17412 { "In-0x0d", 0x0d },
17413 { "In-0x0e", 0x0e },
17414 { "In-0x0f", 0x0f },
17415 },
17416};
17417#endif
17418
bc9f98a9
KY
17419/*
17420 * 2ch mode
17421 */
17422static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17423 { 2, NULL }
17424};
17425
17426/*
17427 * 2ch mode
17428 */
17429static struct hda_verb alc662_3ST_ch2_init[] = {
17430 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17431 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17432 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17433 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17434 { } /* end */
17435};
17436
17437/*
17438 * 6ch mode
17439 */
17440static struct hda_verb alc662_3ST_ch6_init[] = {
17441 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17442 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17443 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17444 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17445 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17446 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17447 { } /* end */
17448};
17449
17450static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17451 { 2, alc662_3ST_ch2_init },
17452 { 6, alc662_3ST_ch6_init },
17453};
17454
17455/*
17456 * 2ch mode
17457 */
17458static struct hda_verb alc662_sixstack_ch6_init[] = {
17459 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17460 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17461 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17462 { } /* end */
17463};
17464
17465/*
17466 * 6ch mode
17467 */
17468static struct hda_verb alc662_sixstack_ch8_init[] = {
17469 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17470 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17471 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17472 { } /* end */
17473};
17474
17475static struct hda_channel_mode alc662_5stack_modes[2] = {
17476 { 2, alc662_sixstack_ch6_init },
17477 { 6, alc662_sixstack_ch8_init },
17478};
17479
17480/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17481 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17482 */
17483
17484static struct snd_kcontrol_new alc662_base_mixer[] = {
17485 /* output mixer control */
17486 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17487 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17488 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17489 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17490 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17491 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17492 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17493 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17494 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17495
17496 /*Input mixer control */
17497 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17498 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17499 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17500 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17501 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17502 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17503 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17504 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17505 { } /* end */
17506};
17507
17508static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17509 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17510 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17511 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17512 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17513 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17514 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17515 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17516 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17517 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17518 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17519 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17520 { } /* end */
17521};
17522
17523static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17524 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17525 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17526 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17527 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17528 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17529 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17530 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17531 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17532 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17533 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17534 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17535 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17536 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17537 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17538 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17539 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17540 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17541 { } /* end */
17542};
17543
17544static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17545 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17546 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17547 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17548 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17549 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17550 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17551 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17552 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17553 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17554 { } /* end */
17555};
17556
291702f0 17557static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17558 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17559 ALC262_HIPPO_MASTER_SWITCH,
291702f0 17560
5f99f86a 17561 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17562 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17563 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
291702f0 17564
5f99f86a 17565 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17566 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17567 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
291702f0
KY
17568 { } /* end */
17569};
17570
8c427226 17571static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17572 ALC262_HIPPO_MASTER_SWITCH,
17573 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17574 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17575 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17576 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17577 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17578 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17579 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17580 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17581 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17582 { } /* end */
17583};
17584
f1d4e28b
KY
17585static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17586 .ops = &snd_hda_bind_vol,
17587 .values = {
17588 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17589 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17590 0
17591 },
17592};
17593
17594static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17595 .ops = &snd_hda_bind_sw,
17596 .values = {
17597 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17598 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17599 0
17600 },
17601};
17602
6dda9f4a 17603static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17604 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17605 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17606 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17607 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17608 { } /* end */
17609};
17610
17611static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17612 .ops = &snd_hda_bind_sw,
17613 .values = {
17614 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17615 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17616 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17617 0
17618 },
17619};
17620
17621static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17622 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17623 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17624 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17625 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17626 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17627 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17628
17629 { } /* end */
17630};
17631
17632static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17633 .ops = &snd_hda_bind_sw,
17634 .values = {
17635 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17636 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17637 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17638 0
17639 },
17640};
17641
17642static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17643 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17644 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17645 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17646 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17647 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17648 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17649 { } /* end */
17650};
17651
17652static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17653 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17654 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17655 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17656 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17657 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17658 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17659 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17660 { } /* end */
17661};
17662
17663static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17664 .ops = &snd_hda_bind_vol,
17665 .values = {
17666 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17667 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17668 0
17669 },
17670};
17671
17672static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17673 .ops = &snd_hda_bind_sw,
17674 .values = {
17675 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17676 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17677 0
17678 },
17679};
17680
17681static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17682 HDA_BIND_VOL("Master Playback Volume",
17683 &alc663_asus_two_bind_master_vol),
17684 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17685 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17686 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17687 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17688 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17689 { } /* end */
17690};
17691
17692static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17693 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17694 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17695 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17696 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17697 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17698 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17699 { } /* end */
17700};
17701
17702static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17703 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17704 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17705 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17706 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17707 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17708
17709 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17710 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17711 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17712 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17713 { } /* end */
17714};
17715
17716static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17717 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17718 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17719 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17720
17721 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17722 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17723 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17724 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17725 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17726 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17727 { } /* end */
17728};
17729
ebb83eeb
KY
17730static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17731 .ops = &snd_hda_bind_sw,
17732 .values = {
17733 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17734 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17735 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17736 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17737 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17738 0
17739 },
17740};
17741
17742static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17743 .ops = &snd_hda_bind_sw,
17744 .values = {
17745 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17746 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17747 0
17748 },
17749};
17750
17751static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17752 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17753 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17754 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17755 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17756 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17757 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17758 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17759 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17760 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17761 { } /* end */
17762};
17763
17764static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17765 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17766 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17767 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17768 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17769 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17770 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17771 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17772 { } /* end */
17773};
17774
17775
bc9f98a9
KY
17776static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17777 {
17778 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17779 .name = "Channel Mode",
17780 .info = alc_ch_mode_info,
17781 .get = alc_ch_mode_get,
17782 .put = alc_ch_mode_put,
17783 },
17784 { } /* end */
17785};
17786
17787static struct hda_verb alc662_init_verbs[] = {
17788 /* ADC: mute amp left and right */
17789 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17790 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17791
b60dd394
KY
17792 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17793 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17794 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17795 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17796 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17797 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17798
17799 /* Front Pin: output 0 (0x0c) */
17800 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17801 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17802
17803 /* Rear Pin: output 1 (0x0d) */
17804 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17805 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17806
17807 /* CLFE Pin: output 2 (0x0e) */
17808 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17809 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17810
17811 /* Mic (rear) pin: input vref at 80% */
17812 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17813 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17814 /* Front Mic pin: input vref at 80% */
17815 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17816 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17817 /* Line In pin: input */
17818 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17819 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17820 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17821 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17822 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17823 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17824 /* CD pin widget for input */
17825 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17826
17827 /* FIXME: use matrix-type input source selection */
17828 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17829 /* Input mixer */
17830 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17831 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
17832
17833 /* always trun on EAPD */
17834 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17835 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17836
bc9f98a9
KY
17837 { }
17838};
17839
cec27c89
KY
17840static struct hda_verb alc663_init_verbs[] = {
17841 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17842 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17843 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17844 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17845 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17846 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17847 { }
17848};
17849
17850static struct hda_verb alc272_init_verbs[] = {
17851 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17852 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17853 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17854 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17855 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17856 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17857 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17858 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17859 { }
17860};
17861
bc9f98a9
KY
17862static struct hda_verb alc662_sue_init_verbs[] = {
17863 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17864 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17865 {}
17866};
17867
17868static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17869 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17870 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17871 {}
bc9f98a9
KY
17872};
17873
8c427226
KY
17874/* Set Unsolicited Event*/
17875static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17876 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17877 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17878 {}
17879};
17880
6dda9f4a 17881static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17882 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17883 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17884 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17885 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17886 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17887 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17888 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17889 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17890 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17891 {}
17892};
17893
17894static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17895 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17896 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17897 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17898 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17899 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17900 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17901 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17902 {}
17903};
17904
17905static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17906 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17907 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17908 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17909 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17910 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17911 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17912 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17913 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17914 {}
17915};
6dda9f4a 17916
f1d4e28b
KY
17917static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17918 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17919 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17920 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17921 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17922 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17923 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17924 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17925 {}
17926};
6dda9f4a 17927
f1d4e28b
KY
17928static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17929 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17930 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17931 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17932 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17933 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17934 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17935 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17936 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17937 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
17938 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17939 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
17940 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17941 {}
17942};
17943
17944static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17945 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17946 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17947 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17948 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17949 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17950 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17951 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17952 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17953 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17954 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17955 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17956 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
17957 {}
17958};
17959
17960static struct hda_verb alc663_g71v_init_verbs[] = {
17961 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17962 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17963 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17964
17965 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17966 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17967 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17968
17969 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17970 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17971 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17972 {}
17973};
17974
17975static struct hda_verb alc663_g50v_init_verbs[] = {
17976 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17977 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17978 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17979
17980 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17981 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17982 {}
17983};
17984
f1d4e28b
KY
17985static struct hda_verb alc662_ecs_init_verbs[] = {
17986 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17987 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17988 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17989 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17990 {}
17991};
17992
622e84cd
KY
17993static struct hda_verb alc272_dell_zm1_init_verbs[] = {
17994 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17995 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17996 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17997 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17998 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17999 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18000 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18001 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18002 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18003 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18004 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18005 {}
18006};
18007
18008static struct hda_verb alc272_dell_init_verbs[] = {
18009 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18010 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18011 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18012 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18013 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18014 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18015 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18016 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18017 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18018 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18019 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18020 {}
18021};
18022
ebb83eeb
KY
18023static struct hda_verb alc663_mode7_init_verbs[] = {
18024 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18025 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18026 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18027 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18028 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18029 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18030 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18031 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18032 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18033 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18034 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18035 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18036 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18037 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18038 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18039 {}
18040};
18041
18042static struct hda_verb alc663_mode8_init_verbs[] = {
18043 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18044 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18045 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18046 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18047 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18048 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18049 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18050 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18051 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18052 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18053 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18054 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18055 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18056 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18057 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18058 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18059 {}
18060};
18061
f1d4e28b
KY
18062static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18063 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18064 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18065 { } /* end */
18066};
18067
622e84cd
KY
18068static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18069 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18070 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18071 { } /* end */
18072};
18073
bc9f98a9
KY
18074static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
18075{
18076 unsigned int present;
f12ab1e0 18077 unsigned char bits;
bc9f98a9 18078
864f92be 18079 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 18080 bits = present ? HDA_AMP_MUTE : 0;
864f92be 18081
47fd830a
TI
18082 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18083 HDA_AMP_MUTE, bits);
bc9f98a9
KY
18084}
18085
18086static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
18087{
18088 unsigned int present;
f12ab1e0 18089 unsigned char bits;
bc9f98a9 18090
864f92be 18091 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 18092 bits = present ? HDA_AMP_MUTE : 0;
864f92be 18093
47fd830a
TI
18094 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18095 HDA_AMP_MUTE, bits);
18096 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18097 HDA_AMP_MUTE, bits);
bc9f98a9
KY
18098}
18099
18100static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
18101 unsigned int res)
18102{
18103 if ((res >> 26) == ALC880_HP_EVENT)
18104 alc662_lenovo_101e_all_automute(codec);
18105 if ((res >> 26) == ALC880_FRONT_EVENT)
18106 alc662_lenovo_101e_ispeaker_automute(codec);
18107}
18108
291702f0
KY
18109/* unsolicited event for HP jack sensing */
18110static void alc662_eeepc_unsol_event(struct hda_codec *codec,
18111 unsigned int res)
18112{
291702f0 18113 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 18114 alc_mic_automute(codec);
42171c17
TI
18115 else
18116 alc262_hippo_unsol_event(codec, res);
291702f0
KY
18117}
18118
4f5d1706
TI
18119static void alc662_eeepc_setup(struct hda_codec *codec)
18120{
18121 struct alc_spec *spec = codec->spec;
18122
18123 alc262_hippo1_setup(codec);
18124 spec->ext_mic.pin = 0x18;
18125 spec->ext_mic.mux_idx = 0;
18126 spec->int_mic.pin = 0x19;
18127 spec->int_mic.mux_idx = 1;
18128 spec->auto_mic = 1;
18129}
18130
291702f0
KY
18131static void alc662_eeepc_inithook(struct hda_codec *codec)
18132{
4f5d1706
TI
18133 alc262_hippo_automute(codec);
18134 alc_mic_automute(codec);
291702f0
KY
18135}
18136
4f5d1706 18137static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18138{
42171c17
TI
18139 struct alc_spec *spec = codec->spec;
18140
18141 spec->autocfg.hp_pins[0] = 0x14;
18142 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
18143}
18144
4f5d1706
TI
18145#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
18146
6dda9f4a
KY
18147static void alc663_m51va_speaker_automute(struct hda_codec *codec)
18148{
18149 unsigned int present;
18150 unsigned char bits;
18151
864f92be 18152 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 18153 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 18154 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18155 HDA_AMP_MUTE, bits);
f1d4e28b 18156 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18157 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18158}
18159
18160static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
18161{
18162 unsigned int present;
18163 unsigned char bits;
18164
864f92be 18165 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
18166 bits = present ? HDA_AMP_MUTE : 0;
18167 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18168 HDA_AMP_MUTE, bits);
f1d4e28b 18169 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18170 HDA_AMP_MUTE, bits);
f1d4e28b 18171 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18172 HDA_AMP_MUTE, bits);
f1d4e28b 18173 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18174 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18175}
18176
18177static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
18178{
18179 unsigned int present;
18180 unsigned char bits;
18181
864f92be 18182 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18183 bits = present ? HDA_AMP_MUTE : 0;
18184 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18185 HDA_AMP_MUTE, bits);
f1d4e28b 18186 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18187 HDA_AMP_MUTE, bits);
f1d4e28b 18188 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18189 HDA_AMP_MUTE, bits);
f1d4e28b 18190 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18191 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18192}
18193
18194static void alc662_f5z_speaker_automute(struct hda_codec *codec)
18195{
18196 unsigned int present;
18197 unsigned char bits;
18198
864f92be 18199 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
18200 bits = present ? 0 : PIN_OUT;
18201 snd_hda_codec_write(codec, 0x14, 0,
18202 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
18203}
18204
18205static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
18206{
18207 unsigned int present1, present2;
18208
864f92be
WF
18209 present1 = snd_hda_jack_detect(codec, 0x21);
18210 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18211
18212 if (present1 || present2) {
18213 snd_hda_codec_write_cache(codec, 0x14, 0,
18214 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18215 } else {
18216 snd_hda_codec_write_cache(codec, 0x14, 0,
18217 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18218 }
18219}
18220
18221static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
18222{
18223 unsigned int present1, present2;
18224
864f92be
WF
18225 present1 = snd_hda_jack_detect(codec, 0x1b);
18226 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18227
18228 if (present1 || present2) {
18229 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18230 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 18231 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18232 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
18233 } else {
18234 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18235 HDA_AMP_MUTE, 0);
f1d4e28b 18236 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18237 HDA_AMP_MUTE, 0);
f1d4e28b 18238 }
6dda9f4a
KY
18239}
18240
ebb83eeb
KY
18241static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
18242{
18243 unsigned int present1, present2;
18244
18245 present1 = snd_hda_codec_read(codec, 0x1b, 0,
18246 AC_VERB_GET_PIN_SENSE, 0)
18247 & AC_PINSENSE_PRESENCE;
18248 present2 = snd_hda_codec_read(codec, 0x21, 0,
18249 AC_VERB_GET_PIN_SENSE, 0)
18250 & AC_PINSENSE_PRESENCE;
18251
18252 if (present1 || present2) {
18253 snd_hda_codec_write_cache(codec, 0x14, 0,
18254 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18255 snd_hda_codec_write_cache(codec, 0x17, 0,
18256 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18257 } else {
18258 snd_hda_codec_write_cache(codec, 0x14, 0,
18259 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18260 snd_hda_codec_write_cache(codec, 0x17, 0,
18261 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18262 }
18263}
18264
18265static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
18266{
18267 unsigned int present1, present2;
18268
18269 present1 = snd_hda_codec_read(codec, 0x21, 0,
18270 AC_VERB_GET_PIN_SENSE, 0)
18271 & AC_PINSENSE_PRESENCE;
18272 present2 = snd_hda_codec_read(codec, 0x15, 0,
18273 AC_VERB_GET_PIN_SENSE, 0)
18274 & AC_PINSENSE_PRESENCE;
18275
18276 if (present1 || present2) {
18277 snd_hda_codec_write_cache(codec, 0x14, 0,
18278 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18279 snd_hda_codec_write_cache(codec, 0x17, 0,
18280 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18281 } else {
18282 snd_hda_codec_write_cache(codec, 0x14, 0,
18283 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18284 snd_hda_codec_write_cache(codec, 0x17, 0,
18285 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18286 }
18287}
18288
6dda9f4a
KY
18289static void alc663_m51va_unsol_event(struct hda_codec *codec,
18290 unsigned int res)
18291{
18292 switch (res >> 26) {
18293 case ALC880_HP_EVENT:
18294 alc663_m51va_speaker_automute(codec);
18295 break;
18296 case ALC880_MIC_EVENT:
4f5d1706 18297 alc_mic_automute(codec);
6dda9f4a
KY
18298 break;
18299 }
18300}
18301
4f5d1706
TI
18302static void alc663_m51va_setup(struct hda_codec *codec)
18303{
18304 struct alc_spec *spec = codec->spec;
18305 spec->ext_mic.pin = 0x18;
18306 spec->ext_mic.mux_idx = 0;
18307 spec->int_mic.pin = 0x12;
ebb83eeb 18308 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18309 spec->auto_mic = 1;
18310}
18311
6dda9f4a
KY
18312static void alc663_m51va_inithook(struct hda_codec *codec)
18313{
18314 alc663_m51va_speaker_automute(codec);
4f5d1706 18315 alc_mic_automute(codec);
6dda9f4a
KY
18316}
18317
f1d4e28b 18318/* ***************** Mode1 ******************************/
4f5d1706 18319#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
18320
18321static void alc663_mode1_setup(struct hda_codec *codec)
18322{
18323 struct alc_spec *spec = codec->spec;
18324 spec->ext_mic.pin = 0x18;
18325 spec->ext_mic.mux_idx = 0;
18326 spec->int_mic.pin = 0x19;
18327 spec->int_mic.mux_idx = 1;
18328 spec->auto_mic = 1;
18329}
18330
4f5d1706 18331#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 18332
f1d4e28b
KY
18333/* ***************** Mode2 ******************************/
18334static void alc662_mode2_unsol_event(struct hda_codec *codec,
18335 unsigned int res)
18336{
18337 switch (res >> 26) {
18338 case ALC880_HP_EVENT:
18339 alc662_f5z_speaker_automute(codec);
18340 break;
18341 case ALC880_MIC_EVENT:
4f5d1706 18342 alc_mic_automute(codec);
f1d4e28b
KY
18343 break;
18344 }
18345}
18346
ebb83eeb 18347#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 18348
f1d4e28b
KY
18349static void alc662_mode2_inithook(struct hda_codec *codec)
18350{
18351 alc662_f5z_speaker_automute(codec);
4f5d1706 18352 alc_mic_automute(codec);
f1d4e28b
KY
18353}
18354/* ***************** Mode3 ******************************/
18355static void alc663_mode3_unsol_event(struct hda_codec *codec,
18356 unsigned int res)
18357{
18358 switch (res >> 26) {
18359 case ALC880_HP_EVENT:
18360 alc663_two_hp_m1_speaker_automute(codec);
18361 break;
18362 case ALC880_MIC_EVENT:
4f5d1706 18363 alc_mic_automute(codec);
f1d4e28b
KY
18364 break;
18365 }
18366}
18367
ebb83eeb 18368#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 18369
f1d4e28b
KY
18370static void alc663_mode3_inithook(struct hda_codec *codec)
18371{
18372 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 18373 alc_mic_automute(codec);
f1d4e28b
KY
18374}
18375/* ***************** Mode4 ******************************/
18376static void alc663_mode4_unsol_event(struct hda_codec *codec,
18377 unsigned int res)
18378{
18379 switch (res >> 26) {
18380 case ALC880_HP_EVENT:
18381 alc663_21jd_two_speaker_automute(codec);
18382 break;
18383 case ALC880_MIC_EVENT:
4f5d1706 18384 alc_mic_automute(codec);
f1d4e28b
KY
18385 break;
18386 }
18387}
18388
ebb83eeb 18389#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 18390
f1d4e28b
KY
18391static void alc663_mode4_inithook(struct hda_codec *codec)
18392{
18393 alc663_21jd_two_speaker_automute(codec);
4f5d1706 18394 alc_mic_automute(codec);
f1d4e28b
KY
18395}
18396/* ***************** Mode5 ******************************/
18397static void alc663_mode5_unsol_event(struct hda_codec *codec,
18398 unsigned int res)
18399{
18400 switch (res >> 26) {
18401 case ALC880_HP_EVENT:
18402 alc663_15jd_two_speaker_automute(codec);
18403 break;
18404 case ALC880_MIC_EVENT:
4f5d1706 18405 alc_mic_automute(codec);
f1d4e28b
KY
18406 break;
18407 }
18408}
18409
ebb83eeb 18410#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 18411
f1d4e28b
KY
18412static void alc663_mode5_inithook(struct hda_codec *codec)
18413{
18414 alc663_15jd_two_speaker_automute(codec);
4f5d1706 18415 alc_mic_automute(codec);
f1d4e28b
KY
18416}
18417/* ***************** Mode6 ******************************/
18418static void alc663_mode6_unsol_event(struct hda_codec *codec,
18419 unsigned int res)
18420{
18421 switch (res >> 26) {
18422 case ALC880_HP_EVENT:
18423 alc663_two_hp_m2_speaker_automute(codec);
18424 break;
18425 case ALC880_MIC_EVENT:
4f5d1706 18426 alc_mic_automute(codec);
f1d4e28b
KY
18427 break;
18428 }
18429}
18430
ebb83eeb 18431#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 18432
f1d4e28b
KY
18433static void alc663_mode6_inithook(struct hda_codec *codec)
18434{
18435 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 18436 alc_mic_automute(codec);
f1d4e28b
KY
18437}
18438
ebb83eeb
KY
18439/* ***************** Mode7 ******************************/
18440static void alc663_mode7_unsol_event(struct hda_codec *codec,
18441 unsigned int res)
18442{
18443 switch (res >> 26) {
18444 case ALC880_HP_EVENT:
18445 alc663_two_hp_m7_speaker_automute(codec);
18446 break;
18447 case ALC880_MIC_EVENT:
18448 alc_mic_automute(codec);
18449 break;
18450 }
18451}
18452
18453#define alc663_mode7_setup alc663_mode1_setup
18454
18455static void alc663_mode7_inithook(struct hda_codec *codec)
18456{
18457 alc663_two_hp_m7_speaker_automute(codec);
18458 alc_mic_automute(codec);
18459}
18460
18461/* ***************** Mode8 ******************************/
18462static void alc663_mode8_unsol_event(struct hda_codec *codec,
18463 unsigned int res)
18464{
18465 switch (res >> 26) {
18466 case ALC880_HP_EVENT:
18467 alc663_two_hp_m8_speaker_automute(codec);
18468 break;
18469 case ALC880_MIC_EVENT:
18470 alc_mic_automute(codec);
18471 break;
18472 }
18473}
18474
18475#define alc663_mode8_setup alc663_m51va_setup
18476
18477static void alc663_mode8_inithook(struct hda_codec *codec)
18478{
18479 alc663_two_hp_m8_speaker_automute(codec);
18480 alc_mic_automute(codec);
18481}
18482
6dda9f4a
KY
18483static void alc663_g71v_hp_automute(struct hda_codec *codec)
18484{
18485 unsigned int present;
18486 unsigned char bits;
18487
864f92be 18488 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
18489 bits = present ? HDA_AMP_MUTE : 0;
18490 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18491 HDA_AMP_MUTE, bits);
18492 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18493 HDA_AMP_MUTE, bits);
18494}
18495
18496static void alc663_g71v_front_automute(struct hda_codec *codec)
18497{
18498 unsigned int present;
18499 unsigned char bits;
18500
864f92be 18501 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
18502 bits = present ? HDA_AMP_MUTE : 0;
18503 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18504 HDA_AMP_MUTE, bits);
18505}
18506
18507static void alc663_g71v_unsol_event(struct hda_codec *codec,
18508 unsigned int res)
18509{
18510 switch (res >> 26) {
18511 case ALC880_HP_EVENT:
18512 alc663_g71v_hp_automute(codec);
18513 break;
18514 case ALC880_FRONT_EVENT:
18515 alc663_g71v_front_automute(codec);
18516 break;
18517 case ALC880_MIC_EVENT:
4f5d1706 18518 alc_mic_automute(codec);
6dda9f4a
KY
18519 break;
18520 }
18521}
18522
4f5d1706
TI
18523#define alc663_g71v_setup alc663_m51va_setup
18524
6dda9f4a
KY
18525static void alc663_g71v_inithook(struct hda_codec *codec)
18526{
18527 alc663_g71v_front_automute(codec);
18528 alc663_g71v_hp_automute(codec);
4f5d1706 18529 alc_mic_automute(codec);
6dda9f4a
KY
18530}
18531
18532static void alc663_g50v_unsol_event(struct hda_codec *codec,
18533 unsigned int res)
18534{
18535 switch (res >> 26) {
18536 case ALC880_HP_EVENT:
18537 alc663_m51va_speaker_automute(codec);
18538 break;
18539 case ALC880_MIC_EVENT:
4f5d1706 18540 alc_mic_automute(codec);
6dda9f4a
KY
18541 break;
18542 }
18543}
18544
4f5d1706
TI
18545#define alc663_g50v_setup alc663_m51va_setup
18546
6dda9f4a
KY
18547static void alc663_g50v_inithook(struct hda_codec *codec)
18548{
18549 alc663_m51va_speaker_automute(codec);
4f5d1706 18550 alc_mic_automute(codec);
6dda9f4a
KY
18551}
18552
f1d4e28b
KY
18553static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18554 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18555 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b 18556
5f99f86a 18557 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
18558 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18559 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b 18560
5f99f86a 18561 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
18562 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18563 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
f1d4e28b
KY
18564 { } /* end */
18565};
18566
9541ba1d
CP
18567static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18568 /* Master Playback automatically created from Speaker and Headphone */
18569 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18570 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18571 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18572 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18573
8607f7c4
DH
18574 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18575 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 18576 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9541ba1d 18577
28c4edb7
DH
18578 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18579 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 18580 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9541ba1d
CP
18581 { } /* end */
18582};
18583
cb53c626
TI
18584#ifdef CONFIG_SND_HDA_POWER_SAVE
18585#define alc662_loopbacks alc880_loopbacks
18586#endif
18587
bc9f98a9 18588
def319f9 18589/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18590#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18591#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18592#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18593#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18594
18595/*
18596 * configuration and preset
18597 */
18598static const char *alc662_models[ALC662_MODEL_LAST] = {
18599 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18600 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18601 [ALC662_3ST_6ch] = "3stack-6ch",
18602 [ALC662_5ST_DIG] = "6stack-dig",
18603 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18604 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18605 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18606 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18607 [ALC663_ASUS_M51VA] = "m51va",
18608 [ALC663_ASUS_G71V] = "g71v",
18609 [ALC663_ASUS_H13] = "h13",
18610 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18611 [ALC663_ASUS_MODE1] = "asus-mode1",
18612 [ALC662_ASUS_MODE2] = "asus-mode2",
18613 [ALC663_ASUS_MODE3] = "asus-mode3",
18614 [ALC663_ASUS_MODE4] = "asus-mode4",
18615 [ALC663_ASUS_MODE5] = "asus-mode5",
18616 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18617 [ALC663_ASUS_MODE7] = "asus-mode7",
18618 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18619 [ALC272_DELL] = "dell",
18620 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18621 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18622 [ALC662_AUTO] = "auto",
18623};
18624
18625static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18626 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18627 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18628 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18629 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18630 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18631 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18632 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18633 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18634 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18635 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18636 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18637 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18638 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18639 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18640 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18641 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18642 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18643 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18644 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18645 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18646 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18647 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18648 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18649 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18650 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18651 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18652 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18653 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18654 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18655 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18656 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18657 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18658 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18659 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18660 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18661 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18662 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18663 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18664 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18665 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18666 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18667 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18668 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18669 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18670 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18671 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18672 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18673 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18674 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18675 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18676 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18677 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18678 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18679 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18680 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18681 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18682 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18683 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18684 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18685 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18686 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18687 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18688 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18689 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18690 ALC662_3ST_6ch_DIG),
4dee8baa 18691 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18692 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
18693 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18694 ALC662_3ST_6ch_DIG),
6227cdce 18695 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18696 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18697 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18698 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18699 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18700 ALC662_3ST_6ch_DIG),
dea0a509
TI
18701 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18702 ALC663_ASUS_H13),
bc9f98a9
KY
18703 {}
18704};
18705
18706static struct alc_config_preset alc662_presets[] = {
18707 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18708 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
18709 .init_verbs = { alc662_init_verbs },
18710 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18711 .dac_nids = alc662_dac_nids,
18712 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18713 .dig_in_nid = ALC662_DIGIN_NID,
18714 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18715 .channel_mode = alc662_3ST_2ch_modes,
18716 .input_mux = &alc662_capture_source,
18717 },
18718 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18719 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18720 .init_verbs = { alc662_init_verbs },
18721 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18722 .dac_nids = alc662_dac_nids,
18723 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18724 .dig_in_nid = ALC662_DIGIN_NID,
18725 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18726 .channel_mode = alc662_3ST_6ch_modes,
18727 .need_dac_fix = 1,
18728 .input_mux = &alc662_capture_source,
f12ab1e0 18729 },
bc9f98a9 18730 [ALC662_3ST_6ch] = {
f9e336f6 18731 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18732 .init_verbs = { alc662_init_verbs },
18733 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18734 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18735 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18736 .channel_mode = alc662_3ST_6ch_modes,
18737 .need_dac_fix = 1,
18738 .input_mux = &alc662_capture_source,
f12ab1e0 18739 },
bc9f98a9 18740 [ALC662_5ST_DIG] = {
f9e336f6 18741 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18742 .init_verbs = { alc662_init_verbs },
18743 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18744 .dac_nids = alc662_dac_nids,
18745 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18746 .dig_in_nid = ALC662_DIGIN_NID,
18747 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18748 .channel_mode = alc662_5stack_modes,
18749 .input_mux = &alc662_capture_source,
18750 },
18751 [ALC662_LENOVO_101E] = {
f9e336f6 18752 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
18753 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18754 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18755 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18756 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18757 .channel_mode = alc662_3ST_2ch_modes,
18758 .input_mux = &alc662_lenovo_101e_capture_source,
18759 .unsol_event = alc662_lenovo_101e_unsol_event,
18760 .init_hook = alc662_lenovo_101e_all_automute,
18761 },
291702f0 18762 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18763 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
18764 .init_verbs = { alc662_init_verbs,
18765 alc662_eeepc_sue_init_verbs },
18766 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18767 .dac_nids = alc662_dac_nids,
291702f0
KY
18768 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18769 .channel_mode = alc662_3ST_2ch_modes,
291702f0 18770 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18771 .setup = alc662_eeepc_setup,
291702f0
KY
18772 .init_hook = alc662_eeepc_inithook,
18773 },
8c427226 18774 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18775 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18776 alc662_chmode_mixer },
18777 .init_verbs = { alc662_init_verbs,
18778 alc662_eeepc_ep20_sue_init_verbs },
18779 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18780 .dac_nids = alc662_dac_nids,
8c427226
KY
18781 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18782 .channel_mode = alc662_3ST_6ch_modes,
18783 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 18784 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18785 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
18786 .init_hook = alc662_eeepc_ep20_inithook,
18787 },
f1d4e28b 18788 [ALC662_ECS] = {
f9e336f6 18789 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
18790 .init_verbs = { alc662_init_verbs,
18791 alc662_ecs_init_verbs },
18792 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18793 .dac_nids = alc662_dac_nids,
18794 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18795 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18796 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18797 .setup = alc662_eeepc_setup,
f1d4e28b
KY
18798 .init_hook = alc662_eeepc_inithook,
18799 },
6dda9f4a 18800 [ALC663_ASUS_M51VA] = {
f9e336f6 18801 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18802 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18803 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18804 .dac_nids = alc662_dac_nids,
18805 .dig_out_nid = ALC662_DIGOUT_NID,
18806 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18807 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18808 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18809 .setup = alc663_m51va_setup,
6dda9f4a
KY
18810 .init_hook = alc663_m51va_inithook,
18811 },
18812 [ALC663_ASUS_G71V] = {
f9e336f6 18813 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
18814 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18815 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
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,
6dda9f4a 18820 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 18821 .setup = alc663_g71v_setup,
6dda9f4a
KY
18822 .init_hook = alc663_g71v_inithook,
18823 },
18824 [ALC663_ASUS_H13] = {
f9e336f6 18825 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18826 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18827 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18828 .dac_nids = alc662_dac_nids,
18829 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18830 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
18831 .unsol_event = alc663_m51va_unsol_event,
18832 .init_hook = alc663_m51va_inithook,
18833 },
18834 [ALC663_ASUS_G50V] = {
f9e336f6 18835 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
18836 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18837 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18838 .dac_nids = alc662_dac_nids,
18839 .dig_out_nid = ALC662_DIGOUT_NID,
18840 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18841 .channel_mode = alc662_3ST_6ch_modes,
18842 .input_mux = &alc663_capture_source,
18843 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 18844 .setup = alc663_g50v_setup,
6dda9f4a
KY
18845 .init_hook = alc663_g50v_inithook,
18846 },
f1d4e28b 18847 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18848 .mixers = { alc663_m51va_mixer },
18849 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18850 .init_verbs = { alc662_init_verbs,
18851 alc663_21jd_amic_init_verbs },
18852 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18853 .hp_nid = 0x03,
18854 .dac_nids = alc662_dac_nids,
18855 .dig_out_nid = ALC662_DIGOUT_NID,
18856 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18857 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18858 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18859 .setup = alc663_mode1_setup,
f1d4e28b
KY
18860 .init_hook = alc663_mode1_inithook,
18861 },
18862 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18863 .mixers = { alc662_1bjd_mixer },
18864 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18865 .init_verbs = { alc662_init_verbs,
18866 alc662_1bjd_amic_init_verbs },
18867 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18868 .dac_nids = alc662_dac_nids,
18869 .dig_out_nid = ALC662_DIGOUT_NID,
18870 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18871 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18872 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18873 .setup = alc662_mode2_setup,
f1d4e28b
KY
18874 .init_hook = alc662_mode2_inithook,
18875 },
18876 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18877 .mixers = { alc663_two_hp_m1_mixer },
18878 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18879 .init_verbs = { alc662_init_verbs,
18880 alc663_two_hp_amic_m1_init_verbs },
18881 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18882 .hp_nid = 0x03,
18883 .dac_nids = alc662_dac_nids,
18884 .dig_out_nid = ALC662_DIGOUT_NID,
18885 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18886 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18887 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 18888 .setup = alc663_mode3_setup,
f1d4e28b
KY
18889 .init_hook = alc663_mode3_inithook,
18890 },
18891 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18892 .mixers = { alc663_asus_21jd_clfe_mixer },
18893 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18894 .init_verbs = { alc662_init_verbs,
18895 alc663_21jd_amic_init_verbs},
18896 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18897 .hp_nid = 0x03,
18898 .dac_nids = alc662_dac_nids,
18899 .dig_out_nid = ALC662_DIGOUT_NID,
18900 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18901 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18902 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18903 .setup = alc663_mode4_setup,
f1d4e28b
KY
18904 .init_hook = alc663_mode4_inithook,
18905 },
18906 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18907 .mixers = { alc663_asus_15jd_clfe_mixer },
18908 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18909 .init_verbs = { alc662_init_verbs,
18910 alc663_15jd_amic_init_verbs },
18911 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18912 .hp_nid = 0x03,
18913 .dac_nids = alc662_dac_nids,
18914 .dig_out_nid = ALC662_DIGOUT_NID,
18915 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18916 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18917 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 18918 .setup = alc663_mode5_setup,
f1d4e28b
KY
18919 .init_hook = alc663_mode5_inithook,
18920 },
18921 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18922 .mixers = { alc663_two_hp_m2_mixer },
18923 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18924 .init_verbs = { alc662_init_verbs,
18925 alc663_two_hp_amic_m2_init_verbs },
18926 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18927 .hp_nid = 0x03,
18928 .dac_nids = alc662_dac_nids,
18929 .dig_out_nid = ALC662_DIGOUT_NID,
18930 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18931 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18932 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 18933 .setup = alc663_mode6_setup,
f1d4e28b
KY
18934 .init_hook = alc663_mode6_inithook,
18935 },
ebb83eeb
KY
18936 [ALC663_ASUS_MODE7] = {
18937 .mixers = { alc663_mode7_mixer },
18938 .cap_mixer = alc662_auto_capture_mixer,
18939 .init_verbs = { alc662_init_verbs,
18940 alc663_mode7_init_verbs },
18941 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18942 .hp_nid = 0x03,
18943 .dac_nids = alc662_dac_nids,
18944 .dig_out_nid = ALC662_DIGOUT_NID,
18945 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18946 .channel_mode = alc662_3ST_2ch_modes,
18947 .unsol_event = alc663_mode7_unsol_event,
18948 .setup = alc663_mode7_setup,
18949 .init_hook = alc663_mode7_inithook,
18950 },
18951 [ALC663_ASUS_MODE8] = {
18952 .mixers = { alc663_mode8_mixer },
18953 .cap_mixer = alc662_auto_capture_mixer,
18954 .init_verbs = { alc662_init_verbs,
18955 alc663_mode8_init_verbs },
18956 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18957 .hp_nid = 0x03,
18958 .dac_nids = alc662_dac_nids,
18959 .dig_out_nid = ALC662_DIGOUT_NID,
18960 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18961 .channel_mode = alc662_3ST_2ch_modes,
18962 .unsol_event = alc663_mode8_unsol_event,
18963 .setup = alc663_mode8_setup,
18964 .init_hook = alc663_mode8_inithook,
18965 },
622e84cd
KY
18966 [ALC272_DELL] = {
18967 .mixers = { alc663_m51va_mixer },
18968 .cap_mixer = alc272_auto_capture_mixer,
18969 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
18970 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18971 .dac_nids = alc662_dac_nids,
18972 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18973 .adc_nids = alc272_adc_nids,
18974 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18975 .capsrc_nids = alc272_capsrc_nids,
18976 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18977 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18978 .setup = alc663_m51va_setup,
622e84cd
KY
18979 .init_hook = alc663_m51va_inithook,
18980 },
18981 [ALC272_DELL_ZM1] = {
18982 .mixers = { alc663_m51va_mixer },
18983 .cap_mixer = alc662_auto_capture_mixer,
18984 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
18985 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18986 .dac_nids = alc662_dac_nids,
18987 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18988 .adc_nids = alc662_adc_nids,
b59bdf3b 18989 .num_adc_nids = 1,
622e84cd
KY
18990 .capsrc_nids = alc662_capsrc_nids,
18991 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18992 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18993 .setup = alc663_m51va_setup,
622e84cd
KY
18994 .init_hook = alc663_m51va_inithook,
18995 },
9541ba1d
CP
18996 [ALC272_SAMSUNG_NC10] = {
18997 .mixers = { alc272_nc10_mixer },
18998 .init_verbs = { alc662_init_verbs,
18999 alc663_21jd_amic_init_verbs },
19000 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19001 .dac_nids = alc272_dac_nids,
19002 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19003 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 19004 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 19005 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 19006 .setup = alc663_mode4_setup,
9541ba1d
CP
19007 .init_hook = alc663_mode4_inithook,
19008 },
bc9f98a9
KY
19009};
19010
19011
19012/*
19013 * BIOS auto configuration
19014 */
19015
7085ec12
TI
19016/* convert from MIX nid to DAC */
19017static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
19018{
19019 if (nid == 0x0f)
19020 return 0x02;
19021 else if (nid >= 0x0c && nid <= 0x0e)
19022 return nid - 0x0c + 0x02;
cc1c452e
DH
19023 else if (nid == 0x26) /* ALC887-VD has this DAC too */
19024 return 0x25;
7085ec12
TI
19025 else
19026 return 0;
19027}
19028
19029/* get MIX nid connected to the given pin targeted to DAC */
19030static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
19031 hda_nid_t dac)
19032{
cc1c452e 19033 hda_nid_t mix[5];
7085ec12
TI
19034 int i, num;
19035
19036 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
19037 for (i = 0; i < num; i++) {
19038 if (alc662_mix_to_dac(mix[i]) == dac)
19039 return mix[i];
19040 }
19041 return 0;
19042}
19043
19044/* look for an empty DAC slot */
19045static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
19046{
19047 struct alc_spec *spec = codec->spec;
19048 hda_nid_t srcs[5];
19049 int i, j, num;
19050
19051 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
19052 if (num < 0)
19053 return 0;
19054 for (i = 0; i < num; i++) {
19055 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
19056 if (!nid)
19057 continue;
19058 for (j = 0; j < spec->multiout.num_dacs; j++)
19059 if (spec->multiout.dac_nids[j] == nid)
19060 break;
19061 if (j >= spec->multiout.num_dacs)
19062 return nid;
19063 }
19064 return 0;
19065}
19066
19067/* fill in the dac_nids table from the parsed pin configuration */
19068static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19069 const struct auto_pin_cfg *cfg)
19070{
19071 struct alc_spec *spec = codec->spec;
19072 int i;
19073 hda_nid_t dac;
19074
19075 spec->multiout.dac_nids = spec->private_dac_nids;
19076 for (i = 0; i < cfg->line_outs; i++) {
19077 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
19078 if (!dac)
19079 continue;
19080 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19081 }
19082 return 0;
19083}
19084
bcb2f0f5
TI
19085static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
19086 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19087{
bcb2f0f5 19088 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
7085ec12
TI
19089 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
19090}
19091
bcb2f0f5
TI
19092static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19093 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19094{
bcb2f0f5 19095 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
7085ec12
TI
19096 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19097}
19098
bcb2f0f5
TI
19099#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19100 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19101#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19102 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
7085ec12
TI
19103#define alc662_add_stereo_vol(spec, pfx, nid) \
19104 alc662_add_vol_ctl(spec, pfx, nid, 3)
19105#define alc662_add_stereo_sw(spec, pfx, nid) \
19106 alc662_add_sw_ctl(spec, pfx, nid, 3)
19107
bc9f98a9 19108/* add playback controls from the parsed DAC table */
7085ec12 19109static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
19110 const struct auto_pin_cfg *cfg)
19111{
7085ec12 19112 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19113 static const char *chname[4] = {
19114 "Front", "Surround", NULL /*CLFE*/, "Side"
19115 };
bcb2f0f5 19116 const char *pfx = alc_get_line_out_pfx(cfg, true);
7085ec12 19117 hda_nid_t nid, mix;
bc9f98a9
KY
19118 int i, err;
19119
19120 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
19121 nid = spec->multiout.dac_nids[i];
19122 if (!nid)
19123 continue;
19124 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
19125 if (!mix)
bc9f98a9 19126 continue;
bcb2f0f5 19127 if (!pfx && i == 2) {
bc9f98a9 19128 /* Center/LFE */
7085ec12 19129 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
19130 if (err < 0)
19131 return err;
7085ec12 19132 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
19133 if (err < 0)
19134 return err;
7085ec12 19135 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
19136 if (err < 0)
19137 return err;
7085ec12 19138 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
19139 if (err < 0)
19140 return err;
19141 } else {
bcb2f0f5
TI
19142 const char *name = pfx;
19143 if (!name)
19144 name = chname[i];
19145 err = __alc662_add_vol_ctl(spec, name, nid, i, 3);
bc9f98a9
KY
19146 if (err < 0)
19147 return err;
bcb2f0f5 19148 err = __alc662_add_sw_ctl(spec, name, mix, i, 3);
bc9f98a9
KY
19149 if (err < 0)
19150 return err;
19151 }
19152 }
19153 return 0;
19154}
19155
19156/* add playback controls for speaker and HP outputs */
7085ec12
TI
19157/* return DAC nid if any new DAC is assigned */
19158static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
19159 const char *pfx)
19160{
7085ec12
TI
19161 struct alc_spec *spec = codec->spec;
19162 hda_nid_t nid, mix;
bc9f98a9 19163 int err;
bc9f98a9
KY
19164
19165 if (!pin)
19166 return 0;
7085ec12
TI
19167 nid = alc662_look_for_dac(codec, pin);
19168 if (!nid) {
7085ec12
TI
19169 /* the corresponding DAC is already occupied */
19170 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19171 return 0; /* no way */
19172 /* create a switch only */
0afe5f89 19173 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 19174 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
19175 }
19176
7085ec12
TI
19177 mix = alc662_dac_to_mix(codec, pin, nid);
19178 if (!mix)
19179 return 0;
19180 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19181 if (err < 0)
19182 return err;
19183 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19184 if (err < 0)
19185 return err;
19186 return nid;
bc9f98a9
KY
19187}
19188
19189/* create playback/capture controls for input pins */
05f5f477 19190#define alc662_auto_create_input_ctls \
4b7348a1 19191 alc882_auto_create_input_ctls
bc9f98a9
KY
19192
19193static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19194 hda_nid_t nid, int pin_type,
7085ec12 19195 hda_nid_t dac)
bc9f98a9 19196{
7085ec12 19197 int i, num;
ce503f38 19198 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 19199
f6c7e546 19200 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 19201 /* need the manual connection? */
7085ec12
TI
19202 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19203 if (num <= 1)
19204 return;
19205 for (i = 0; i < num; i++) {
19206 if (alc662_mix_to_dac(srcs[i]) != dac)
19207 continue;
19208 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
19209 return;
bc9f98a9
KY
19210 }
19211}
19212
19213static void alc662_auto_init_multi_out(struct hda_codec *codec)
19214{
19215 struct alc_spec *spec = codec->spec;
7085ec12 19216 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
19217 int i;
19218
19219 for (i = 0; i <= HDA_SIDE; i++) {
19220 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19221 if (nid)
baba8ee9 19222 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 19223 spec->multiout.dac_nids[i]);
bc9f98a9
KY
19224 }
19225}
19226
19227static void alc662_auto_init_hp_out(struct hda_codec *codec)
19228{
19229 struct alc_spec *spec = codec->spec;
19230 hda_nid_t pin;
19231
19232 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
19233 if (pin)
19234 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19235 spec->multiout.hp_nid);
f6c7e546
TI
19236 pin = spec->autocfg.speaker_pins[0];
19237 if (pin)
7085ec12
TI
19238 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19239 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
19240}
19241
bc9f98a9
KY
19242#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19243
19244static void alc662_auto_init_analog_input(struct hda_codec *codec)
19245{
19246 struct alc_spec *spec = codec->spec;
66ceeb6b 19247 struct auto_pin_cfg *cfg = &spec->autocfg;
bc9f98a9
KY
19248 int i;
19249
66ceeb6b
TI
19250 for (i = 0; i < cfg->num_inputs; i++) {
19251 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 19252 if (alc_is_input_pin(codec, nid)) {
30ea098f 19253 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
52ca15b7 19254 if (nid != ALC662_PIN_CD_NID &&
e82c025b 19255 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
19256 snd_hda_codec_write(codec, nid, 0,
19257 AC_VERB_SET_AMP_GAIN_MUTE,
19258 AMP_OUT_MUTE);
19259 }
19260 }
19261}
19262
f511b01c
TI
19263#define alc662_auto_init_input_src alc882_auto_init_input_src
19264
bc9f98a9
KY
19265static int alc662_parse_auto_config(struct hda_codec *codec)
19266{
19267 struct alc_spec *spec = codec->spec;
19268 int err;
19269 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19270
19271 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19272 alc662_ignore);
19273 if (err < 0)
19274 return err;
19275 if (!spec->autocfg.line_outs)
19276 return 0; /* can't find valid BIOS pin config */
19277
7085ec12 19278 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
19279 if (err < 0)
19280 return err;
7085ec12 19281 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19282 if (err < 0)
19283 return err;
7085ec12 19284 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
19285 spec->autocfg.speaker_pins[0],
19286 "Speaker");
19287 if (err < 0)
19288 return err;
7085ec12
TI
19289 if (err)
19290 spec->multiout.extra_out_nid[0] = err;
19291 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
19292 "Headphone");
19293 if (err < 0)
19294 return err;
7085ec12
TI
19295 if (err)
19296 spec->multiout.hp_nid = err;
05f5f477 19297 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19298 if (err < 0)
bc9f98a9
KY
19299 return err;
19300
19301 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19302
757899ac 19303 alc_auto_parse_digital(codec);
bc9f98a9 19304
603c4019 19305 if (spec->kctls.list)
d88897ea 19306 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19307
19308 spec->num_mux_defs = 1;
61b9b9b1 19309 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19310
cec27c89
KY
19311 add_verb(spec, alc662_init_verbs);
19312 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
d1eb57f4 19313 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
cec27c89
KY
19314 add_verb(spec, alc663_init_verbs);
19315
19316 if (codec->vendor_id == 0x10ec0272)
19317 add_verb(spec, alc272_init_verbs);
ee979a14
TI
19318
19319 err = alc_auto_add_mic_boost(codec);
19320 if (err < 0)
19321 return err;
19322
6227cdce
KY
19323 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19324 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19325 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19326 else
19327 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19328
8c87286f 19329 return 1;
bc9f98a9
KY
19330}
19331
19332/* additional initialization for auto-configuration model */
19333static void alc662_auto_init(struct hda_codec *codec)
19334{
f6c7e546 19335 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19336 alc662_auto_init_multi_out(codec);
19337 alc662_auto_init_hp_out(codec);
19338 alc662_auto_init_analog_input(codec);
f511b01c 19339 alc662_auto_init_input_src(codec);
757899ac 19340 alc_auto_init_digital(codec);
f6c7e546 19341 if (spec->unsol_event)
7fb0d78f 19342 alc_inithook(codec);
bc9f98a9
KY
19343}
19344
6be7948f
TB
19345static void alc272_fixup_mario(struct hda_codec *codec,
19346 const struct alc_fixup *fix, int pre_init) {
19347 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19348 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19349 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19350 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19351 (0 << AC_AMPCAP_MUTE_SHIFT)))
19352 printk(KERN_WARNING
19353 "hda_codec: failed to override amp caps for NID 0x2\n");
19354}
19355
6cb3b707 19356enum {
2df03514 19357 ALC662_FIXUP_ASPIRE,
6cb3b707 19358 ALC662_FIXUP_IDEAPAD,
6be7948f 19359 ALC272_FIXUP_MARIO,
6cb3b707
DH
19360};
19361
19362static const struct alc_fixup alc662_fixups[] = {
2df03514
DC
19363 [ALC662_FIXUP_ASPIRE] = {
19364 .pins = (const struct alc_pincfg[]) {
19365 { 0x15, 0x99130112 }, /* subwoofer */
19366 { }
19367 }
19368 },
6cb3b707
DH
19369 [ALC662_FIXUP_IDEAPAD] = {
19370 .pins = (const struct alc_pincfg[]) {
19371 { 0x17, 0x99130112 }, /* subwoofer */
19372 { }
19373 }
19374 },
6be7948f
TB
19375 [ALC272_FIXUP_MARIO] = {
19376 .func = alc272_fixup_mario,
19377 }
6cb3b707
DH
19378};
19379
19380static struct snd_pci_quirk alc662_fixup_tbl[] = {
2df03514 19381 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
a0e90acc 19382 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
d4118588 19383 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707
DH
19384 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
19385 {}
19386};
19387
6be7948f
TB
19388static const struct alc_model_fixup alc662_fixup_models[] = {
19389 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19390 {}
19391};
6cb3b707
DH
19392
19393
bc9f98a9
KY
19394static int patch_alc662(struct hda_codec *codec)
19395{
19396 struct alc_spec *spec;
19397 int err, board_config;
693194f3 19398 int coef;
bc9f98a9
KY
19399
19400 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19401 if (!spec)
19402 return -ENOMEM;
19403
19404 codec->spec = spec;
19405
da00c244
KY
19406 alc_auto_parse_customize_define(codec);
19407
2c3bf9ab
TI
19408 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19409
693194f3
KY
19410 coef = alc_read_coef_idx(codec, 0);
19411 if (coef == 0x8020 || coef == 0x8011)
c027ddcd 19412 alc_codec_rename(codec, "ALC661");
693194f3
KY
19413 else if (coef & (1 << 14) &&
19414 codec->bus->pci->subsystem_vendor == 0x1025 &&
19415 spec->cdefine.platform_type == 1)
c027ddcd 19416 alc_codec_rename(codec, "ALC272X");
693194f3
KY
19417 else if (coef == 0x4011)
19418 alc_codec_rename(codec, "ALC656");
274693f3 19419
bc9f98a9
KY
19420 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19421 alc662_models,
19422 alc662_cfg_tbl);
19423 if (board_config < 0) {
9a11f1aa
TI
19424 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19425 codec->chip_name);
bc9f98a9
KY
19426 board_config = ALC662_AUTO;
19427 }
19428
19429 if (board_config == ALC662_AUTO) {
6cb3b707 19430 alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 1);
bc9f98a9
KY
19431 /* automatic parse from the BIOS config */
19432 err = alc662_parse_auto_config(codec);
19433 if (err < 0) {
19434 alc_free(codec);
19435 return err;
8c87286f 19436 } else if (!err) {
bc9f98a9
KY
19437 printk(KERN_INFO
19438 "hda_codec: Cannot set up configuration "
19439 "from BIOS. Using base mode...\n");
19440 board_config = ALC662_3ST_2ch_DIG;
19441 }
19442 }
19443
dc1eae25 19444 if (has_cdefine_beep(codec)) {
8af2591d
TI
19445 err = snd_hda_attach_beep_device(codec, 0x1);
19446 if (err < 0) {
19447 alc_free(codec);
19448 return err;
19449 }
680cd536
KK
19450 }
19451
bc9f98a9 19452 if (board_config != ALC662_AUTO)
e9c364c0 19453 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19454
bc9f98a9
KY
19455 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19456 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19457
bc9f98a9
KY
19458 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19459 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19460
dd704698
TI
19461 if (!spec->adc_nids) {
19462 spec->adc_nids = alc662_adc_nids;
19463 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19464 }
19465 if (!spec->capsrc_nids)
19466 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19467
f9e336f6 19468 if (!spec->cap_mixer)
b59bdf3b 19469 set_capture_mixer(codec);
cec27c89 19470
dc1eae25 19471 if (has_cdefine_beep(codec)) {
da00c244
KY
19472 switch (codec->vendor_id) {
19473 case 0x10ec0662:
19474 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19475 break;
19476 case 0x10ec0272:
19477 case 0x10ec0663:
19478 case 0x10ec0665:
19479 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19480 break;
19481 case 0x10ec0273:
19482 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19483 break;
19484 }
cec27c89 19485 }
2134ea4f
TI
19486 spec->vmaster_nid = 0x02;
19487
bc9f98a9 19488 codec->patch_ops = alc_patch_ops;
6cb3b707 19489 if (board_config == ALC662_AUTO) {
bc9f98a9 19490 spec->init_hook = alc662_auto_init;
6be7948f
TB
19491 alc_pick_fixup_model(codec, alc662_fixup_models,
19492 alc662_fixup_tbl, alc662_fixups, 0);
6cb3b707
DH
19493 }
19494
bf1b0225
KY
19495 alc_init_jacks(codec);
19496
cb53c626
TI
19497#ifdef CONFIG_SND_HDA_POWER_SAVE
19498 if (!spec->loopback.amplist)
19499 spec->loopback.amplist = alc662_loopbacks;
19500#endif
bc9f98a9
KY
19501
19502 return 0;
19503}
19504
274693f3
KY
19505static int patch_alc888(struct hda_codec *codec)
19506{
19507 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19508 kfree(codec->chip_name);
01e0f137
KY
19509 if (codec->vendor_id == 0x10ec0887)
19510 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19511 else
19512 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19513 if (!codec->chip_name) {
19514 alc_free(codec);
274693f3 19515 return -ENOMEM;
ac2c92e0
TI
19516 }
19517 return patch_alc662(codec);
274693f3 19518 }
ac2c92e0 19519 return patch_alc882(codec);
274693f3
KY
19520}
19521
d1eb57f4
KY
19522/*
19523 * ALC680 support
19524 */
c69aefab 19525#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19526#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19527#define alc680_modes alc260_modes
19528
19529static hda_nid_t alc680_dac_nids[3] = {
19530 /* Lout1, Lout2, hp */
19531 0x02, 0x03, 0x04
19532};
19533
19534static hda_nid_t alc680_adc_nids[3] = {
19535 /* ADC0-2 */
19536 /* DMIC, MIC, Line-in*/
19537 0x07, 0x08, 0x09
19538};
19539
c69aefab
KY
19540/*
19541 * Analog capture ADC cgange
19542 */
66ceeb6b
TI
19543static void alc680_rec_autoswitch(struct hda_codec *codec)
19544{
19545 struct alc_spec *spec = codec->spec;
19546 struct auto_pin_cfg *cfg = &spec->autocfg;
19547 int pin_found = 0;
19548 int type_found = AUTO_PIN_LAST;
19549 hda_nid_t nid;
19550 int i;
19551
19552 for (i = 0; i < cfg->num_inputs; i++) {
19553 nid = cfg->inputs[i].pin;
19554 if (!(snd_hda_query_pin_caps(codec, nid) &
19555 AC_PINCAP_PRES_DETECT))
19556 continue;
19557 if (snd_hda_jack_detect(codec, nid)) {
19558 if (cfg->inputs[i].type < type_found) {
19559 type_found = cfg->inputs[i].type;
19560 pin_found = nid;
19561 }
19562 }
19563 }
19564
19565 nid = 0x07;
19566 if (pin_found)
19567 snd_hda_get_connections(codec, pin_found, &nid, 1);
19568
19569 if (nid != spec->cur_adc)
19570 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19571 spec->cur_adc = nid;
19572 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19573 spec->cur_adc_format);
19574}
19575
c69aefab
KY
19576static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19577 struct hda_codec *codec,
19578 unsigned int stream_tag,
19579 unsigned int format,
19580 struct snd_pcm_substream *substream)
19581{
19582 struct alc_spec *spec = codec->spec;
c69aefab 19583
66ceeb6b 19584 spec->cur_adc = 0x07;
c69aefab
KY
19585 spec->cur_adc_stream_tag = stream_tag;
19586 spec->cur_adc_format = format;
19587
66ceeb6b 19588 alc680_rec_autoswitch(codec);
c69aefab
KY
19589 return 0;
19590}
19591
19592static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19593 struct hda_codec *codec,
19594 struct snd_pcm_substream *substream)
19595{
19596 snd_hda_codec_cleanup_stream(codec, 0x07);
19597 snd_hda_codec_cleanup_stream(codec, 0x08);
19598 snd_hda_codec_cleanup_stream(codec, 0x09);
19599 return 0;
19600}
19601
19602static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19603 .substreams = 1, /* can be overridden */
19604 .channels_min = 2,
19605 .channels_max = 2,
19606 /* NID is set in alc_build_pcms */
19607 .ops = {
19608 .prepare = alc680_capture_pcm_prepare,
19609 .cleanup = alc680_capture_pcm_cleanup
19610 },
19611};
19612
d1eb57f4
KY
19613static struct snd_kcontrol_new alc680_base_mixer[] = {
19614 /* output mixer control */
19615 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19616 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19617 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19618 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5f99f86a
DH
19619 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19620 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19621 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19622 { }
19623};
19624
c69aefab
KY
19625static struct hda_bind_ctls alc680_bind_cap_vol = {
19626 .ops = &snd_hda_bind_vol,
19627 .values = {
19628 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19629 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19630 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19631 0
19632 },
19633};
19634
19635static struct hda_bind_ctls alc680_bind_cap_switch = {
19636 .ops = &snd_hda_bind_sw,
19637 .values = {
19638 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19639 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19640 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19641 0
19642 },
19643};
19644
19645static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19646 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19647 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19648 { } /* end */
19649};
19650
19651/*
19652 * generic initialization of ADC, input mixers and output mixers
19653 */
19654static struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19655 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19656 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19657 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19658
c69aefab
KY
19659 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19660 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19661 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19662 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19663 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19664 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19665
19666 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19667 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19668 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19669 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19670 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19671
19672 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19673 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19674 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19675
d1eb57f4
KY
19676 { }
19677};
19678
c69aefab
KY
19679/* toggle speaker-output according to the hp-jack state */
19680static void alc680_base_setup(struct hda_codec *codec)
19681{
19682 struct alc_spec *spec = codec->spec;
19683
19684 spec->autocfg.hp_pins[0] = 0x16;
19685 spec->autocfg.speaker_pins[0] = 0x14;
19686 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19687 spec->autocfg.num_inputs = 2;
19688 spec->autocfg.inputs[0].pin = 0x18;
19689 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19690 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19691 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
c69aefab
KY
19692}
19693
19694static void alc680_unsol_event(struct hda_codec *codec,
19695 unsigned int res)
19696{
19697 if ((res >> 26) == ALC880_HP_EVENT)
19698 alc_automute_amp(codec);
19699 if ((res >> 26) == ALC880_MIC_EVENT)
19700 alc680_rec_autoswitch(codec);
19701}
19702
19703static void alc680_inithook(struct hda_codec *codec)
19704{
19705 alc_automute_amp(codec);
19706 alc680_rec_autoswitch(codec);
19707}
19708
d1eb57f4
KY
19709/* create input playback/capture controls for the given pin */
19710static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19711 const char *ctlname, int idx)
19712{
19713 hda_nid_t dac;
19714 int err;
19715
19716 switch (nid) {
19717 case 0x14:
19718 dac = 0x02;
19719 break;
19720 case 0x15:
19721 dac = 0x03;
19722 break;
19723 case 0x16:
19724 dac = 0x04;
19725 break;
19726 default:
19727 return 0;
19728 }
19729 if (spec->multiout.dac_nids[0] != dac &&
19730 spec->multiout.dac_nids[1] != dac) {
19731 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19732 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19733 HDA_OUTPUT));
19734 if (err < 0)
19735 return err;
19736
19737 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19738 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19739
19740 if (err < 0)
19741 return err;
19742 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19743 }
19744
19745 return 0;
19746}
19747
19748/* add playback controls from the parsed DAC table */
19749static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19750 const struct auto_pin_cfg *cfg)
19751{
19752 hda_nid_t nid;
19753 int err;
19754
19755 spec->multiout.dac_nids = spec->private_dac_nids;
19756
19757 nid = cfg->line_out_pins[0];
19758 if (nid) {
19759 const char *name;
19760 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19761 name = "Speaker";
19762 else
19763 name = "Front";
19764 err = alc680_new_analog_output(spec, nid, name, 0);
19765 if (err < 0)
19766 return err;
19767 }
19768
19769 nid = cfg->speaker_pins[0];
19770 if (nid) {
19771 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19772 if (err < 0)
19773 return err;
19774 }
19775 nid = cfg->hp_pins[0];
19776 if (nid) {
19777 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19778 if (err < 0)
19779 return err;
19780 }
19781
19782 return 0;
19783}
19784
19785static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19786 hda_nid_t nid, int pin_type)
19787{
19788 alc_set_pin_output(codec, nid, pin_type);
19789}
19790
19791static void alc680_auto_init_multi_out(struct hda_codec *codec)
19792{
19793 struct alc_spec *spec = codec->spec;
19794 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19795 if (nid) {
19796 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19797 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19798 }
19799}
19800
19801static void alc680_auto_init_hp_out(struct hda_codec *codec)
19802{
19803 struct alc_spec *spec = codec->spec;
19804 hda_nid_t pin;
19805
19806 pin = spec->autocfg.hp_pins[0];
19807 if (pin)
19808 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19809 pin = spec->autocfg.speaker_pins[0];
19810 if (pin)
19811 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19812}
19813
19814/* pcm configuration: identical with ALC880 */
19815#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19816#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19817#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19818#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19819#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19820
19821/*
19822 * BIOS auto configuration
19823 */
19824static int alc680_parse_auto_config(struct hda_codec *codec)
19825{
19826 struct alc_spec *spec = codec->spec;
19827 int err;
19828 static hda_nid_t alc680_ignore[] = { 0 };
19829
19830 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19831 alc680_ignore);
19832 if (err < 0)
19833 return err;
c69aefab 19834
d1eb57f4
KY
19835 if (!spec->autocfg.line_outs) {
19836 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19837 spec->multiout.max_channels = 2;
19838 spec->no_analog = 1;
19839 goto dig_only;
19840 }
19841 return 0; /* can't find valid BIOS pin config */
19842 }
19843 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19844 if (err < 0)
19845 return err;
19846
19847 spec->multiout.max_channels = 2;
19848
19849 dig_only:
19850 /* digital only support output */
757899ac 19851 alc_auto_parse_digital(codec);
d1eb57f4
KY
19852 if (spec->kctls.list)
19853 add_mixer(spec, spec->kctls.list);
19854
19855 add_verb(spec, alc680_init_verbs);
d1eb57f4
KY
19856
19857 err = alc_auto_add_mic_boost(codec);
19858 if (err < 0)
19859 return err;
19860
19861 return 1;
19862}
19863
19864#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19865
19866/* init callback for auto-configuration model -- overriding the default init */
19867static void alc680_auto_init(struct hda_codec *codec)
19868{
19869 struct alc_spec *spec = codec->spec;
19870 alc680_auto_init_multi_out(codec);
19871 alc680_auto_init_hp_out(codec);
19872 alc680_auto_init_analog_input(codec);
757899ac 19873 alc_auto_init_digital(codec);
d1eb57f4
KY
19874 if (spec->unsol_event)
19875 alc_inithook(codec);
19876}
19877
19878/*
19879 * configuration and preset
19880 */
19881static const char *alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19882 [ALC680_BASE] = "base",
19883 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19884};
19885
19886static struct snd_pci_quirk alc680_cfg_tbl[] = {
19887 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19888 {}
19889};
19890
19891static struct alc_config_preset alc680_presets[] = {
19892 [ALC680_BASE] = {
19893 .mixers = { alc680_base_mixer },
c69aefab 19894 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
19895 .init_verbs = { alc680_init_verbs },
19896 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19897 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
19898 .dig_out_nid = ALC680_DIGOUT_NID,
19899 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19900 .channel_mode = alc680_modes,
c69aefab
KY
19901 .unsol_event = alc680_unsol_event,
19902 .setup = alc680_base_setup,
19903 .init_hook = alc680_inithook,
19904
d1eb57f4
KY
19905 },
19906};
19907
19908static int patch_alc680(struct hda_codec *codec)
19909{
19910 struct alc_spec *spec;
19911 int board_config;
19912 int err;
19913
19914 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19915 if (spec == NULL)
19916 return -ENOMEM;
19917
19918 codec->spec = spec;
19919
19920 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19921 alc680_models,
19922 alc680_cfg_tbl);
19923
19924 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19925 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19926 codec->chip_name);
19927 board_config = ALC680_AUTO;
19928 }
19929
19930 if (board_config == ALC680_AUTO) {
19931 /* automatic parse from the BIOS config */
19932 err = alc680_parse_auto_config(codec);
19933 if (err < 0) {
19934 alc_free(codec);
19935 return err;
19936 } else if (!err) {
19937 printk(KERN_INFO
19938 "hda_codec: Cannot set up configuration "
19939 "from BIOS. Using base mode...\n");
19940 board_config = ALC680_BASE;
19941 }
19942 }
19943
19944 if (board_config != ALC680_AUTO)
19945 setup_preset(codec, &alc680_presets[board_config]);
19946
19947 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 19948 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 19949 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 19950 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
19951
19952 if (!spec->adc_nids) {
19953 spec->adc_nids = alc680_adc_nids;
19954 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19955 }
19956
19957 if (!spec->cap_mixer)
19958 set_capture_mixer(codec);
19959
19960 spec->vmaster_nid = 0x02;
19961
19962 codec->patch_ops = alc_patch_ops;
19963 if (board_config == ALC680_AUTO)
19964 spec->init_hook = alc680_auto_init;
19965
19966 return 0;
19967}
19968
1da177e4
LT
19969/*
19970 * patch entries
19971 */
1289e9e8 19972static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 19973 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 19974 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 19975 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 19976 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 19977 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 19978 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 19979 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 19980 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 19981 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 19982 .patch = patch_alc861 },
f32610ed
JS
19983 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19984 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19985 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 19986 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 19987 .patch = patch_alc882 },
bc9f98a9
KY
19988 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19989 .patch = patch_alc662 },
6dda9f4a 19990 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 19991 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 19992 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 19993 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 19994 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 19995 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 19996 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 19997 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 19998 .patch = patch_alc882 },
cb308f97 19999 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 20000 .patch = patch_alc882 },
df694daa 20001 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
01e0f137 20002 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
4442608d 20003 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 20004 .patch = patch_alc882 },
274693f3 20005 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 20006 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 20007 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
20008 {} /* terminator */
20009};
1289e9e8
TI
20010
20011MODULE_ALIAS("snd-hda-codec-id:10ec*");
20012
20013MODULE_LICENSE("GPL");
20014MODULE_DESCRIPTION("Realtek HD-audio codec");
20015
20016static struct hda_codec_preset_list realtek_list = {
20017 .preset = snd_hda_preset_realtek,
20018 .owner = THIS_MODULE,
20019};
20020
20021static int __init patch_realtek_init(void)
20022{
20023 return snd_hda_add_codec_preset(&realtek_list);
20024}
20025
20026static void __exit patch_realtek_exit(void)
20027{
20028 snd_hda_delete_codec_preset(&realtek_list);
20029}
20030
20031module_init(patch_realtek_init)
20032module_exit(patch_realtek_exit)