ALSA: HDA: Fixup unnecessary volume control index on Realtek ALC88x
[deliverable/linux.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
9ad0e496 31#include <sound/jack.h>
1da177e4
LT
32#include "hda_codec.h"
33#include "hda_local.h"
680cd536 34#include "hda_beep.h"
1da177e4 35
ccc656ce
KY
36#define ALC880_FRONT_EVENT 0x01
37#define ALC880_DCVOL_EVENT 0x02
38#define ALC880_HP_EVENT 0x04
39#define ALC880_MIC_EVENT 0x08
1da177e4
LT
40
41/* ALC880 board config type */
42enum {
1da177e4
LT
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
dfc0ff62 48 ALC880_Z71V,
b6482d48 49 ALC880_6ST,
16ded525
TI
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
df694daa 55 ALC880_ASUS_DIG2,
2cf9f0fc 56 ALC880_FUJITSU,
16ded525 57 ALC880_UNIWILL_DIG,
ccc656ce
KY
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
df694daa
KY
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
ae6b813a 62 ALC880_LG,
d681518a 63 ALC880_LG_LW,
df99cd33 64 ALC880_MEDION_RIM,
e9edcee0
TI
65#ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67#endif
df694daa 68 ALC880_AUTO,
16ded525
TI
69 ALC880_MODEL_LAST /* last tag */
70};
71
72/* ALC260 models */
73enum {
74 ALC260_BASIC,
75 ALC260_HP,
3f878308 76 ALC260_HP_DC7600,
df694daa
KY
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
0bfc90e9 79 ALC260_ACER,
bc9f98a9
KY
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
cc959489 82 ALC260_FAVORIT100,
7cf51e48
JW
83#ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85#endif
df694daa 86 ALC260_AUTO,
16ded525 87 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
88};
89
df694daa
KY
90/* ALC262 models */
91enum {
92 ALC262_BASIC,
ccc656ce
KY
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
834be88d 95 ALC262_FUJITSU,
9c7f852e 96 ALC262_HP_BPC,
cd7509a4
KY
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
66d2a9d6 99 ALC262_HP_TC_T5735,
8c427226 100 ALC262_HP_RP5700,
304dcaac 101 ALC262_BENQ_ED8,
272a527c 102 ALC262_SONY_ASSAMD,
83c34218 103 ALC262_BENQ_T31,
f651b50b 104 ALC262_ULTRA,
0e31daf7 105 ALC262_LENOVO_3000,
e8f9ae2a 106 ALC262_NEC,
4e555fe5 107 ALC262_TOSHIBA_S06,
9f99a638 108 ALC262_TOSHIBA_RX1,
ba340e82 109 ALC262_TYAN,
df694daa
KY
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
112};
113
a361d84b
KY
114/* ALC268 models */
115enum {
eb5a6621 116 ALC267_QUANTA_IL1,
a361d84b 117 ALC268_3ST,
d1a991a6 118 ALC268_TOSHIBA,
d273809e 119 ALC268_ACER,
c238b4f4 120 ALC268_ACER_DMIC,
8ef355da 121 ALC268_ACER_ASPIRE_ONE,
3866f0b0 122 ALC268_DELL,
f12462c5 123 ALC268_ZEPTO,
86c53bd2
JW
124#ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126#endif
a361d84b
KY
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
129};
130
f6a92248
KY
131/* ALC269 models */
132enum {
133 ALC269_BASIC,
60db6b53 134 ALC269_QUANTA_FL1,
84898e87
KY
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
26f5df26 139 ALC269_FUJITSU,
64154835 140 ALC269_LIFEBOOK,
fe3eb0a7 141 ALC271_ACER,
f6a92248
KY
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
144};
145
df694daa
KY
146/* ALC861 models */
147enum {
148 ALC861_3ST,
9c7f852e 149 ALC660_3ST,
df694daa
KY
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
22309c3e 152 ALC861_UNIWILL_M31,
a53d1aec 153 ALC861_TOSHIBA,
7cdbff94 154 ALC861_ASUS,
56bb0cab 155 ALC861_ASUS_LAPTOP,
df694daa
KY
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
158};
159
f32610ed
JS
160/* ALC861-VD models */
161enum {
162 ALC660VD_3ST,
6963f84c 163 ALC660VD_3ST_DIG,
13c94744 164 ALC660VD_ASUS_V1S,
f32610ed
JS
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
bdd148a3 168 ALC861VD_LENOVO,
272a527c 169 ALC861VD_DALLAS,
d1a991a6 170 ALC861VD_HP,
f32610ed
JS
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
173};
174
bc9f98a9
KY
175/* ALC662 models */
176enum {
177 ALC662_3ST_2ch_DIG,
178 ALC662_3ST_6ch_DIG,
179 ALC662_3ST_6ch,
180 ALC662_5ST_DIG,
181 ALC662_LENOVO_101E,
291702f0 182 ALC662_ASUS_EEEPC_P701,
8c427226 183 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
f1d4e28b
KY
188 ALC662_ECS,
189 ALC663_ASUS_MODE1,
190 ALC662_ASUS_MODE2,
191 ALC663_ASUS_MODE3,
192 ALC663_ASUS_MODE4,
193 ALC663_ASUS_MODE5,
194 ALC663_ASUS_MODE6,
ebb83eeb
KY
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
622e84cd
KY
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
9541ba1d 199 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
202};
203
df694daa
KY
204/* ALC882 models */
205enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
4b146cb0 208 ALC882_ARIMA,
bdd148a3 209 ALC882_W2JC,
272a527c
KY
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
914759b7 212 ALC882_ASUS_A7M,
9102cd1c 213 ALC885_MACPRO,
76e6f5a9 214 ALC885_MBA21,
87350ad0 215 ALC885_MBP3,
41d5545d 216 ALC885_MB5,
e458b1fa 217 ALC885_MACMINI3,
c54728d8 218 ALC885_IMAC24,
4b7e1803 219 ALC885_IMAC91,
9c7f852e
TI
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
ccc656ce
KY
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
64a8be74 226 ALC883_TARGA_8ch_DIG,
bab282b9 227 ALC883_ACER,
2880a867 228 ALC883_ACER_ASPIRE,
5b2d1eca 229 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 230 ALC888_ACER_ASPIRE_6530G,
3b315d70 231 ALC888_ACER_ASPIRE_8930G,
fc86f954 232 ALC888_ACER_ASPIRE_7730G,
c07584c8 233 ALC883_MEDION,
7ad7b218 234 ALC883_MEDION_WIM2160,
b373bdeb 235 ALC883_LAPTOP_EAPD,
bc9f98a9 236 ALC883_LENOVO_101E_2ch,
272a527c 237 ALC883_LENOVO_NB0763,
189609ae 238 ALC888_LENOVO_MS7195_DIG,
e2757d5e 239 ALC888_LENOVO_SKY,
ea1fb29a 240 ALC883_HAIER_W66,
4723c022 241 ALC888_3ST_HP,
5795b9e6 242 ALC888_6ST_DELL,
a8848bd6 243 ALC883_MITAC,
a65cc60f 244 ALC883_CLEVO_M540R,
0c4cc443 245 ALC883_CLEVO_M720,
fb97dc67 246 ALC883_FUJITSU_PI2515,
ef8ef5fb 247 ALC888_FUJITSU_XA3530,
17bba1b7 248 ALC883_3ST_6ch_INTEL,
87a8c370
JK
249 ALC889A_INTEL,
250 ALC889_INTEL,
e2757d5e
KY
251 ALC888_ASUS_M90V,
252 ALC888_ASUS_EEE1601,
eb4c41d3 253 ALC889A_MB31,
3ab90935 254 ALC1200_ASUS_P5Q,
3e1647c5 255 ALC883_SONY_VAIO_TT,
4953550a
TI
256 ALC882_AUTO,
257 ALC882_MODEL_LAST,
9c7f852e
TI
258};
259
d4a86d81
TI
260/* ALC680 models */
261enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
265};
266
df694daa
KY
267/* for GPIO Poll */
268#define GPIO_MASK 0x03
269
4a79ba34
TI
270/* extra amp-initialization sequence types */
271enum {
272 ALC_INIT_NONE,
273 ALC_INIT_DEFAULT,
274 ALC_INIT_GPIO1,
275 ALC_INIT_GPIO2,
276 ALC_INIT_GPIO3,
277};
278
6c819492
TI
279struct alc_mic_route {
280 hda_nid_t pin;
281 unsigned char mux_idx;
282 unsigned char amix_idx;
283};
284
285#define MUX_IDX_UNDEF ((unsigned char)-1)
286
da00c244
KY
287struct alc_customize_define {
288 unsigned int sku_cfg;
289 unsigned char port_connectivity;
290 unsigned char check_sum;
291 unsigned char customization;
292 unsigned char external_amp;
293 unsigned int enable_pcbeep:1;
294 unsigned int platform_type:1;
295 unsigned int swap:1;
296 unsigned int override:1;
90622917 297 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
da00c244
KY
298};
299
b5bfbc67
TI
300struct alc_fixup;
301
1da177e4
LT
302struct alc_spec {
303 /* codec parameterization */
df694daa 304 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 305 unsigned int num_mixers;
f9e336f6 306 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 307 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 308
2d9c6482 309 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
310 * don't forget NULL
311 * termination!
e9edcee0
TI
312 */
313 unsigned int num_init_verbs;
1da177e4 314
aa563af7 315 char stream_name_analog[32]; /* analog PCM stream */
1da177e4
LT
316 struct hda_pcm_stream *stream_analog_playback;
317 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
318 struct hda_pcm_stream *stream_analog_alt_playback;
319 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 320
aa563af7 321 char stream_name_digital[32]; /* digital PCM stream */
1da177e4
LT
322 struct hda_pcm_stream *stream_digital_playback;
323 struct hda_pcm_stream *stream_digital_capture;
324
325 /* playback */
16ded525
TI
326 struct hda_multi_out multiout; /* playback set-up
327 * max_channels, dacs must be set
328 * dig_out_nid and hp_nid are optional
329 */
6330079f 330 hda_nid_t alt_dac_nid;
6a05ac4a 331 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 332 int dig_out_type;
1da177e4
LT
333
334 /* capture */
335 unsigned int num_adc_nids;
336 hda_nid_t *adc_nids;
e1406348 337 hda_nid_t *capsrc_nids;
16ded525 338 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4 339
840b64c0
TI
340 /* capture setup for dynamic dual-adc switch */
341 unsigned int cur_adc_idx;
342 hda_nid_t cur_adc;
343 unsigned int cur_adc_stream_tag;
344 unsigned int cur_adc_format;
345
1da177e4 346 /* capture source */
a1e8d2da 347 unsigned int num_mux_defs;
1da177e4
LT
348 const struct hda_input_mux *input_mux;
349 unsigned int cur_mux[3];
6c819492
TI
350 struct alc_mic_route ext_mic;
351 struct alc_mic_route int_mic;
1da177e4
LT
352
353 /* channel model */
d2a6d7dc 354 const struct hda_channel_mode *channel_mode;
1da177e4 355 int num_channel_mode;
4e195a7b 356 int need_dac_fix;
3b315d70
HM
357 int const_channel_count;
358 int ext_channel_count;
1da177e4
LT
359
360 /* PCM information */
4c5186ed 361 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 362
e9edcee0
TI
363 /* dynamic controls, init_verbs and input_mux */
364 struct auto_pin_cfg autocfg;
da00c244 365 struct alc_customize_define cdefine;
603c4019 366 struct snd_array kctls;
61b9b9b1 367 struct hda_input_mux private_imux[3];
41923e44 368 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
369 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
370 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 371
ae6b813a
TI
372 /* hooks */
373 void (*init_hook)(struct hda_codec *codec);
374 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 375#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 376 void (*power_hook)(struct hda_codec *codec);
f5de24b0 377#endif
ae6b813a 378
834be88d
TI
379 /* for pin sensing */
380 unsigned int sense_updated: 1;
381 unsigned int jack_present: 1;
bec15c3a 382 unsigned int master_sw: 1;
6c819492 383 unsigned int auto_mic:1;
cb53c626 384
e64f14f4
TI
385 /* other flags */
386 unsigned int no_analog :1; /* digital I/O only */
840b64c0 387 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
4a79ba34 388 int init_amp;
d433a678 389 int codec_variant; /* flag for other variants */
e64f14f4 390
2134ea4f
TI
391 /* for virtual master */
392 hda_nid_t vmaster_nid;
cb53c626
TI
393#ifdef CONFIG_SND_HDA_POWER_SAVE
394 struct hda_loopback_check loopback;
395#endif
2c3bf9ab
TI
396
397 /* for PLL fix */
398 hda_nid_t pll_nid;
399 unsigned int pll_coef_idx, pll_coef_bit;
b5bfbc67
TI
400
401 /* fix-up list */
402 int fixup_id;
403 const struct alc_fixup *fixup_list;
404 const char *fixup_name;
df694daa
KY
405};
406
407/*
408 * configuration template - to be copied to the spec instance
409 */
410struct alc_config_preset {
9c7f852e
TI
411 struct snd_kcontrol_new *mixers[5]; /* should be identical size
412 * with spec
413 */
f9e336f6 414 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
415 const struct hda_verb *init_verbs[5];
416 unsigned int num_dacs;
417 hda_nid_t *dac_nids;
418 hda_nid_t dig_out_nid; /* optional */
419 hda_nid_t hp_nid; /* optional */
b25c9da1 420 hda_nid_t *slave_dig_outs;
df694daa
KY
421 unsigned int num_adc_nids;
422 hda_nid_t *adc_nids;
e1406348 423 hda_nid_t *capsrc_nids;
df694daa
KY
424 hda_nid_t dig_in_nid;
425 unsigned int num_channel_mode;
426 const struct hda_channel_mode *channel_mode;
4e195a7b 427 int need_dac_fix;
3b315d70 428 int const_channel_count;
a1e8d2da 429 unsigned int num_mux_defs;
df694daa 430 const struct hda_input_mux *input_mux;
ae6b813a 431 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 432 void (*setup)(struct hda_codec *);
ae6b813a 433 void (*init_hook)(struct hda_codec *);
cb53c626
TI
434#ifdef CONFIG_SND_HDA_POWER_SAVE
435 struct hda_amp_list *loopbacks;
c97259df 436 void (*power_hook)(struct hda_codec *codec);
cb53c626 437#endif
1da177e4
LT
438};
439
1da177e4
LT
440
441/*
442 * input MUX handling
443 */
9c7f852e
TI
444static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
445 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
446{
447 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
448 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
449 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
450 if (mux_idx >= spec->num_mux_defs)
451 mux_idx = 0;
5311114d
TI
452 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
453 mux_idx = 0;
a1e8d2da 454 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
455}
456
9c7f852e
TI
457static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
458 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
459{
460 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
461 struct alc_spec *spec = codec->spec;
462 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
463
464 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
465 return 0;
466}
467
9c7f852e
TI
468static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
469 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
470{
471 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
472 struct alc_spec *spec = codec->spec;
cd896c33 473 const struct hda_input_mux *imux;
1da177e4 474 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 475 unsigned int mux_idx;
e1406348
TI
476 hda_nid_t nid = spec->capsrc_nids ?
477 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 478 unsigned int type;
1da177e4 479
cd896c33
TI
480 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
481 imux = &spec->input_mux[mux_idx];
5311114d
TI
482 if (!imux->num_items && mux_idx > 0)
483 imux = &spec->input_mux[0];
cd896c33 484
a22d543a 485 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 486 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
487 /* Matrix-mixer style (e.g. ALC882) */
488 unsigned int *cur_val = &spec->cur_mux[adc_idx];
489 unsigned int i, idx;
490
491 idx = ucontrol->value.enumerated.item[0];
492 if (idx >= imux->num_items)
493 idx = imux->num_items - 1;
494 if (*cur_val == idx)
495 return 0;
496 for (i = 0; i < imux->num_items; i++) {
497 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
498 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
499 imux->items[i].index,
500 HDA_AMP_MUTE, v);
501 }
502 *cur_val = idx;
503 return 1;
504 } else {
505 /* MUX style (e.g. ALC880) */
cd896c33 506 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
507 &spec->cur_mux[adc_idx]);
508 }
509}
e9edcee0 510
1da177e4
LT
511/*
512 * channel mode setting
513 */
9c7f852e
TI
514static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
515 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
516{
517 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
518 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
519 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
520 spec->num_channel_mode);
1da177e4
LT
521}
522
9c7f852e
TI
523static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
524 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
525{
526 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
527 struct alc_spec *spec = codec->spec;
d2a6d7dc 528 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 529 spec->num_channel_mode,
3b315d70 530 spec->ext_channel_count);
1da177e4
LT
531}
532
9c7f852e
TI
533static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
534 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
535{
536 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
537 struct alc_spec *spec = codec->spec;
4e195a7b
TI
538 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
539 spec->num_channel_mode,
3b315d70
HM
540 &spec->ext_channel_count);
541 if (err >= 0 && !spec->const_channel_count) {
542 spec->multiout.max_channels = spec->ext_channel_count;
543 if (spec->need_dac_fix)
544 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
545 }
4e195a7b 546 return err;
1da177e4
LT
547}
548
a9430dd8 549/*
4c5186ed 550 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 551 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
552 * being part of a format specifier. Maximum allowed length of a value is
553 * 63 characters plus NULL terminator.
7cf51e48
JW
554 *
555 * Note: some retasking pin complexes seem to ignore requests for input
556 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
557 * are requested. Therefore order this list so that this behaviour will not
558 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
559 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
560 * March 2006.
4c5186ed
JW
561 */
562static char *alc_pin_mode_names[] = {
7cf51e48
JW
563 "Mic 50pc bias", "Mic 80pc bias",
564 "Line in", "Line out", "Headphone out",
4c5186ed
JW
565};
566static unsigned char alc_pin_mode_values[] = {
7cf51e48 567 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
568};
569/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
570 * in the pin being assumed to be exclusively an input or an output pin. In
571 * addition, "input" pins may or may not process the mic bias option
572 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
573 * accept requests for bias as of chip versions up to March 2006) and/or
574 * wiring in the computer.
a9430dd8 575 */
a1e8d2da
JW
576#define ALC_PIN_DIR_IN 0x00
577#define ALC_PIN_DIR_OUT 0x01
578#define ALC_PIN_DIR_INOUT 0x02
579#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
580#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 581
ea1fb29a 582/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
583 * For each direction the minimum and maximum values are given.
584 */
a1e8d2da 585static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
586 { 0, 2 }, /* ALC_PIN_DIR_IN */
587 { 3, 4 }, /* ALC_PIN_DIR_OUT */
588 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
589 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
590 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
591};
592#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
593#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
594#define alc_pin_mode_n_items(_dir) \
595 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
596
9c7f852e
TI
597static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
598 struct snd_ctl_elem_info *uinfo)
a9430dd8 599{
4c5186ed
JW
600 unsigned int item_num = uinfo->value.enumerated.item;
601 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
602
603 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 604 uinfo->count = 1;
4c5186ed
JW
605 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
606
607 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
608 item_num = alc_pin_mode_min(dir);
609 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
610 return 0;
611}
612
9c7f852e
TI
613static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
614 struct snd_ctl_elem_value *ucontrol)
a9430dd8 615{
4c5186ed 616 unsigned int i;
a9430dd8
JW
617 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
618 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 619 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 620 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
621 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
622 AC_VERB_GET_PIN_WIDGET_CONTROL,
623 0x00);
a9430dd8 624
4c5186ed
JW
625 /* Find enumerated value for current pinctl setting */
626 i = alc_pin_mode_min(dir);
4b35d2ca 627 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 628 i++;
9c7f852e 629 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
630 return 0;
631}
632
9c7f852e
TI
633static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
634 struct snd_ctl_elem_value *ucontrol)
a9430dd8 635{
4c5186ed 636 signed int change;
a9430dd8
JW
637 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
638 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
639 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
640 long val = *ucontrol->value.integer.value;
9c7f852e
TI
641 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
642 AC_VERB_GET_PIN_WIDGET_CONTROL,
643 0x00);
a9430dd8 644
f12ab1e0 645 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
646 val = alc_pin_mode_min(dir);
647
648 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
649 if (change) {
650 /* Set pin mode to that requested */
82beb8fd
TI
651 snd_hda_codec_write_cache(codec, nid, 0,
652 AC_VERB_SET_PIN_WIDGET_CONTROL,
653 alc_pin_mode_values[val]);
cdcd9268 654
ea1fb29a 655 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
656 * for the requested pin mode. Enum values of 2 or less are
657 * input modes.
658 *
659 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
660 * reduces noise slightly (particularly on input) so we'll
661 * do it. However, having both input and output buffers
662 * enabled simultaneously doesn't seem to be problematic if
663 * this turns out to be necessary in the future.
cdcd9268
JW
664 */
665 if (val <= 2) {
47fd830a
TI
666 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
667 HDA_AMP_MUTE, HDA_AMP_MUTE);
668 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
669 HDA_AMP_MUTE, 0);
cdcd9268 670 } else {
47fd830a
TI
671 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
672 HDA_AMP_MUTE, HDA_AMP_MUTE);
673 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
674 HDA_AMP_MUTE, 0);
cdcd9268
JW
675 }
676 }
a9430dd8
JW
677 return change;
678}
679
4c5186ed 680#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 681 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 682 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
683 .info = alc_pin_mode_info, \
684 .get = alc_pin_mode_get, \
685 .put = alc_pin_mode_put, \
686 .private_value = nid | (dir<<16) }
df694daa 687
5c8f858d
JW
688/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
689 * together using a mask with more than one bit set. This control is
690 * currently used only by the ALC260 test model. At this stage they are not
691 * needed for any "production" models.
692 */
693#ifdef CONFIG_SND_DEBUG
a5ce8890 694#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 695
9c7f852e
TI
696static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
697 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
698{
699 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
700 hda_nid_t nid = kcontrol->private_value & 0xffff;
701 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
702 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
703 unsigned int val = snd_hda_codec_read(codec, nid, 0,
704 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
705
706 *valp = (val & mask) != 0;
707 return 0;
708}
9c7f852e
TI
709static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
710 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
711{
712 signed int change;
713 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
714 hda_nid_t nid = kcontrol->private_value & 0xffff;
715 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
716 long val = *ucontrol->value.integer.value;
9c7f852e
TI
717 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
718 AC_VERB_GET_GPIO_DATA,
719 0x00);
5c8f858d
JW
720
721 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
722 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
723 if (val == 0)
5c8f858d
JW
724 gpio_data &= ~mask;
725 else
726 gpio_data |= mask;
82beb8fd
TI
727 snd_hda_codec_write_cache(codec, nid, 0,
728 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
729
730 return change;
731}
732#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
733 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 734 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
735 .info = alc_gpio_data_info, \
736 .get = alc_gpio_data_get, \
737 .put = alc_gpio_data_put, \
738 .private_value = nid | (mask<<16) }
739#endif /* CONFIG_SND_DEBUG */
740
92621f13
JW
741/* A switch control to allow the enabling of the digital IO pins on the
742 * ALC260. This is incredibly simplistic; the intention of this control is
743 * to provide something in the test model allowing digital outputs to be
744 * identified if present. If models are found which can utilise these
745 * outputs a more complete mixer control can be devised for those models if
746 * necessary.
747 */
748#ifdef CONFIG_SND_DEBUG
a5ce8890 749#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 750
9c7f852e
TI
751static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
752 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
753{
754 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
755 hda_nid_t nid = kcontrol->private_value & 0xffff;
756 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
757 long *valp = ucontrol->value.integer.value;
9c7f852e 758 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 759 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
760
761 *valp = (val & mask) != 0;
762 return 0;
763}
9c7f852e
TI
764static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
765 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
766{
767 signed int change;
768 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
769 hda_nid_t nid = kcontrol->private_value & 0xffff;
770 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
771 long val = *ucontrol->value.integer.value;
9c7f852e 772 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 773 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 774 0x00);
92621f13
JW
775
776 /* Set/unset the masked control bit(s) as needed */
9c7f852e 777 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
778 if (val==0)
779 ctrl_data &= ~mask;
780 else
781 ctrl_data |= mask;
82beb8fd
TI
782 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
783 ctrl_data);
92621f13
JW
784
785 return change;
786}
787#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
788 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 789 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
790 .info = alc_spdif_ctrl_info, \
791 .get = alc_spdif_ctrl_get, \
792 .put = alc_spdif_ctrl_put, \
793 .private_value = nid | (mask<<16) }
794#endif /* CONFIG_SND_DEBUG */
795
f8225f6d
JW
796/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
797 * Again, this is only used in the ALC26x test models to help identify when
798 * the EAPD line must be asserted for features to work.
799 */
800#ifdef CONFIG_SND_DEBUG
801#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
802
803static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
804 struct snd_ctl_elem_value *ucontrol)
805{
806 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
807 hda_nid_t nid = kcontrol->private_value & 0xffff;
808 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
809 long *valp = ucontrol->value.integer.value;
810 unsigned int val = snd_hda_codec_read(codec, nid, 0,
811 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
812
813 *valp = (val & mask) != 0;
814 return 0;
815}
816
817static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
818 struct snd_ctl_elem_value *ucontrol)
819{
820 int change;
821 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
822 hda_nid_t nid = kcontrol->private_value & 0xffff;
823 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
824 long val = *ucontrol->value.integer.value;
825 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
826 AC_VERB_GET_EAPD_BTLENABLE,
827 0x00);
828
829 /* Set/unset the masked control bit(s) as needed */
830 change = (!val ? 0 : mask) != (ctrl_data & mask);
831 if (!val)
832 ctrl_data &= ~mask;
833 else
834 ctrl_data |= mask;
835 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
836 ctrl_data);
837
838 return change;
839}
840
841#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
842 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 843 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
844 .info = alc_eapd_ctrl_info, \
845 .get = alc_eapd_ctrl_get, \
846 .put = alc_eapd_ctrl_put, \
847 .private_value = nid | (mask<<16) }
848#endif /* CONFIG_SND_DEBUG */
849
23f0c048
TI
850/*
851 * set up the input pin config (depending on the given auto-pin type)
852 */
853static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
854 int auto_pin_type)
855{
856 unsigned int val = PIN_IN;
857
86e2959a 858 if (auto_pin_type == AUTO_PIN_MIC) {
23f0c048 859 unsigned int pincap;
954a29c8
TI
860 unsigned int oldval;
861 oldval = snd_hda_codec_read(codec, nid, 0,
862 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1327a32b 863 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048 864 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
954a29c8
TI
865 /* if the default pin setup is vref50, we give it priority */
866 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
23f0c048 867 val = PIN_VREF80;
461c6c3a
TI
868 else if (pincap & AC_PINCAP_VREF_50)
869 val = PIN_VREF50;
870 else if (pincap & AC_PINCAP_VREF_100)
871 val = PIN_VREF100;
872 else if (pincap & AC_PINCAP_VREF_GRD)
873 val = PIN_VREFGRD;
23f0c048
TI
874 }
875 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
876}
877
f6837bbd
TI
878static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
879{
880 struct alc_spec *spec = codec->spec;
881 struct auto_pin_cfg *cfg = &spec->autocfg;
882
883 if (!cfg->line_outs) {
884 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
885 cfg->line_out_pins[cfg->line_outs])
886 cfg->line_outs++;
887 }
888 if (!cfg->speaker_outs) {
889 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
890 cfg->speaker_pins[cfg->speaker_outs])
891 cfg->speaker_outs++;
892 }
893 if (!cfg->hp_outs) {
894 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
895 cfg->hp_pins[cfg->hp_outs])
896 cfg->hp_outs++;
897 }
898}
899
d88897ea
TI
900/*
901 */
902static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
903{
904 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
905 return;
906 spec->mixers[spec->num_mixers++] = mix;
907}
908
909static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
910{
911 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
912 return;
913 spec->init_verbs[spec->num_init_verbs++] = verb;
914}
915
df694daa
KY
916/*
917 * set up from the preset table
918 */
e9c364c0 919static void setup_preset(struct hda_codec *codec,
9c7f852e 920 const struct alc_config_preset *preset)
df694daa 921{
e9c364c0 922 struct alc_spec *spec = codec->spec;
df694daa
KY
923 int i;
924
925 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 926 add_mixer(spec, preset->mixers[i]);
f9e336f6 927 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
928 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
929 i++)
d88897ea 930 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 931
df694daa
KY
932 spec->channel_mode = preset->channel_mode;
933 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 934 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 935 spec->const_channel_count = preset->const_channel_count;
df694daa 936
3b315d70
HM
937 if (preset->const_channel_count)
938 spec->multiout.max_channels = preset->const_channel_count;
939 else
940 spec->multiout.max_channels = spec->channel_mode[0].channels;
941 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
942
943 spec->multiout.num_dacs = preset->num_dacs;
944 spec->multiout.dac_nids = preset->dac_nids;
945 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 946 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 947 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 948
a1e8d2da 949 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 950 if (!spec->num_mux_defs)
a1e8d2da 951 spec->num_mux_defs = 1;
df694daa
KY
952 spec->input_mux = preset->input_mux;
953
954 spec->num_adc_nids = preset->num_adc_nids;
955 spec->adc_nids = preset->adc_nids;
e1406348 956 spec->capsrc_nids = preset->capsrc_nids;
df694daa 957 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
958
959 spec->unsol_event = preset->unsol_event;
960 spec->init_hook = preset->init_hook;
cb53c626 961#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 962 spec->power_hook = preset->power_hook;
cb53c626
TI
963 spec->loopback.amplist = preset->loopbacks;
964#endif
e9c364c0
TI
965
966 if (preset->setup)
967 preset->setup(codec);
f6837bbd
TI
968
969 alc_fixup_autocfg_pin_nums(codec);
df694daa
KY
970}
971
bc9f98a9
KY
972/* Enable GPIO mask and set output */
973static struct hda_verb alc_gpio1_init_verbs[] = {
974 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
975 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
976 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
977 { }
978};
979
980static struct hda_verb alc_gpio2_init_verbs[] = {
981 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
982 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
983 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
984 { }
985};
986
bdd148a3
KY
987static struct hda_verb alc_gpio3_init_verbs[] = {
988 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
989 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
990 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
991 { }
992};
993
2c3bf9ab
TI
994/*
995 * Fix hardware PLL issue
996 * On some codecs, the analog PLL gating control must be off while
997 * the default value is 1.
998 */
999static void alc_fix_pll(struct hda_codec *codec)
1000{
1001 struct alc_spec *spec = codec->spec;
1002 unsigned int val;
1003
1004 if (!spec->pll_nid)
1005 return;
1006 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1007 spec->pll_coef_idx);
1008 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1009 AC_VERB_GET_PROC_COEF, 0);
1010 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1011 spec->pll_coef_idx);
1012 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1013 val & ~(1 << spec->pll_coef_bit));
1014}
1015
1016static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1017 unsigned int coef_idx, unsigned int coef_bit)
1018{
1019 struct alc_spec *spec = codec->spec;
1020 spec->pll_nid = nid;
1021 spec->pll_coef_idx = coef_idx;
1022 spec->pll_coef_bit = coef_bit;
1023 alc_fix_pll(codec);
1024}
1025
9ad0e496
KY
1026static int alc_init_jacks(struct hda_codec *codec)
1027{
cd372fb3 1028#ifdef CONFIG_SND_HDA_INPUT_JACK
9ad0e496
KY
1029 struct alc_spec *spec = codec->spec;
1030 int err;
1031 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1032 unsigned int mic_nid = spec->ext_mic.pin;
1033
265a0247 1034 if (hp_nid) {
cd372fb3
TI
1035 err = snd_hda_input_jack_add(codec, hp_nid,
1036 SND_JACK_HEADPHONE, NULL);
265a0247
TI
1037 if (err < 0)
1038 return err;
cd372fb3 1039 snd_hda_input_jack_report(codec, hp_nid);
265a0247 1040 }
9ad0e496 1041
265a0247 1042 if (mic_nid) {
cd372fb3
TI
1043 err = snd_hda_input_jack_add(codec, mic_nid,
1044 SND_JACK_MICROPHONE, NULL);
265a0247
TI
1045 if (err < 0)
1046 return err;
cd372fb3 1047 snd_hda_input_jack_report(codec, mic_nid);
265a0247 1048 }
cd372fb3 1049#endif /* CONFIG_SND_HDA_INPUT_JACK */
9ad0e496
KY
1050 return 0;
1051}
9ad0e496 1052
bb35febd 1053static void alc_automute_speaker(struct hda_codec *codec, int pinctl)
c9b58006
KY
1054{
1055 struct alc_spec *spec = codec->spec;
bb35febd
TI
1056 unsigned int mute;
1057 hda_nid_t nid;
a9fd4f3f 1058 int i;
c9b58006 1059
bb35febd
TI
1060 spec->jack_present = 0;
1061 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1062 nid = spec->autocfg.hp_pins[i];
1063 if (!nid)
1064 break;
cd372fb3 1065 snd_hda_input_jack_report(codec, nid);
f0ce2799 1066 spec->jack_present |= snd_hda_jack_detect(codec, nid);
bb35febd
TI
1067 }
1068
1069 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1070 /* Toggle internal speakers muting */
a9fd4f3f
TI
1071 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1072 nid = spec->autocfg.speaker_pins[i];
1073 if (!nid)
1074 break;
bb35febd
TI
1075 if (pinctl) {
1076 snd_hda_codec_write(codec, nid, 0,
a9fd4f3f
TI
1077 AC_VERB_SET_PIN_WIDGET_CONTROL,
1078 spec->jack_present ? 0 : PIN_OUT);
bb35febd
TI
1079 } else {
1080 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1081 HDA_AMP_MUTE, mute);
1082 }
a9fd4f3f 1083 }
c9b58006
KY
1084}
1085
bb35febd
TI
1086static void alc_automute_pin(struct hda_codec *codec)
1087{
1088 alc_automute_speaker(codec, 1);
1089}
1090
6c819492
TI
1091static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1092 hda_nid_t nid)
1093{
1094 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1095 int i, nums;
1096
1097 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1098 for (i = 0; i < nums; i++)
1099 if (conn[i] == nid)
1100 return i;
1101 return -1;
1102}
1103
840b64c0
TI
1104/* switch the current ADC according to the jack state */
1105static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1106{
1107 struct alc_spec *spec = codec->spec;
1108 unsigned int present;
1109 hda_nid_t new_adc;
1110
1111 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1112 if (present)
1113 spec->cur_adc_idx = 1;
1114 else
1115 spec->cur_adc_idx = 0;
1116 new_adc = spec->adc_nids[spec->cur_adc_idx];
1117 if (spec->cur_adc && spec->cur_adc != new_adc) {
1118 /* stream is running, let's swap the current ADC */
f0cea797 1119 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
840b64c0
TI
1120 spec->cur_adc = new_adc;
1121 snd_hda_codec_setup_stream(codec, new_adc,
1122 spec->cur_adc_stream_tag, 0,
1123 spec->cur_adc_format);
1124 }
1125}
1126
7fb0d78f
KY
1127static void alc_mic_automute(struct hda_codec *codec)
1128{
1129 struct alc_spec *spec = codec->spec;
6c819492
TI
1130 struct alc_mic_route *dead, *alive;
1131 unsigned int present, type;
1132 hda_nid_t cap_nid;
1133
b59bdf3b
TI
1134 if (!spec->auto_mic)
1135 return;
6c819492
TI
1136 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1137 return;
1138 if (snd_BUG_ON(!spec->adc_nids))
1139 return;
1140
840b64c0
TI
1141 if (spec->dual_adc_switch) {
1142 alc_dual_mic_adc_auto_switch(codec);
1143 return;
1144 }
1145
6c819492
TI
1146 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1147
864f92be 1148 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1149 if (present) {
1150 alive = &spec->ext_mic;
1151 dead = &spec->int_mic;
1152 } else {
1153 alive = &spec->int_mic;
1154 dead = &spec->ext_mic;
1155 }
1156
6c819492
TI
1157 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1158 if (type == AC_WID_AUD_MIX) {
1159 /* Matrix-mixer style (e.g. ALC882) */
1160 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1161 alive->mux_idx,
1162 HDA_AMP_MUTE, 0);
1163 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1164 dead->mux_idx,
1165 HDA_AMP_MUTE, HDA_AMP_MUTE);
1166 } else {
1167 /* MUX style (e.g. ALC880) */
1168 snd_hda_codec_write_cache(codec, cap_nid, 0,
1169 AC_VERB_SET_CONNECT_SEL,
1170 alive->mux_idx);
1171 }
cd372fb3 1172 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
6c819492
TI
1173
1174 /* FIXME: analog mixer */
7fb0d78f
KY
1175}
1176
c9b58006
KY
1177/* unsolicited event for HP jack sensing */
1178static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1179{
1180 if (codec->vendor_id == 0x10ec0880)
1181 res >>= 28;
1182 else
1183 res >>= 26;
a9fd4f3f
TI
1184 switch (res) {
1185 case ALC880_HP_EVENT:
1186 alc_automute_pin(codec);
1187 break;
1188 case ALC880_MIC_EVENT:
7fb0d78f 1189 alc_mic_automute(codec);
a9fd4f3f
TI
1190 break;
1191 }
7fb0d78f
KY
1192}
1193
1194static void alc_inithook(struct hda_codec *codec)
1195{
a9fd4f3f 1196 alc_automute_pin(codec);
7fb0d78f 1197 alc_mic_automute(codec);
c9b58006
KY
1198}
1199
f9423e7a
KY
1200/* additional initialization for ALC888 variants */
1201static void alc888_coef_init(struct hda_codec *codec)
1202{
1203 unsigned int tmp;
1204
1205 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1206 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1207 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1208 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1209 /* alc888S-VC */
1210 snd_hda_codec_read(codec, 0x20, 0,
1211 AC_VERB_SET_PROC_COEF, 0x830);
1212 else
1213 /* alc888-VB */
1214 snd_hda_codec_read(codec, 0x20, 0,
1215 AC_VERB_SET_PROC_COEF, 0x3030);
1216}
1217
87a8c370
JK
1218static void alc889_coef_init(struct hda_codec *codec)
1219{
1220 unsigned int tmp;
1221
1222 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1223 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1224 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1225 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1226}
1227
3fb4a508
TI
1228/* turn on/off EAPD control (only if available) */
1229static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1230{
1231 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1232 return;
1233 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1234 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1235 on ? 2 : 0);
1236}
1237
4a79ba34 1238static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1239{
4a79ba34 1240 unsigned int tmp;
bc9f98a9 1241
4a79ba34
TI
1242 switch (type) {
1243 case ALC_INIT_GPIO1:
bc9f98a9
KY
1244 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1245 break;
4a79ba34 1246 case ALC_INIT_GPIO2:
bc9f98a9
KY
1247 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1248 break;
4a79ba34 1249 case ALC_INIT_GPIO3:
bdd148a3
KY
1250 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1251 break;
4a79ba34 1252 case ALC_INIT_DEFAULT:
bdd148a3 1253 switch (codec->vendor_id) {
c9b58006 1254 case 0x10ec0260:
3fb4a508
TI
1255 set_eapd(codec, 0x0f, 1);
1256 set_eapd(codec, 0x10, 1);
c9b58006
KY
1257 break;
1258 case 0x10ec0262:
bdd148a3
KY
1259 case 0x10ec0267:
1260 case 0x10ec0268:
c9b58006 1261 case 0x10ec0269:
3fb4a508 1262 case 0x10ec0270:
c6e8f2da 1263 case 0x10ec0272:
f9423e7a
KY
1264 case 0x10ec0660:
1265 case 0x10ec0662:
1266 case 0x10ec0663:
c9b58006 1267 case 0x10ec0862:
20a3a05d 1268 case 0x10ec0889:
3fb4a508
TI
1269 set_eapd(codec, 0x14, 1);
1270 set_eapd(codec, 0x15, 1);
c9b58006 1271 break;
bdd148a3 1272 }
c9b58006
KY
1273 switch (codec->vendor_id) {
1274 case 0x10ec0260:
1275 snd_hda_codec_write(codec, 0x1a, 0,
1276 AC_VERB_SET_COEF_INDEX, 7);
1277 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1278 AC_VERB_GET_PROC_COEF, 0);
1279 snd_hda_codec_write(codec, 0x1a, 0,
1280 AC_VERB_SET_COEF_INDEX, 7);
1281 snd_hda_codec_write(codec, 0x1a, 0,
1282 AC_VERB_SET_PROC_COEF,
1283 tmp | 0x2010);
1284 break;
1285 case 0x10ec0262:
1286 case 0x10ec0880:
1287 case 0x10ec0882:
1288 case 0x10ec0883:
1289 case 0x10ec0885:
4a5a4c56 1290 case 0x10ec0887:
20a3a05d 1291 case 0x10ec0889:
87a8c370 1292 alc889_coef_init(codec);
c9b58006 1293 break;
f9423e7a 1294 case 0x10ec0888:
4a79ba34 1295 alc888_coef_init(codec);
f9423e7a 1296 break;
0aea778e 1297#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1298 case 0x10ec0267:
1299 case 0x10ec0268:
1300 snd_hda_codec_write(codec, 0x20, 0,
1301 AC_VERB_SET_COEF_INDEX, 7);
1302 tmp = snd_hda_codec_read(codec, 0x20, 0,
1303 AC_VERB_GET_PROC_COEF, 0);
1304 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1305 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1306 snd_hda_codec_write(codec, 0x20, 0,
1307 AC_VERB_SET_PROC_COEF,
1308 tmp | 0x3000);
1309 break;
0aea778e 1310#endif /* XXX */
bc9f98a9 1311 }
4a79ba34
TI
1312 break;
1313 }
1314}
1315
1316static void alc_init_auto_hp(struct hda_codec *codec)
1317{
1318 struct alc_spec *spec = codec->spec;
bb35febd
TI
1319 struct auto_pin_cfg *cfg = &spec->autocfg;
1320 int i;
4a79ba34 1321
bb35febd
TI
1322 if (!cfg->hp_pins[0]) {
1323 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
1324 return;
1325 }
4a79ba34 1326
bb35febd
TI
1327 if (!cfg->speaker_pins[0]) {
1328 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
4a79ba34 1329 return;
bb35febd
TI
1330 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1331 sizeof(cfg->speaker_pins));
1332 cfg->speaker_outs = cfg->line_outs;
1333 }
1334
1335 if (!cfg->hp_pins[0]) {
1336 memcpy(cfg->hp_pins, cfg->line_out_pins,
1337 sizeof(cfg->hp_pins));
1338 cfg->hp_outs = cfg->line_outs;
4a79ba34
TI
1339 }
1340
bb35febd
TI
1341 for (i = 0; i < cfg->hp_outs; i++) {
1342 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1343 cfg->hp_pins[i]);
1344 snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0,
4a79ba34
TI
1345 AC_VERB_SET_UNSOLICITED_ENABLE,
1346 AC_USRSP_EN | ALC880_HP_EVENT);
bb35febd 1347 }
4a79ba34
TI
1348 spec->unsol_event = alc_sku_unsol_event;
1349}
1350
6c819492
TI
1351static void alc_init_auto_mic(struct hda_codec *codec)
1352{
1353 struct alc_spec *spec = codec->spec;
1354 struct auto_pin_cfg *cfg = &spec->autocfg;
1355 hda_nid_t fixed, ext;
1356 int i;
1357
1358 /* there must be only two mic inputs exclusively */
66ceeb6b 1359 for (i = 0; i < cfg->num_inputs; i++)
86e2959a 1360 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN)
6c819492
TI
1361 return;
1362
1363 fixed = ext = 0;
66ceeb6b
TI
1364 for (i = 0; i < cfg->num_inputs; i++) {
1365 hda_nid_t nid = cfg->inputs[i].pin;
6c819492 1366 unsigned int defcfg;
6c819492 1367 defcfg = snd_hda_codec_get_pincfg(codec, nid);
99ae28be
TI
1368 switch (snd_hda_get_input_pin_attr(defcfg)) {
1369 case INPUT_PIN_ATTR_INT:
6c819492
TI
1370 if (fixed)
1371 return; /* already occupied */
1372 fixed = nid;
1373 break;
99ae28be
TI
1374 case INPUT_PIN_ATTR_UNUSED:
1375 return; /* invalid entry */
1376 default:
6c819492
TI
1377 if (ext)
1378 return; /* already occupied */
1379 ext = nid;
1380 break;
6c819492
TI
1381 }
1382 }
eaa9b3a7
TI
1383 if (!ext || !fixed)
1384 return;
6c819492
TI
1385 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1386 return; /* no unsol support */
1387 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1388 ext, fixed);
1389 spec->ext_mic.pin = ext;
1390 spec->int_mic.pin = fixed;
1391 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1392 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1393 spec->auto_mic = 1;
1394 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1395 AC_VERB_SET_UNSOLICITED_ENABLE,
1396 AC_USRSP_EN | ALC880_MIC_EVENT);
1397 spec->unsol_event = alc_sku_unsol_event;
1398}
1399
90622917
DH
1400/* Could be any non-zero and even value. When used as fixup, tells
1401 * the driver to ignore any present sku defines.
1402 */
1403#define ALC_FIXUP_SKU_IGNORE (2)
1404
da00c244
KY
1405static int alc_auto_parse_customize_define(struct hda_codec *codec)
1406{
1407 unsigned int ass, tmp, i;
7fb56223 1408 unsigned nid = 0;
da00c244
KY
1409 struct alc_spec *spec = codec->spec;
1410
b6cbe517
TI
1411 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1412
90622917
DH
1413 if (spec->cdefine.fixup) {
1414 ass = spec->cdefine.sku_cfg;
1415 if (ass == ALC_FIXUP_SKU_IGNORE)
1416 return -1;
1417 goto do_sku;
1418 }
1419
da00c244 1420 ass = codec->subsystem_id & 0xffff;
b6cbe517 1421 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1422 goto do_sku;
1423
1424 nid = 0x1d;
1425 if (codec->vendor_id == 0x10ec0260)
1426 nid = 0x17;
1427 ass = snd_hda_codec_get_pincfg(codec, nid);
1428
1429 if (!(ass & 1)) {
1430 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1431 codec->chip_name, ass);
1432 return -1;
1433 }
1434
1435 /* check sum */
1436 tmp = 0;
1437 for (i = 1; i < 16; i++) {
1438 if ((ass >> i) & 1)
1439 tmp++;
1440 }
1441 if (((ass >> 16) & 0xf) != tmp)
1442 return -1;
1443
1444 spec->cdefine.port_connectivity = ass >> 30;
1445 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1446 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1447 spec->cdefine.customization = ass >> 8;
1448do_sku:
1449 spec->cdefine.sku_cfg = ass;
1450 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1451 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1452 spec->cdefine.swap = (ass & 0x2) >> 1;
1453 spec->cdefine.override = ass & 0x1;
1454
1455 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1456 nid, spec->cdefine.sku_cfg);
1457 snd_printd("SKU: port_connectivity=0x%x\n",
1458 spec->cdefine.port_connectivity);
1459 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1460 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1461 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1462 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1463 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1464 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1465 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1466
1467 return 0;
1468}
1469
4a79ba34
TI
1470/* check subsystem ID and set up device-specific initialization;
1471 * return 1 if initialized, 0 if invalid SSID
1472 */
1473/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1474 * 31 ~ 16 : Manufacture ID
1475 * 15 ~ 8 : SKU ID
1476 * 7 ~ 0 : Assembly ID
1477 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1478 */
1479static int alc_subsystem_id(struct hda_codec *codec,
1480 hda_nid_t porta, hda_nid_t porte,
6227cdce 1481 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1482{
1483 unsigned int ass, tmp, i;
1484 unsigned nid;
1485 struct alc_spec *spec = codec->spec;
1486
90622917
DH
1487 if (spec->cdefine.fixup) {
1488 ass = spec->cdefine.sku_cfg;
1489 if (ass == ALC_FIXUP_SKU_IGNORE)
1490 return 0;
1491 goto do_sku;
1492 }
1493
4a79ba34
TI
1494 ass = codec->subsystem_id & 0xffff;
1495 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1496 goto do_sku;
1497
1498 /* invalid SSID, check the special NID pin defcfg instead */
1499 /*
def319f9 1500 * 31~30 : port connectivity
4a79ba34
TI
1501 * 29~21 : reserve
1502 * 20 : PCBEEP input
1503 * 19~16 : Check sum (15:1)
1504 * 15~1 : Custom
1505 * 0 : override
1506 */
1507 nid = 0x1d;
1508 if (codec->vendor_id == 0x10ec0260)
1509 nid = 0x17;
1510 ass = snd_hda_codec_get_pincfg(codec, nid);
1511 snd_printd("realtek: No valid SSID, "
1512 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1513 ass, nid);
6227cdce 1514 if (!(ass & 1))
4a79ba34
TI
1515 return 0;
1516 if ((ass >> 30) != 1) /* no physical connection */
1517 return 0;
1518
1519 /* check sum */
1520 tmp = 0;
1521 for (i = 1; i < 16; i++) {
1522 if ((ass >> i) & 1)
1523 tmp++;
1524 }
1525 if (((ass >> 16) & 0xf) != tmp)
1526 return 0;
1527do_sku:
1528 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1529 ass & 0xffff, codec->vendor_id);
1530 /*
1531 * 0 : override
1532 * 1 : Swap Jack
1533 * 2 : 0 --> Desktop, 1 --> Laptop
1534 * 3~5 : External Amplifier control
1535 * 7~6 : Reserved
1536 */
1537 tmp = (ass & 0x38) >> 3; /* external Amp control */
1538 switch (tmp) {
1539 case 1:
1540 spec->init_amp = ALC_INIT_GPIO1;
1541 break;
1542 case 3:
1543 spec->init_amp = ALC_INIT_GPIO2;
1544 break;
1545 case 7:
1546 spec->init_amp = ALC_INIT_GPIO3;
1547 break;
1548 case 5:
5a8cfb4e 1549 default:
4a79ba34 1550 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1551 break;
1552 }
ea1fb29a 1553
8c427226 1554 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1555 * when the external headphone out jack is plugged"
1556 */
8c427226 1557 if (!(ass & 0x8000))
4a79ba34 1558 return 1;
c9b58006
KY
1559 /*
1560 * 10~8 : Jack location
1561 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1562 * 14~13: Resvered
1563 * 15 : 1 --> enable the function "Mute internal speaker
1564 * when the external headphone out jack is plugged"
1565 */
c9b58006 1566 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1567 hda_nid_t nid;
c9b58006
KY
1568 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1569 if (tmp == 0)
01d4825d 1570 nid = porta;
c9b58006 1571 else if (tmp == 1)
01d4825d 1572 nid = porte;
c9b58006 1573 else if (tmp == 2)
01d4825d 1574 nid = portd;
6227cdce
KY
1575 else if (tmp == 3)
1576 nid = porti;
c9b58006 1577 else
4a79ba34 1578 return 1;
01d4825d
TI
1579 for (i = 0; i < spec->autocfg.line_outs; i++)
1580 if (spec->autocfg.line_out_pins[i] == nid)
1581 return 1;
1582 spec->autocfg.hp_pins[0] = nid;
c9b58006
KY
1583 }
1584
4a79ba34 1585 alc_init_auto_hp(codec);
6c819492 1586 alc_init_auto_mic(codec);
4a79ba34
TI
1587 return 1;
1588}
ea1fb29a 1589
4a79ba34 1590static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1591 hda_nid_t porta, hda_nid_t porte,
1592 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1593{
6227cdce 1594 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1595 struct alc_spec *spec = codec->spec;
1596 snd_printd("realtek: "
1597 "Enable default setup for auto mode as fallback\n");
1598 spec->init_amp = ALC_INIT_DEFAULT;
1599 alc_init_auto_hp(codec);
6c819492 1600 alc_init_auto_mic(codec);
4a79ba34 1601 }
bc9f98a9
KY
1602}
1603
f95474ec 1604/*
f8f25ba3 1605 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1606 */
1607
1608struct alc_pincfg {
1609 hda_nid_t nid;
1610 u32 val;
1611};
1612
e1eb5f10
TB
1613struct alc_model_fixup {
1614 const int id;
1615 const char *name;
1616};
1617
f8f25ba3 1618struct alc_fixup {
b5bfbc67 1619 int type;
361fe6e9
TI
1620 bool chained;
1621 int chain_id;
b5bfbc67
TI
1622 union {
1623 unsigned int sku;
1624 const struct alc_pincfg *pins;
1625 const struct hda_verb *verbs;
1626 void (*func)(struct hda_codec *codec,
1627 const struct alc_fixup *fix,
1628 int action);
1629 } v;
f8f25ba3
TI
1630};
1631
b5bfbc67
TI
1632enum {
1633 ALC_FIXUP_INVALID,
1634 ALC_FIXUP_SKU,
1635 ALC_FIXUP_PINS,
1636 ALC_FIXUP_VERBS,
1637 ALC_FIXUP_FUNC,
1638};
1639
1640enum {
1641 ALC_FIXUP_ACT_PRE_PROBE,
1642 ALC_FIXUP_ACT_PROBE,
58701120 1643 ALC_FIXUP_ACT_INIT,
b5bfbc67
TI
1644};
1645
1646static void alc_apply_fixup(struct hda_codec *codec, int action)
f95474ec 1647{
b5bfbc67
TI
1648 struct alc_spec *spec = codec->spec;
1649 int id = spec->fixup_id;
aa1d0c52 1650#ifdef CONFIG_SND_DEBUG_VERBOSE
b5bfbc67 1651 const char *modelname = spec->fixup_name;
aa1d0c52 1652#endif
b5bfbc67 1653 int depth = 0;
f95474ec 1654
b5bfbc67
TI
1655 if (!spec->fixup_list)
1656 return;
1657
1658 while (id >= 0) {
1659 const struct alc_fixup *fix = spec->fixup_list + id;
1660 const struct alc_pincfg *cfg;
1661
1662 switch (fix->type) {
1663 case ALC_FIXUP_SKU:
1664 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1665 break;;
1666 snd_printdd(KERN_INFO "hda_codec: %s: "
1667 "Apply sku override for %s\n",
1668 codec->chip_name, modelname);
1669 spec->cdefine.sku_cfg = fix->v.sku;
1670 spec->cdefine.fixup = 1;
1671 break;
1672 case ALC_FIXUP_PINS:
1673 cfg = fix->v.pins;
1674 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1675 break;
1676 snd_printdd(KERN_INFO "hda_codec: %s: "
1677 "Apply pincfg for %s\n",
1678 codec->chip_name, modelname);
1679 for (; cfg->nid; cfg++)
1680 snd_hda_codec_set_pincfg(codec, cfg->nid,
1681 cfg->val);
1682 break;
1683 case ALC_FIXUP_VERBS:
1684 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1685 break;
1686 snd_printdd(KERN_INFO "hda_codec: %s: "
1687 "Apply fix-verbs for %s\n",
1688 codec->chip_name, modelname);
1689 add_verb(codec->spec, fix->v.verbs);
1690 break;
1691 case ALC_FIXUP_FUNC:
1692 if (!fix->v.func)
1693 break;
1694 snd_printdd(KERN_INFO "hda_codec: %s: "
1695 "Apply fix-func for %s\n",
1696 codec->chip_name, modelname);
1697 fix->v.func(codec, fix, action);
1698 break;
1699 default:
1700 snd_printk(KERN_ERR "hda_codec: %s: "
1701 "Invalid fixup type %d\n",
1702 codec->chip_name, fix->type);
1703 break;
1704 }
1705 if (!fix[id].chained)
1706 break;
1707 if (++depth > 10)
1708 break;
1709 id = fix[id].chain_id;
9d57883f 1710 }
f95474ec
TI
1711}
1712
e1eb5f10 1713static void alc_pick_fixup(struct hda_codec *codec,
b5bfbc67
TI
1714 const struct alc_model_fixup *models,
1715 const struct snd_pci_quirk *quirk,
1716 const struct alc_fixup *fixlist)
e1eb5f10 1717{
b5bfbc67
TI
1718 struct alc_spec *spec = codec->spec;
1719 int id = -1;
1720 const char *name = NULL;
e1eb5f10 1721
e1eb5f10
TB
1722 if (codec->modelname && models) {
1723 while (models->name) {
1724 if (!strcmp(codec->modelname, models->name)) {
b5bfbc67
TI
1725 id = models->id;
1726 name = models->name;
e1eb5f10
TB
1727 break;
1728 }
1729 models++;
1730 }
b5bfbc67
TI
1731 }
1732 if (id < 0) {
1733 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1734 if (quirk) {
1735 id = quirk->value;
1736#ifdef CONFIG_SND_DEBUG_VERBOSE
1737 name = quirk->name;
1738#endif
1739 }
1740 }
1741
1742 spec->fixup_id = id;
1743 if (id >= 0) {
1744 spec->fixup_list = fixlist;
1745 spec->fixup_name = name;
e1eb5f10 1746 }
f95474ec
TI
1747}
1748
274693f3
KY
1749static int alc_read_coef_idx(struct hda_codec *codec,
1750 unsigned int coef_idx)
1751{
1752 unsigned int val;
1753 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1754 coef_idx);
1755 val = snd_hda_codec_read(codec, 0x20, 0,
1756 AC_VERB_GET_PROC_COEF, 0);
1757 return val;
1758}
1759
977ddd6b
KY
1760static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
1761 unsigned int coef_val)
1762{
1763 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1764 coef_idx);
1765 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
1766 coef_val);
1767}
1768
757899ac
TI
1769/* set right pin controls for digital I/O */
1770static void alc_auto_init_digital(struct hda_codec *codec)
1771{
1772 struct alc_spec *spec = codec->spec;
1773 int i;
1774 hda_nid_t pin;
1775
1776 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1777 pin = spec->autocfg.dig_out_pins[i];
1778 if (pin) {
1779 snd_hda_codec_write(codec, pin, 0,
1780 AC_VERB_SET_PIN_WIDGET_CONTROL,
1781 PIN_OUT);
1782 }
1783 }
1784 pin = spec->autocfg.dig_in_pin;
1785 if (pin)
1786 snd_hda_codec_write(codec, pin, 0,
1787 AC_VERB_SET_PIN_WIDGET_CONTROL,
1788 PIN_IN);
1789}
1790
1791/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1792static void alc_auto_parse_digital(struct hda_codec *codec)
1793{
1794 struct alc_spec *spec = codec->spec;
1795 int i, err;
1796 hda_nid_t dig_nid;
1797
1798 /* support multiple SPDIFs; the secondary is set up as a slave */
1799 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1800 err = snd_hda_get_connections(codec,
1801 spec->autocfg.dig_out_pins[i],
1802 &dig_nid, 1);
1803 if (err < 0)
1804 continue;
1805 if (!i) {
1806 spec->multiout.dig_out_nid = dig_nid;
1807 spec->dig_out_type = spec->autocfg.dig_out_type[0];
1808 } else {
1809 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1810 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1811 break;
1812 spec->slave_dig_outs[i - 1] = dig_nid;
1813 }
1814 }
1815
1816 if (spec->autocfg.dig_in_pin) {
01fdf180
TI
1817 dig_nid = codec->start_nid;
1818 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
1819 unsigned int wcaps = get_wcaps(codec, dig_nid);
1820 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
1821 continue;
1822 if (!(wcaps & AC_WCAP_DIGITAL))
1823 continue;
1824 if (!(wcaps & AC_WCAP_CONN_LIST))
1825 continue;
1826 err = get_connection_index(codec, dig_nid,
1827 spec->autocfg.dig_in_pin);
1828 if (err >= 0) {
1829 spec->dig_in_nid = dig_nid;
1830 break;
1831 }
1832 }
757899ac
TI
1833 }
1834}
1835
ef8ef5fb
VP
1836/*
1837 * ALC888
1838 */
1839
1840/*
1841 * 2ch mode
1842 */
1843static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1844/* Mic-in jack as mic in */
1845 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1846 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1847/* Line-in jack as Line in */
1848 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1849 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1850/* Line-Out as Front */
1851 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1852 { } /* end */
1853};
1854
1855/*
1856 * 4ch mode
1857 */
1858static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1859/* Mic-in jack as mic in */
1860 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1861 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1862/* Line-in jack as Surround */
1863 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1864 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1865/* Line-Out as Front */
1866 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1867 { } /* end */
1868};
1869
1870/*
1871 * 6ch mode
1872 */
1873static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1874/* Mic-in jack as CLFE */
1875 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1876 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1877/* Line-in jack as Surround */
1878 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1879 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1880/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1881 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1882 { } /* end */
1883};
1884
1885/*
1886 * 8ch mode
1887 */
1888static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1889/* Mic-in jack as CLFE */
1890 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1891 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1892/* Line-in jack as Surround */
1893 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1894 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1895/* Line-Out as Side */
1896 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1897 { } /* end */
1898};
1899
1900static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1901 { 2, alc888_4ST_ch2_intel_init },
1902 { 4, alc888_4ST_ch4_intel_init },
1903 { 6, alc888_4ST_ch6_intel_init },
1904 { 8, alc888_4ST_ch8_intel_init },
1905};
1906
1907/*
1908 * ALC888 Fujitsu Siemens Amillo xa3530
1909 */
1910
1911static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1912/* Front Mic: set to PIN_IN (empty by default) */
1913 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1914/* Connect Internal HP to Front */
1915 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1916 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1917 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1918/* Connect Bass HP to Front */
1919 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1920 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1921 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1922/* Connect Line-Out side jack (SPDIF) to Side */
1923 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1924 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1925 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1926/* Connect Mic jack to CLFE */
1927 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1928 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1929 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1930/* Connect Line-in jack to Surround */
1931 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1932 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1933 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1934/* Connect HP out jack to Front */
1935 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1936 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1937 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1938/* Enable unsolicited event for HP jack and Line-out jack */
1939 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1940 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1941 {}
1942};
1943
a9fd4f3f 1944static void alc_automute_amp(struct hda_codec *codec)
ef8ef5fb 1945{
bb35febd 1946 alc_automute_speaker(codec, 0);
ef8ef5fb
VP
1947}
1948
a9fd4f3f
TI
1949static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1950 unsigned int res)
ef8ef5fb 1951{
a9fd4f3f
TI
1952 if (codec->vendor_id == 0x10ec0880)
1953 res >>= 28;
1954 else
1955 res >>= 26;
1956 if (res == ALC880_HP_EVENT)
1957 alc_automute_amp(codec);
ef8ef5fb
VP
1958}
1959
4f5d1706 1960static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
1961{
1962 struct alc_spec *spec = codec->spec;
1963
1964 spec->autocfg.hp_pins[0] = 0x15;
1965 spec->autocfg.speaker_pins[0] = 0x14;
1966 spec->autocfg.speaker_pins[1] = 0x16;
1967 spec->autocfg.speaker_pins[2] = 0x17;
1968 spec->autocfg.speaker_pins[3] = 0x19;
1969 spec->autocfg.speaker_pins[4] = 0x1a;
6732bd0d
WF
1970}
1971
1972static void alc889_intel_init_hook(struct hda_codec *codec)
1973{
1974 alc889_coef_init(codec);
4f5d1706 1975 alc_automute_amp(codec);
6732bd0d
WF
1976}
1977
4f5d1706 1978static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
1979{
1980 struct alc_spec *spec = codec->spec;
1981
1982 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1983 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1984 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1985 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
a9fd4f3f 1986}
ef8ef5fb 1987
5b2d1eca
VP
1988/*
1989 * ALC888 Acer Aspire 4930G model
1990 */
1991
1992static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1993/* Front Mic: set to PIN_IN (empty by default) */
1994 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1995/* Unselect Front Mic by default in input mixer 3 */
1996 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 1997/* Enable unsolicited event for HP jack */
5b2d1eca
VP
1998 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1999/* Connect Internal HP to front */
2000 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2001 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2002 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2003/* Connect HP out to front */
2004 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2005 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2006 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
e2e93296 2007 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
5b2d1eca
VP
2008 { }
2009};
2010
d2fd4b09
TV
2011/*
2012 * ALC888 Acer Aspire 6530G model
2013 */
2014
2015static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
2016/* Route to built-in subwoofer as well as speakers */
2017 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2018 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2019 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2020 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
2021/* Bias voltage on for external mic port */
2022 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
2023/* Front Mic: set to PIN_IN (empty by default) */
2024 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2025/* Unselect Front Mic by default in input mixer 3 */
2026 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
2027/* Enable unsolicited event for HP jack */
2028 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2029/* Enable speaker output */
2030 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2031 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 2032 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2033/* Enable headphone output */
2034 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2035 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2036 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 2037 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2038 { }
2039};
2040
d9477207
DK
2041/*
2042 *ALC888 Acer Aspire 7730G model
2043 */
2044
2045static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2046/* Bias voltage on for external mic port */
2047 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2048/* Front Mic: set to PIN_IN (empty by default) */
2049 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2050/* Unselect Front Mic by default in input mixer 3 */
2051 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2052/* Enable unsolicited event for HP jack */
2053 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2054/* Enable speaker output */
2055 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2056 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2057 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2058/* Enable headphone output */
2059 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2060 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2061 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2062 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2063/*Enable internal subwoofer */
2064 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2065 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2066 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2067 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2068 { }
2069};
2070
3b315d70 2071/*
018df418 2072 * ALC889 Acer Aspire 8930G model
3b315d70
HM
2073 */
2074
018df418 2075static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
2076/* Front Mic: set to PIN_IN (empty by default) */
2077 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2078/* Unselect Front Mic by default in input mixer 3 */
2079 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2080/* Enable unsolicited event for HP jack */
2081 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2082/* Connect Internal Front to Front */
2083 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2084 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2085 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2086/* Connect Internal Rear to Rear */
2087 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2088 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2089 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2090/* Connect Internal CLFE to CLFE */
2091 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2092 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2093 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2094/* Connect HP out to Front */
018df418 2095 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
2096 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2097 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2098/* Enable all DACs */
2099/* DAC DISABLE/MUTE 1? */
2100/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2101 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2102 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2103/* DAC DISABLE/MUTE 2? */
2104/* some bit here disables the other DACs. Init=0x4900 */
2105 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2106 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
2107/* DMIC fix
2108 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2109 * which makes the stereo useless. However, either the mic or the ALC889
2110 * makes the signal become a difference/sum signal instead of standard
2111 * stereo, which is annoying. So instead we flip this bit which makes the
2112 * codec replicate the sum signal to both channels, turning it into a
2113 * normal mono mic.
2114 */
2115/* DMIC_CONTROL? Init value = 0x0001 */
2116 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2117 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
2118 { }
2119};
2120
ef8ef5fb 2121static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
2122 /* Front mic only available on one ADC */
2123 {
2124 .num_items = 4,
2125 .items = {
2126 { "Mic", 0x0 },
2127 { "Line", 0x2 },
2128 { "CD", 0x4 },
2129 { "Front Mic", 0xb },
2130 },
2131 },
2132 {
2133 .num_items = 3,
2134 .items = {
2135 { "Mic", 0x0 },
2136 { "Line", 0x2 },
2137 { "CD", 0x4 },
2138 },
2139 }
2140};
2141
d2fd4b09
TV
2142static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2143 /* Interal mic only available on one ADC */
2144 {
684a8842 2145 .num_items = 5,
d2fd4b09 2146 .items = {
8607f7c4 2147 { "Mic", 0x0 },
684a8842 2148 { "Line In", 0x2 },
d2fd4b09 2149 { "CD", 0x4 },
684a8842 2150 { "Input Mix", 0xa },
28c4edb7 2151 { "Internal Mic", 0xb },
d2fd4b09
TV
2152 },
2153 },
2154 {
684a8842 2155 .num_items = 4,
d2fd4b09 2156 .items = {
8607f7c4 2157 { "Mic", 0x0 },
684a8842 2158 { "Line In", 0x2 },
d2fd4b09 2159 { "CD", 0x4 },
684a8842 2160 { "Input Mix", 0xa },
d2fd4b09
TV
2161 },
2162 }
2163};
2164
018df418
HM
2165static struct hda_input_mux alc889_capture_sources[3] = {
2166 /* Digital mic only available on first "ADC" */
2167 {
2168 .num_items = 5,
2169 .items = {
2170 { "Mic", 0x0 },
2171 { "Line", 0x2 },
2172 { "CD", 0x4 },
2173 { "Front Mic", 0xb },
2174 { "Input Mix", 0xa },
2175 },
2176 },
2177 {
2178 .num_items = 4,
2179 .items = {
2180 { "Mic", 0x0 },
2181 { "Line", 0x2 },
2182 { "CD", 0x4 },
2183 { "Input Mix", 0xa },
2184 },
2185 },
2186 {
2187 .num_items = 4,
2188 .items = {
2189 { "Mic", 0x0 },
2190 { "Line", 0x2 },
2191 { "CD", 0x4 },
2192 { "Input Mix", 0xa },
2193 },
2194 }
2195};
2196
ef8ef5fb 2197static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
2198 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2199 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2200 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2201 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2202 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2203 HDA_OUTPUT),
2204 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2205 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2206 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2207 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2208 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2209 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2210 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2211 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2212 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2213 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2214 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
5b2d1eca 2215 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
2216 { } /* end */
2217};
2218
460c92fa
ŁW
2219static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
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),
786c51f9 2224 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
460c92fa 2225 HDA_OUTPUT),
786c51f9
ŁW
2226 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2227 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2228 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2229 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2230 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
460c92fa
ŁW
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),
2236 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2237 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
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 */
ea734963 2869static const char * const alc_slave_vols[] = {
2134ea4f
TI
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
ea734963 2883static const char * const alc_slave_sws[] = {
2134ea4f
TI
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
58701120
TI
3864 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
3865
9e5341b9 3866 hda_call_check_power_status(codec, 0x01);
1da177e4
LT
3867 return 0;
3868}
3869
ae6b813a
TI
3870static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3871{
3872 struct alc_spec *spec = codec->spec;
3873
3874 if (spec->unsol_event)
3875 spec->unsol_event(codec, res);
3876}
3877
cb53c626
TI
3878#ifdef CONFIG_SND_HDA_POWER_SAVE
3879static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3880{
3881 struct alc_spec *spec = codec->spec;
3882 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3883}
3884#endif
3885
1da177e4
LT
3886/*
3887 * Analog playback callbacks
3888 */
3889static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3890 struct hda_codec *codec,
c8b6bf9b 3891 struct snd_pcm_substream *substream)
1da177e4
LT
3892{
3893 struct alc_spec *spec = codec->spec;
9a08160b
TI
3894 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3895 hinfo);
1da177e4
LT
3896}
3897
3898static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3899 struct hda_codec *codec,
3900 unsigned int stream_tag,
3901 unsigned int format,
c8b6bf9b 3902 struct snd_pcm_substream *substream)
1da177e4
LT
3903{
3904 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3905 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3906 stream_tag, format, substream);
1da177e4
LT
3907}
3908
3909static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3910 struct hda_codec *codec,
c8b6bf9b 3911 struct snd_pcm_substream *substream)
1da177e4
LT
3912{
3913 struct alc_spec *spec = codec->spec;
3914 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3915}
3916
3917/*
3918 * Digital out
3919 */
3920static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3921 struct hda_codec *codec,
c8b6bf9b 3922 struct snd_pcm_substream *substream)
1da177e4
LT
3923{
3924 struct alc_spec *spec = codec->spec;
3925 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3926}
3927
6b97eb45
TI
3928static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3929 struct hda_codec *codec,
3930 unsigned int stream_tag,
3931 unsigned int format,
3932 struct snd_pcm_substream *substream)
3933{
3934 struct alc_spec *spec = codec->spec;
3935 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3936 stream_tag, format, substream);
3937}
3938
9b5f12e5
TI
3939static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3940 struct hda_codec *codec,
3941 struct snd_pcm_substream *substream)
3942{
3943 struct alc_spec *spec = codec->spec;
3944 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3945}
3946
1da177e4
LT
3947static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3948 struct hda_codec *codec,
c8b6bf9b 3949 struct snd_pcm_substream *substream)
1da177e4
LT
3950{
3951 struct alc_spec *spec = codec->spec;
3952 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3953}
3954
3955/*
3956 * Analog capture
3957 */
6330079f 3958static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3959 struct hda_codec *codec,
3960 unsigned int stream_tag,
3961 unsigned int format,
c8b6bf9b 3962 struct snd_pcm_substream *substream)
1da177e4
LT
3963{
3964 struct alc_spec *spec = codec->spec;
3965
6330079f 3966 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3967 stream_tag, 0, format);
3968 return 0;
3969}
3970
6330079f 3971static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3972 struct hda_codec *codec,
c8b6bf9b 3973 struct snd_pcm_substream *substream)
1da177e4
LT
3974{
3975 struct alc_spec *spec = codec->spec;
3976
888afa15
TI
3977 snd_hda_codec_cleanup_stream(codec,
3978 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3979 return 0;
3980}
3981
840b64c0
TI
3982/* analog capture with dynamic dual-adc changes */
3983static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3984 struct hda_codec *codec,
3985 unsigned int stream_tag,
3986 unsigned int format,
3987 struct snd_pcm_substream *substream)
3988{
3989 struct alc_spec *spec = codec->spec;
3990 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
3991 spec->cur_adc_stream_tag = stream_tag;
3992 spec->cur_adc_format = format;
3993 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
3994 return 0;
3995}
3996
3997static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3998 struct hda_codec *codec,
3999 struct snd_pcm_substream *substream)
4000{
4001 struct alc_spec *spec = codec->spec;
4002 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4003 spec->cur_adc = 0;
4004 return 0;
4005}
4006
4007static struct hda_pcm_stream dualmic_pcm_analog_capture = {
4008 .substreams = 1,
4009 .channels_min = 2,
4010 .channels_max = 2,
4011 .nid = 0, /* fill later */
4012 .ops = {
4013 .prepare = dualmic_capture_pcm_prepare,
4014 .cleanup = dualmic_capture_pcm_cleanup
4015 },
4016};
1da177e4
LT
4017
4018/*
4019 */
4020static struct hda_pcm_stream alc880_pcm_analog_playback = {
4021 .substreams = 1,
4022 .channels_min = 2,
4023 .channels_max = 8,
e9edcee0 4024 /* NID is set in alc_build_pcms */
1da177e4
LT
4025 .ops = {
4026 .open = alc880_playback_pcm_open,
4027 .prepare = alc880_playback_pcm_prepare,
4028 .cleanup = alc880_playback_pcm_cleanup
4029 },
4030};
4031
4032static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
4033 .substreams = 1,
4034 .channels_min = 2,
4035 .channels_max = 2,
4036 /* NID is set in alc_build_pcms */
4037};
4038
4039static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
4040 .substreams = 1,
4041 .channels_min = 2,
4042 .channels_max = 2,
4043 /* NID is set in alc_build_pcms */
4044};
4045
4046static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4047 .substreams = 2, /* can be overridden */
1da177e4
LT
4048 .channels_min = 2,
4049 .channels_max = 2,
e9edcee0 4050 /* NID is set in alc_build_pcms */
1da177e4 4051 .ops = {
6330079f
TI
4052 .prepare = alc880_alt_capture_pcm_prepare,
4053 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
4054 },
4055};
4056
4057static struct hda_pcm_stream alc880_pcm_digital_playback = {
4058 .substreams = 1,
4059 .channels_min = 2,
4060 .channels_max = 2,
4061 /* NID is set in alc_build_pcms */
4062 .ops = {
4063 .open = alc880_dig_playback_pcm_open,
6b97eb45 4064 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
4065 .prepare = alc880_dig_playback_pcm_prepare,
4066 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
4067 },
4068};
4069
4070static struct hda_pcm_stream alc880_pcm_digital_capture = {
4071 .substreams = 1,
4072 .channels_min = 2,
4073 .channels_max = 2,
4074 /* NID is set in alc_build_pcms */
4075};
4076
4c5186ed 4077/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 4078static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
4079 .substreams = 0,
4080 .channels_min = 0,
4081 .channels_max = 0,
4082};
4083
1da177e4
LT
4084static int alc_build_pcms(struct hda_codec *codec)
4085{
4086 struct alc_spec *spec = codec->spec;
4087 struct hda_pcm *info = spec->pcm_rec;
4088 int i;
4089
4090 codec->num_pcms = 1;
4091 codec->pcm_info = info;
4092
e64f14f4
TI
4093 if (spec->no_analog)
4094 goto skip_analog;
4095
812a2cca
TI
4096 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4097 "%s Analog", codec->chip_name);
1da177e4 4098 info->name = spec->stream_name_analog;
274693f3 4099
4a471b7d 4100 if (spec->stream_analog_playback) {
da3cec35
TI
4101 if (snd_BUG_ON(!spec->multiout.dac_nids))
4102 return -EINVAL;
4a471b7d
TI
4103 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4104 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4105 }
4106 if (spec->stream_analog_capture) {
da3cec35
TI
4107 if (snd_BUG_ON(!spec->adc_nids))
4108 return -EINVAL;
4a471b7d
TI
4109 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4110 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4111 }
4112
4113 if (spec->channel_mode) {
4114 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4115 for (i = 0; i < spec->num_channel_mode; i++) {
4116 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4117 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4118 }
1da177e4
LT
4119 }
4120 }
4121
e64f14f4 4122 skip_analog:
e08a007d 4123 /* SPDIF for stream index #1 */
1da177e4 4124 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
4125 snprintf(spec->stream_name_digital,
4126 sizeof(spec->stream_name_digital),
4127 "%s Digital", codec->chip_name);
e08a007d 4128 codec->num_pcms = 2;
b25c9da1 4129 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 4130 info = spec->pcm_rec + 1;
1da177e4 4131 info->name = spec->stream_name_digital;
8c441982
TI
4132 if (spec->dig_out_type)
4133 info->pcm_type = spec->dig_out_type;
4134 else
4135 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
4136 if (spec->multiout.dig_out_nid &&
4137 spec->stream_digital_playback) {
1da177e4
LT
4138 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4139 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4140 }
4a471b7d
TI
4141 if (spec->dig_in_nid &&
4142 spec->stream_digital_capture) {
1da177e4
LT
4143 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4144 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4145 }
963f803f
TI
4146 /* FIXME: do we need this for all Realtek codec models? */
4147 codec->spdif_status_reset = 1;
1da177e4
LT
4148 }
4149
e64f14f4
TI
4150 if (spec->no_analog)
4151 return 0;
4152
e08a007d
TI
4153 /* If the use of more than one ADC is requested for the current
4154 * model, configure a second analog capture-only PCM.
4155 */
4156 /* Additional Analaog capture for index #2 */
6330079f
TI
4157 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4158 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 4159 codec->num_pcms = 3;
c06134d7 4160 info = spec->pcm_rec + 2;
e08a007d 4161 info->name = spec->stream_name_analog;
6330079f
TI
4162 if (spec->alt_dac_nid) {
4163 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4164 *spec->stream_analog_alt_playback;
4165 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4166 spec->alt_dac_nid;
4167 } else {
4168 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4169 alc_pcm_null_stream;
4170 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4171 }
4172 if (spec->num_adc_nids > 1) {
4173 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4174 *spec->stream_analog_alt_capture;
4175 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4176 spec->adc_nids[1];
4177 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4178 spec->num_adc_nids - 1;
4179 } else {
4180 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4181 alc_pcm_null_stream;
4182 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4183 }
4184 }
4185
1da177e4
LT
4186 return 0;
4187}
4188
a4e09aa3
TI
4189static inline void alc_shutup(struct hda_codec *codec)
4190{
4191 snd_hda_shutup_pins(codec);
4192}
4193
603c4019
TI
4194static void alc_free_kctls(struct hda_codec *codec)
4195{
4196 struct alc_spec *spec = codec->spec;
4197
4198 if (spec->kctls.list) {
4199 struct snd_kcontrol_new *kctl = spec->kctls.list;
4200 int i;
4201 for (i = 0; i < spec->kctls.used; i++)
4202 kfree(kctl[i].name);
4203 }
4204 snd_array_free(&spec->kctls);
4205}
4206
1da177e4
LT
4207static void alc_free(struct hda_codec *codec)
4208{
e9edcee0 4209 struct alc_spec *spec = codec->spec;
e9edcee0 4210
f12ab1e0 4211 if (!spec)
e9edcee0
TI
4212 return;
4213
a4e09aa3 4214 alc_shutup(codec);
cd372fb3 4215 snd_hda_input_jack_free(codec);
603c4019 4216 alc_free_kctls(codec);
e9edcee0 4217 kfree(spec);
680cd536 4218 snd_hda_detach_beep_device(codec);
1da177e4
LT
4219}
4220
f5de24b0 4221#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4222static void alc_power_eapd(struct hda_codec *codec)
4223{
4224 /* We currently only handle front, HP */
4225 switch (codec->vendor_id) {
4226 case 0x10ec0260:
9e4c8496
TI
4227 set_eapd(codec, 0x0f, 0);
4228 set_eapd(codec, 0x10, 0);
c97259df
DC
4229 break;
4230 case 0x10ec0262:
4231 case 0x10ec0267:
4232 case 0x10ec0268:
4233 case 0x10ec0269:
9e4c8496 4234 case 0x10ec0270:
c97259df
DC
4235 case 0x10ec0272:
4236 case 0x10ec0660:
4237 case 0x10ec0662:
4238 case 0x10ec0663:
4239 case 0x10ec0862:
4240 case 0x10ec0889:
9e4c8496
TI
4241 set_eapd(codec, 0x14, 0);
4242 set_eapd(codec, 0x15, 0);
c97259df
DC
4243 break;
4244 }
4245}
4246
f5de24b0
HM
4247static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4248{
4249 struct alc_spec *spec = codec->spec;
a4e09aa3 4250 alc_shutup(codec);
f5de24b0 4251 if (spec && spec->power_hook)
c97259df 4252 spec->power_hook(codec);
f5de24b0
HM
4253 return 0;
4254}
4255#endif
4256
e044c39a 4257#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4258static int alc_resume(struct hda_codec *codec)
4259{
e044c39a
TI
4260 codec->patch_ops.init(codec);
4261 snd_hda_codec_resume_amp(codec);
4262 snd_hda_codec_resume_cache(codec);
9e5341b9 4263 hda_call_check_power_status(codec, 0x01);
e044c39a
TI
4264 return 0;
4265}
e044c39a
TI
4266#endif
4267
1da177e4
LT
4268/*
4269 */
4270static struct hda_codec_ops alc_patch_ops = {
4271 .build_controls = alc_build_controls,
4272 .build_pcms = alc_build_pcms,
4273 .init = alc_init,
4274 .free = alc_free,
ae6b813a 4275 .unsol_event = alc_unsol_event,
e044c39a
TI
4276#ifdef SND_HDA_NEEDS_RESUME
4277 .resume = alc_resume,
4278#endif
cb53c626 4279#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4280 .suspend = alc_suspend,
cb53c626
TI
4281 .check_power_status = alc_check_power_status,
4282#endif
c97259df 4283 .reboot_notify = alc_shutup,
1da177e4
LT
4284};
4285
c027ddcd
KY
4286/* replace the codec chip_name with the given string */
4287static int alc_codec_rename(struct hda_codec *codec, const char *name)
4288{
4289 kfree(codec->chip_name);
4290 codec->chip_name = kstrdup(name, GFP_KERNEL);
4291 if (!codec->chip_name) {
4292 alc_free(codec);
4293 return -ENOMEM;
4294 }
4295 return 0;
4296}
4297
2fa522be
TI
4298/*
4299 * Test configuration for debugging
4300 *
4301 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4302 * enum controls.
4303 */
4304#ifdef CONFIG_SND_DEBUG
4305static hda_nid_t alc880_test_dac_nids[4] = {
4306 0x02, 0x03, 0x04, 0x05
4307};
4308
4309static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4310 .num_items = 7,
2fa522be
TI
4311 .items = {
4312 { "In-1", 0x0 },
4313 { "In-2", 0x1 },
4314 { "In-3", 0x2 },
4315 { "In-4", 0x3 },
4316 { "CD", 0x4 },
ae6b813a
TI
4317 { "Front", 0x5 },
4318 { "Surround", 0x6 },
2fa522be
TI
4319 },
4320};
4321
d2a6d7dc 4322static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4323 { 2, NULL },
fd2c326d 4324 { 4, NULL },
2fa522be 4325 { 6, NULL },
fd2c326d 4326 { 8, NULL },
2fa522be
TI
4327};
4328
9c7f852e
TI
4329static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4330 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4331{
4332 static char *texts[] = {
4333 "N/A", "Line Out", "HP Out",
4334 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4335 };
4336 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4337 uinfo->count = 1;
4338 uinfo->value.enumerated.items = 8;
4339 if (uinfo->value.enumerated.item >= 8)
4340 uinfo->value.enumerated.item = 7;
4341 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4342 return 0;
4343}
4344
9c7f852e
TI
4345static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4346 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4347{
4348 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4349 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4350 unsigned int pin_ctl, item = 0;
4351
4352 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4353 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4354 if (pin_ctl & AC_PINCTL_OUT_EN) {
4355 if (pin_ctl & AC_PINCTL_HP_EN)
4356 item = 2;
4357 else
4358 item = 1;
4359 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4360 switch (pin_ctl & AC_PINCTL_VREFEN) {
4361 case AC_PINCTL_VREF_HIZ: item = 3; break;
4362 case AC_PINCTL_VREF_50: item = 4; break;
4363 case AC_PINCTL_VREF_GRD: item = 5; break;
4364 case AC_PINCTL_VREF_80: item = 6; break;
4365 case AC_PINCTL_VREF_100: item = 7; break;
4366 }
4367 }
4368 ucontrol->value.enumerated.item[0] = item;
4369 return 0;
4370}
4371
9c7f852e
TI
4372static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4373 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4374{
4375 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4376 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4377 static unsigned int ctls[] = {
4378 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4379 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4380 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4381 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4382 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4383 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4384 };
4385 unsigned int old_ctl, new_ctl;
4386
4387 old_ctl = snd_hda_codec_read(codec, nid, 0,
4388 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4389 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4390 if (old_ctl != new_ctl) {
82beb8fd
TI
4391 int val;
4392 snd_hda_codec_write_cache(codec, nid, 0,
4393 AC_VERB_SET_PIN_WIDGET_CONTROL,
4394 new_ctl);
47fd830a
TI
4395 val = ucontrol->value.enumerated.item[0] >= 3 ?
4396 HDA_AMP_MUTE : 0;
4397 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4398 HDA_AMP_MUTE, val);
2fa522be
TI
4399 return 1;
4400 }
4401 return 0;
4402}
4403
9c7f852e
TI
4404static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4405 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4406{
4407 static char *texts[] = {
4408 "Front", "Surround", "CLFE", "Side"
4409 };
4410 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4411 uinfo->count = 1;
4412 uinfo->value.enumerated.items = 4;
4413 if (uinfo->value.enumerated.item >= 4)
4414 uinfo->value.enumerated.item = 3;
4415 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4416 return 0;
4417}
4418
9c7f852e
TI
4419static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4420 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4421{
4422 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4423 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4424 unsigned int sel;
4425
4426 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4427 ucontrol->value.enumerated.item[0] = sel & 3;
4428 return 0;
4429}
4430
9c7f852e
TI
4431static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4432 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4433{
4434 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4435 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4436 unsigned int sel;
4437
4438 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4439 if (ucontrol->value.enumerated.item[0] != sel) {
4440 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4441 snd_hda_codec_write_cache(codec, nid, 0,
4442 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4443 return 1;
4444 }
4445 return 0;
4446}
4447
4448#define PIN_CTL_TEST(xname,nid) { \
4449 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4450 .name = xname, \
5b0cb1d8 4451 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4452 .info = alc_test_pin_ctl_info, \
4453 .get = alc_test_pin_ctl_get, \
4454 .put = alc_test_pin_ctl_put, \
4455 .private_value = nid \
4456 }
4457
4458#define PIN_SRC_TEST(xname,nid) { \
4459 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4460 .name = xname, \
5b0cb1d8 4461 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4462 .info = alc_test_pin_src_info, \
4463 .get = alc_test_pin_src_get, \
4464 .put = alc_test_pin_src_put, \
4465 .private_value = nid \
4466 }
4467
c8b6bf9b 4468static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4469 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4470 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4471 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4472 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4473 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4474 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4475 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4476 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4477 PIN_CTL_TEST("Front Pin Mode", 0x14),
4478 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4479 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4480 PIN_CTL_TEST("Side Pin Mode", 0x17),
4481 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4482 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4483 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4484 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4485 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4486 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4487 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4488 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4489 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4490 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4491 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4492 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4493 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4494 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4495 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4496 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4497 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4498 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4499 {
4500 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4501 .name = "Channel Mode",
df694daa
KY
4502 .info = alc_ch_mode_info,
4503 .get = alc_ch_mode_get,
4504 .put = alc_ch_mode_put,
2fa522be
TI
4505 },
4506 { } /* end */
4507};
4508
4509static struct hda_verb alc880_test_init_verbs[] = {
4510 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4511 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4513 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4515 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4516 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4517 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4518 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4519 /* Vol output for 0x0c-0x0f */
05acb863
TI
4520 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4521 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4522 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4523 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4524 /* Set output pins 0x14-0x17 */
05acb863
TI
4525 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4526 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4527 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4528 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4529 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4530 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4531 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4532 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4533 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4534 /* Set input pins 0x18-0x1c */
16ded525
TI
4535 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4536 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4537 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4538 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4539 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4540 /* Mute input pins 0x18-0x1b */
05acb863
TI
4541 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4542 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4543 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4544 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4545 /* ADC set up */
05acb863 4546 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4547 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4548 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4549 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4550 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4551 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4552 /* Analog input/passthru */
4553 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4554 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4555 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4556 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4557 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4558 { }
4559};
4560#endif
4561
1da177e4
LT
4562/*
4563 */
4564
ea734963 4565static const char * const alc880_models[ALC880_MODEL_LAST] = {
f5fcc13c
TI
4566 [ALC880_3ST] = "3stack",
4567 [ALC880_TCL_S700] = "tcl",
4568 [ALC880_3ST_DIG] = "3stack-digout",
4569 [ALC880_CLEVO] = "clevo",
4570 [ALC880_5ST] = "5stack",
4571 [ALC880_5ST_DIG] = "5stack-digout",
4572 [ALC880_W810] = "w810",
4573 [ALC880_Z71V] = "z71v",
4574 [ALC880_6ST] = "6stack",
4575 [ALC880_6ST_DIG] = "6stack-digout",
4576 [ALC880_ASUS] = "asus",
4577 [ALC880_ASUS_W1V] = "asus-w1v",
4578 [ALC880_ASUS_DIG] = "asus-dig",
4579 [ALC880_ASUS_DIG2] = "asus-dig2",
4580 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4581 [ALC880_UNIWILL_P53] = "uniwill-p53",
4582 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4583 [ALC880_F1734] = "F1734",
4584 [ALC880_LG] = "lg",
4585 [ALC880_LG_LW] = "lg-lw",
df99cd33 4586 [ALC880_MEDION_RIM] = "medion",
2fa522be 4587#ifdef CONFIG_SND_DEBUG
f5fcc13c 4588 [ALC880_TEST] = "test",
2fa522be 4589#endif
f5fcc13c
TI
4590 [ALC880_AUTO] = "auto",
4591};
4592
4593static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4594 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4595 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4596 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4597 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4598 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4599 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4600 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4601 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4602 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4603 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4604 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4605 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4606 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4607 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4608 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4609 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4610 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4611 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4612 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4613 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4614 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4615 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4616 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4617 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4618 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4619 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4620 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4621 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4622 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4623 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4624 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4625 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4626 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4627 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4628 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4629 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4630 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4631 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4632 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4633 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 4634 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
4635 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4636 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4637 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4638 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4639 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4640 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4641 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4642 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4643 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4644 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4645 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c 4646 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
77c4d5cd 4647 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
f5fcc13c 4648 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4649 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4650 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4651 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4652 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4653 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4654 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4655 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4656 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4657 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4658 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4659 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4660 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4661 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4662 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4663 /* default Intel */
4664 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4665 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4666 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4667 {}
4668};
4669
16ded525 4670/*
df694daa 4671 * ALC880 codec presets
16ded525 4672 */
16ded525
TI
4673static struct alc_config_preset alc880_presets[] = {
4674 [ALC880_3ST] = {
e9edcee0 4675 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4676 .init_verbs = { alc880_volume_init_verbs,
4677 alc880_pin_3stack_init_verbs },
16ded525 4678 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4679 .dac_nids = alc880_dac_nids,
16ded525
TI
4680 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4681 .channel_mode = alc880_threestack_modes,
4e195a7b 4682 .need_dac_fix = 1,
16ded525
TI
4683 .input_mux = &alc880_capture_source,
4684 },
4685 [ALC880_3ST_DIG] = {
e9edcee0 4686 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4687 .init_verbs = { alc880_volume_init_verbs,
4688 alc880_pin_3stack_init_verbs },
16ded525 4689 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4690 .dac_nids = alc880_dac_nids,
4691 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4692 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4693 .channel_mode = alc880_threestack_modes,
4e195a7b 4694 .need_dac_fix = 1,
16ded525
TI
4695 .input_mux = &alc880_capture_source,
4696 },
df694daa
KY
4697 [ALC880_TCL_S700] = {
4698 .mixers = { alc880_tcl_s700_mixer },
4699 .init_verbs = { alc880_volume_init_verbs,
4700 alc880_pin_tcl_S700_init_verbs,
4701 alc880_gpio2_init_verbs },
4702 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4703 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4704 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4705 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4706 .hp_nid = 0x03,
4707 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4708 .channel_mode = alc880_2_jack_modes,
4709 .input_mux = &alc880_capture_source,
4710 },
16ded525 4711 [ALC880_5ST] = {
f12ab1e0
TI
4712 .mixers = { alc880_three_stack_mixer,
4713 alc880_five_stack_mixer},
4714 .init_verbs = { alc880_volume_init_verbs,
4715 alc880_pin_5stack_init_verbs },
16ded525
TI
4716 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4717 .dac_nids = alc880_dac_nids,
16ded525
TI
4718 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4719 .channel_mode = alc880_fivestack_modes,
4720 .input_mux = &alc880_capture_source,
4721 },
4722 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4723 .mixers = { alc880_three_stack_mixer,
4724 alc880_five_stack_mixer },
4725 .init_verbs = { alc880_volume_init_verbs,
4726 alc880_pin_5stack_init_verbs },
16ded525
TI
4727 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4728 .dac_nids = alc880_dac_nids,
4729 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4730 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4731 .channel_mode = alc880_fivestack_modes,
4732 .input_mux = &alc880_capture_source,
4733 },
b6482d48
TI
4734 [ALC880_6ST] = {
4735 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4736 .init_verbs = { alc880_volume_init_verbs,
4737 alc880_pin_6stack_init_verbs },
b6482d48
TI
4738 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4739 .dac_nids = alc880_6st_dac_nids,
4740 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4741 .channel_mode = alc880_sixstack_modes,
4742 .input_mux = &alc880_6stack_capture_source,
4743 },
16ded525 4744 [ALC880_6ST_DIG] = {
e9edcee0 4745 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4746 .init_verbs = { alc880_volume_init_verbs,
4747 alc880_pin_6stack_init_verbs },
16ded525
TI
4748 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4749 .dac_nids = alc880_6st_dac_nids,
4750 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4751 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4752 .channel_mode = alc880_sixstack_modes,
4753 .input_mux = &alc880_6stack_capture_source,
4754 },
4755 [ALC880_W810] = {
e9edcee0 4756 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4757 .init_verbs = { alc880_volume_init_verbs,
4758 alc880_pin_w810_init_verbs,
b0af0de5 4759 alc880_gpio2_init_verbs },
16ded525
TI
4760 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4761 .dac_nids = alc880_w810_dac_nids,
4762 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4763 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4764 .channel_mode = alc880_w810_modes,
4765 .input_mux = &alc880_capture_source,
4766 },
4767 [ALC880_Z71V] = {
e9edcee0 4768 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
4769 .init_verbs = { alc880_volume_init_verbs,
4770 alc880_pin_z71v_init_verbs },
16ded525
TI
4771 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4772 .dac_nids = alc880_z71v_dac_nids,
4773 .dig_out_nid = ALC880_DIGOUT_NID,
4774 .hp_nid = 0x03,
e9edcee0
TI
4775 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4776 .channel_mode = alc880_2_jack_modes,
16ded525
TI
4777 .input_mux = &alc880_capture_source,
4778 },
4779 [ALC880_F1734] = {
e9edcee0 4780 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
4781 .init_verbs = { alc880_volume_init_verbs,
4782 alc880_pin_f1734_init_verbs },
e9edcee0
TI
4783 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4784 .dac_nids = alc880_f1734_dac_nids,
4785 .hp_nid = 0x02,
4786 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4787 .channel_mode = alc880_2_jack_modes,
937b4160
TI
4788 .input_mux = &alc880_f1734_capture_source,
4789 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4790 .setup = alc880_uniwill_p53_setup,
4791 .init_hook = alc_automute_amp,
16ded525
TI
4792 },
4793 [ALC880_ASUS] = {
e9edcee0 4794 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4795 .init_verbs = { alc880_volume_init_verbs,
4796 alc880_pin_asus_init_verbs,
e9edcee0
TI
4797 alc880_gpio1_init_verbs },
4798 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4799 .dac_nids = alc880_asus_dac_nids,
4800 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4801 .channel_mode = alc880_asus_modes,
4e195a7b 4802 .need_dac_fix = 1,
16ded525
TI
4803 .input_mux = &alc880_capture_source,
4804 },
4805 [ALC880_ASUS_DIG] = {
e9edcee0 4806 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4807 .init_verbs = { alc880_volume_init_verbs,
4808 alc880_pin_asus_init_verbs,
e9edcee0
TI
4809 alc880_gpio1_init_verbs },
4810 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4811 .dac_nids = alc880_asus_dac_nids,
16ded525 4812 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4813 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4814 .channel_mode = alc880_asus_modes,
4e195a7b 4815 .need_dac_fix = 1,
16ded525
TI
4816 .input_mux = &alc880_capture_source,
4817 },
df694daa
KY
4818 [ALC880_ASUS_DIG2] = {
4819 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4820 .init_verbs = { alc880_volume_init_verbs,
4821 alc880_pin_asus_init_verbs,
df694daa
KY
4822 alc880_gpio2_init_verbs }, /* use GPIO2 */
4823 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4824 .dac_nids = alc880_asus_dac_nids,
4825 .dig_out_nid = ALC880_DIGOUT_NID,
4826 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4827 .channel_mode = alc880_asus_modes,
4e195a7b 4828 .need_dac_fix = 1,
df694daa
KY
4829 .input_mux = &alc880_capture_source,
4830 },
16ded525 4831 [ALC880_ASUS_W1V] = {
e9edcee0 4832 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
4833 .init_verbs = { alc880_volume_init_verbs,
4834 alc880_pin_asus_init_verbs,
e9edcee0
TI
4835 alc880_gpio1_init_verbs },
4836 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4837 .dac_nids = alc880_asus_dac_nids,
16ded525 4838 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4839 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4840 .channel_mode = alc880_asus_modes,
4e195a7b 4841 .need_dac_fix = 1,
16ded525
TI
4842 .input_mux = &alc880_capture_source,
4843 },
4844 [ALC880_UNIWILL_DIG] = {
45bdd1c1 4845 .mixers = { alc880_asus_mixer },
ccc656ce
KY
4846 .init_verbs = { alc880_volume_init_verbs,
4847 alc880_pin_asus_init_verbs },
e9edcee0
TI
4848 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4849 .dac_nids = alc880_asus_dac_nids,
16ded525 4850 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4851 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4852 .channel_mode = alc880_asus_modes,
4e195a7b 4853 .need_dac_fix = 1,
16ded525
TI
4854 .input_mux = &alc880_capture_source,
4855 },
ccc656ce
KY
4856 [ALC880_UNIWILL] = {
4857 .mixers = { alc880_uniwill_mixer },
4858 .init_verbs = { alc880_volume_init_verbs,
4859 alc880_uniwill_init_verbs },
4860 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4861 .dac_nids = alc880_asus_dac_nids,
4862 .dig_out_nid = ALC880_DIGOUT_NID,
4863 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4864 .channel_mode = alc880_threestack_modes,
4865 .need_dac_fix = 1,
4866 .input_mux = &alc880_capture_source,
4867 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 4868 .setup = alc880_uniwill_setup,
a9fd4f3f 4869 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
4870 },
4871 [ALC880_UNIWILL_P53] = {
4872 .mixers = { alc880_uniwill_p53_mixer },
4873 .init_verbs = { alc880_volume_init_verbs,
4874 alc880_uniwill_p53_init_verbs },
4875 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4876 .dac_nids = alc880_asus_dac_nids,
4877 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4878 .channel_mode = alc880_threestack_modes,
4879 .input_mux = &alc880_capture_source,
4880 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4881 .setup = alc880_uniwill_p53_setup,
4882 .init_hook = alc_automute_amp,
2cf9f0fc
TD
4883 },
4884 [ALC880_FUJITSU] = {
45bdd1c1 4885 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4886 .init_verbs = { alc880_volume_init_verbs,
4887 alc880_uniwill_p53_init_verbs,
4888 alc880_beep_init_verbs },
4889 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4890 .dac_nids = alc880_dac_nids,
d53d7d9e 4891 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4892 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4893 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4894 .input_mux = &alc880_capture_source,
4895 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4896 .setup = alc880_uniwill_p53_setup,
4897 .init_hook = alc_automute_amp,
ccc656ce 4898 },
df694daa
KY
4899 [ALC880_CLEVO] = {
4900 .mixers = { alc880_three_stack_mixer },
4901 .init_verbs = { alc880_volume_init_verbs,
4902 alc880_pin_clevo_init_verbs },
4903 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4904 .dac_nids = alc880_dac_nids,
4905 .hp_nid = 0x03,
4906 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4907 .channel_mode = alc880_threestack_modes,
4e195a7b 4908 .need_dac_fix = 1,
df694daa
KY
4909 .input_mux = &alc880_capture_source,
4910 },
ae6b813a
TI
4911 [ALC880_LG] = {
4912 .mixers = { alc880_lg_mixer },
4913 .init_verbs = { alc880_volume_init_verbs,
4914 alc880_lg_init_verbs },
4915 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4916 .dac_nids = alc880_lg_dac_nids,
4917 .dig_out_nid = ALC880_DIGOUT_NID,
4918 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4919 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4920 .need_dac_fix = 1,
ae6b813a 4921 .input_mux = &alc880_lg_capture_source,
a9fd4f3f 4922 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4923 .setup = alc880_lg_setup,
4924 .init_hook = alc_automute_amp,
cb53c626
TI
4925#ifdef CONFIG_SND_HDA_POWER_SAVE
4926 .loopbacks = alc880_lg_loopbacks,
4927#endif
ae6b813a 4928 },
d681518a
TI
4929 [ALC880_LG_LW] = {
4930 .mixers = { alc880_lg_lw_mixer },
4931 .init_verbs = { alc880_volume_init_verbs,
4932 alc880_lg_lw_init_verbs },
0a8c5da3 4933 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
4934 .dac_nids = alc880_dac_nids,
4935 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
4936 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4937 .channel_mode = alc880_lg_lw_modes,
d681518a 4938 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f 4939 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4940 .setup = alc880_lg_lw_setup,
4941 .init_hook = alc_automute_amp,
d681518a 4942 },
df99cd33
TI
4943 [ALC880_MEDION_RIM] = {
4944 .mixers = { alc880_medion_rim_mixer },
4945 .init_verbs = { alc880_volume_init_verbs,
4946 alc880_medion_rim_init_verbs,
4947 alc_gpio2_init_verbs },
4948 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4949 .dac_nids = alc880_dac_nids,
4950 .dig_out_nid = ALC880_DIGOUT_NID,
4951 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4952 .channel_mode = alc880_2_jack_modes,
4953 .input_mux = &alc880_medion_rim_capture_source,
4954 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
4955 .setup = alc880_medion_rim_setup,
4956 .init_hook = alc880_medion_rim_automute,
df99cd33 4957 },
16ded525
TI
4958#ifdef CONFIG_SND_DEBUG
4959 [ALC880_TEST] = {
e9edcee0
TI
4960 .mixers = { alc880_test_mixer },
4961 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
4962 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4963 .dac_nids = alc880_test_dac_nids,
4964 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4965 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4966 .channel_mode = alc880_test_modes,
4967 .input_mux = &alc880_test_capture_source,
4968 },
4969#endif
4970};
4971
e9edcee0
TI
4972/*
4973 * Automatic parse of I/O pins from the BIOS configuration
4974 */
4975
e9edcee0
TI
4976enum {
4977 ALC_CTL_WIDGET_VOL,
4978 ALC_CTL_WIDGET_MUTE,
4979 ALC_CTL_BIND_MUTE,
4980};
c8b6bf9b 4981static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
4982 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4983 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 4984 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
4985};
4986
4987/* add dynamic controls */
f12ab1e0 4988static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 4989 int cidx, unsigned long val)
e9edcee0 4990{
c8b6bf9b 4991 struct snd_kcontrol_new *knew;
e9edcee0 4992
603c4019
TI
4993 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4994 knew = snd_array_new(&spec->kctls);
4995 if (!knew)
4996 return -ENOMEM;
e9edcee0 4997 *knew = alc880_control_templates[type];
543537bd 4998 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 4999 if (!knew->name)
e9edcee0 5000 return -ENOMEM;
66ceeb6b 5001 knew->index = cidx;
4d02d1b6 5002 if (get_amp_nid_(val))
5e26dfd0 5003 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 5004 knew->private_value = val;
e9edcee0
TI
5005 return 0;
5006}
5007
0afe5f89
TI
5008static int add_control_with_pfx(struct alc_spec *spec, int type,
5009 const char *pfx, const char *dir,
66ceeb6b 5010 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
5011{
5012 char name[32];
5013 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 5014 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
5015}
5016
66ceeb6b
TI
5017#define add_pb_vol_ctrl(spec, type, pfx, val) \
5018 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5019#define add_pb_sw_ctrl(spec, type, pfx, val) \
5020 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5021#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5022 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5023#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5024 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 5025
e9edcee0
TI
5026#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5027#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5028#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5029#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
5030#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5031#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5032#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5033#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5034#define ALC880_PIN_CD_NID 0x1c
5035
5036/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
5037static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5038 const struct auto_pin_cfg *cfg)
e9edcee0
TI
5039{
5040 hda_nid_t nid;
5041 int assigned[4];
5042 int i, j;
5043
5044 memset(assigned, 0, sizeof(assigned));
b0af0de5 5045 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
5046
5047 /* check the pins hardwired to audio widget */
5048 for (i = 0; i < cfg->line_outs; i++) {
5049 nid = cfg->line_out_pins[i];
5050 if (alc880_is_fixed_pin(nid)) {
5051 int idx = alc880_fixed_pin_idx(nid);
5014f193 5052 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
5053 assigned[idx] = 1;
5054 }
5055 }
5056 /* left pins can be connect to any audio widget */
5057 for (i = 0; i < cfg->line_outs; i++) {
5058 nid = cfg->line_out_pins[i];
5059 if (alc880_is_fixed_pin(nid))
5060 continue;
5061 /* search for an empty channel */
5062 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
5063 if (!assigned[j]) {
5064 spec->multiout.dac_nids[i] =
5065 alc880_idx_to_dac(j);
e9edcee0
TI
5066 assigned[j] = 1;
5067 break;
5068 }
5069 }
5070 }
5071 spec->multiout.num_dacs = cfg->line_outs;
5072 return 0;
5073}
5074
bcb2f0f5
TI
5075static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg,
5076 bool can_be_master)
5077{
5078 if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5079 return "Master";
5080
5081 switch (cfg->line_out_type) {
5082 case AUTO_PIN_SPEAKER_OUT:
ebbeb3d6
DH
5083 if (cfg->line_outs == 1)
5084 return "Speaker";
5085 break;
bcb2f0f5
TI
5086 case AUTO_PIN_HP_OUT:
5087 return "Headphone";
5088 default:
5089 if (cfg->line_outs == 1)
5090 return "PCM";
5091 break;
5092 }
5093 return NULL;
5094}
5095
e9edcee0 5096/* add playback controls from the parsed DAC table */
df694daa
KY
5097static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5098 const struct auto_pin_cfg *cfg)
e9edcee0 5099{
ea734963 5100 static const char * const chname[4] = {
f12ab1e0
TI
5101 "Front", "Surround", NULL /*CLFE*/, "Side"
5102 };
bcb2f0f5 5103 const char *pfx = alc_get_line_out_pfx(cfg, false);
e9edcee0
TI
5104 hda_nid_t nid;
5105 int i, err;
5106
5107 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 5108 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
5109 continue;
5110 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
bcb2f0f5 5111 if (!pfx && i == 2) {
e9edcee0 5112 /* Center/LFE */
0afe5f89
TI
5113 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5114 "Center",
f12ab1e0
TI
5115 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5116 HDA_OUTPUT));
5117 if (err < 0)
e9edcee0 5118 return err;
0afe5f89
TI
5119 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5120 "LFE",
f12ab1e0
TI
5121 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5122 HDA_OUTPUT));
5123 if (err < 0)
e9edcee0 5124 return err;
0afe5f89
TI
5125 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5126 "Center",
f12ab1e0
TI
5127 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5128 HDA_INPUT));
5129 if (err < 0)
e9edcee0 5130 return err;
0afe5f89
TI
5131 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5132 "LFE",
f12ab1e0
TI
5133 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5134 HDA_INPUT));
5135 if (err < 0)
e9edcee0
TI
5136 return err;
5137 } else {
bcb2f0f5 5138 const char *name = pfx;
7e59e097
DH
5139 int index = i;
5140 if (!name) {
bcb2f0f5 5141 name = chname[i];
7e59e097
DH
5142 index = 0;
5143 }
bcb2f0f5 5144 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
7e59e097 5145 name, index,
f12ab1e0
TI
5146 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5147 HDA_OUTPUT));
5148 if (err < 0)
e9edcee0 5149 return err;
bcb2f0f5 5150 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
7e59e097 5151 name, index,
f12ab1e0
TI
5152 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5153 HDA_INPUT));
5154 if (err < 0)
e9edcee0
TI
5155 return err;
5156 }
5157 }
e9edcee0
TI
5158 return 0;
5159}
5160
8d88bc3d
TI
5161/* add playback controls for speaker and HP outputs */
5162static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5163 const char *pfx)
e9edcee0
TI
5164{
5165 hda_nid_t nid;
5166 int err;
5167
f12ab1e0 5168 if (!pin)
e9edcee0
TI
5169 return 0;
5170
5171 if (alc880_is_fixed_pin(pin)) {
5172 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5173 /* specify the DAC as the extra output */
f12ab1e0 5174 if (!spec->multiout.hp_nid)
e9edcee0 5175 spec->multiout.hp_nid = nid;
82bc955f
TI
5176 else
5177 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5178 /* control HP volume/switch on the output mixer amp */
5179 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5180 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5181 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5182 if (err < 0)
e9edcee0 5183 return err;
0afe5f89 5184 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5185 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5186 if (err < 0)
e9edcee0
TI
5187 return err;
5188 } else if (alc880_is_multi_pin(pin)) {
5189 /* set manual connection */
e9edcee0 5190 /* we have only a switch on HP-out PIN */
0afe5f89 5191 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5192 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5193 if (err < 0)
e9edcee0
TI
5194 return err;
5195 }
5196 return 0;
5197}
5198
5199/* create input playback/capture controls for the given pin */
f12ab1e0 5200static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5201 const char *ctlname, int ctlidx,
df694daa 5202 int idx, hda_nid_t mix_nid)
e9edcee0 5203{
df694daa 5204 int err;
e9edcee0 5205
66ceeb6b 5206 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5207 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5208 if (err < 0)
e9edcee0 5209 return err;
66ceeb6b 5210 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5211 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5212 if (err < 0)
e9edcee0
TI
5213 return err;
5214 return 0;
5215}
5216
05f5f477
TI
5217static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5218{
5219 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5220 return (pincap & AC_PINCAP_IN) != 0;
5221}
5222
e9edcee0 5223/* create playback/capture controls for input pins */
05f5f477
TI
5224static int alc_auto_create_input_ctls(struct hda_codec *codec,
5225 const struct auto_pin_cfg *cfg,
5226 hda_nid_t mixer,
5227 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5228{
05f5f477 5229 struct alc_spec *spec = codec->spec;
61b9b9b1 5230 struct hda_input_mux *imux = &spec->private_imux[0];
5322bf27
DH
5231 int i, err, idx, type_idx = 0;
5232 const char *prev_label = NULL;
e9edcee0 5233
66ceeb6b 5234 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5235 hda_nid_t pin;
10a20af7 5236 const char *label;
05f5f477 5237
66ceeb6b 5238 pin = cfg->inputs[i].pin;
05f5f477
TI
5239 if (!alc_is_input_pin(codec, pin))
5240 continue;
5241
5322bf27
DH
5242 label = hda_get_autocfg_input_label(codec, cfg, i);
5243 if (prev_label && !strcmp(label, prev_label))
66ceeb6b
TI
5244 type_idx++;
5245 else
5246 type_idx = 0;
5322bf27
DH
5247 prev_label = label;
5248
05f5f477
TI
5249 if (mixer) {
5250 idx = get_connection_index(codec, mixer, pin);
5251 if (idx >= 0) {
5252 err = new_analog_input(spec, pin,
10a20af7
TI
5253 label, type_idx,
5254 idx, mixer);
05f5f477
TI
5255 if (err < 0)
5256 return err;
5257 }
5258 }
5259
5260 if (!cap1)
5261 continue;
5262 idx = get_connection_index(codec, cap1, pin);
5263 if (idx < 0 && cap2)
5264 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5265 if (idx >= 0)
5266 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5267 }
5268 return 0;
5269}
5270
05f5f477
TI
5271static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5272 const struct auto_pin_cfg *cfg)
5273{
5274 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5275}
5276
f6c7e546
TI
5277static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5278 unsigned int pin_type)
5279{
5280 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5281 pin_type);
5282 /* unmute pin */
d260cdf6
TI
5283 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5284 AMP_OUT_UNMUTE);
f6c7e546
TI
5285}
5286
df694daa
KY
5287static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5288 hda_nid_t nid, int pin_type,
e9edcee0
TI
5289 int dac_idx)
5290{
f6c7e546 5291 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5292 /* need the manual connection? */
5293 if (alc880_is_multi_pin(nid)) {
5294 struct alc_spec *spec = codec->spec;
5295 int idx = alc880_multi_pin_idx(nid);
5296 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5297 AC_VERB_SET_CONNECT_SEL,
5298 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5299 }
5300}
5301
baba8ee9
TI
5302static int get_pin_type(int line_out_type)
5303{
5304 if (line_out_type == AUTO_PIN_HP_OUT)
5305 return PIN_HP;
5306 else
5307 return PIN_OUT;
5308}
5309
e9edcee0
TI
5310static void alc880_auto_init_multi_out(struct hda_codec *codec)
5311{
5312 struct alc_spec *spec = codec->spec;
5313 int i;
ea1fb29a 5314
e9edcee0
TI
5315 for (i = 0; i < spec->autocfg.line_outs; i++) {
5316 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5317 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5318 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5319 }
5320}
5321
8d88bc3d 5322static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5323{
5324 struct alc_spec *spec = codec->spec;
5325 hda_nid_t pin;
5326
82bc955f 5327 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5328 if (pin) /* connect to front */
5329 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5330 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5331 if (pin) /* connect to front */
5332 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5333}
5334
5335static void alc880_auto_init_analog_input(struct hda_codec *codec)
5336{
5337 struct alc_spec *spec = codec->spec;
66ceeb6b 5338 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5339 int i;
5340
66ceeb6b
TI
5341 for (i = 0; i < cfg->num_inputs; i++) {
5342 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5343 if (alc_is_input_pin(codec, nid)) {
30ea098f 5344 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
5345 if (nid != ALC880_PIN_CD_NID &&
5346 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5347 snd_hda_codec_write(codec, nid, 0,
5348 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5349 AMP_OUT_MUTE);
5350 }
5351 }
5352}
5353
7f311a46
TI
5354static void alc880_auto_init_input_src(struct hda_codec *codec)
5355{
5356 struct alc_spec *spec = codec->spec;
5357 int c;
5358
5359 for (c = 0; c < spec->num_adc_nids; c++) {
5360 unsigned int mux_idx;
5361 const struct hda_input_mux *imux;
5362 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5363 imux = &spec->input_mux[mux_idx];
5364 if (!imux->num_items && mux_idx > 0)
5365 imux = &spec->input_mux[0];
5366 if (imux)
5367 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5368 AC_VERB_SET_CONNECT_SEL,
5369 imux->items[0].index);
5370 }
5371}
5372
e9edcee0 5373/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5374/* return 1 if successful, 0 if the proper config is not found,
5375 * or a negative error code
5376 */
e9edcee0
TI
5377static int alc880_parse_auto_config(struct hda_codec *codec)
5378{
5379 struct alc_spec *spec = codec->spec;
757899ac 5380 int err;
df694daa 5381 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5382
f12ab1e0
TI
5383 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5384 alc880_ignore);
5385 if (err < 0)
e9edcee0 5386 return err;
f12ab1e0 5387 if (!spec->autocfg.line_outs)
e9edcee0 5388 return 0; /* can't find valid BIOS pin config */
df694daa 5389
f12ab1e0
TI
5390 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5391 if (err < 0)
5392 return err;
5393 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5394 if (err < 0)
5395 return err;
5396 err = alc880_auto_create_extra_out(spec,
5397 spec->autocfg.speaker_pins[0],
5398 "Speaker");
5399 if (err < 0)
5400 return err;
5401 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5402 "Headphone");
5403 if (err < 0)
5404 return err;
05f5f477 5405 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5406 if (err < 0)
e9edcee0
TI
5407 return err;
5408
5409 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5410
757899ac 5411 alc_auto_parse_digital(codec);
e9edcee0 5412
603c4019 5413 if (spec->kctls.list)
d88897ea 5414 add_mixer(spec, spec->kctls.list);
e9edcee0 5415
d88897ea 5416 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5417
a1e8d2da 5418 spec->num_mux_defs = 1;
61b9b9b1 5419 spec->input_mux = &spec->private_imux[0];
e9edcee0 5420
6227cdce 5421 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5422
e9edcee0
TI
5423 return 1;
5424}
5425
ae6b813a
TI
5426/* additional initialization for auto-configuration model */
5427static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5428{
f6c7e546 5429 struct alc_spec *spec = codec->spec;
e9edcee0 5430 alc880_auto_init_multi_out(codec);
8d88bc3d 5431 alc880_auto_init_extra_out(codec);
e9edcee0 5432 alc880_auto_init_analog_input(codec);
7f311a46 5433 alc880_auto_init_input_src(codec);
757899ac 5434 alc_auto_init_digital(codec);
f6c7e546 5435 if (spec->unsol_event)
7fb0d78f 5436 alc_inithook(codec);
e9edcee0
TI
5437}
5438
b59bdf3b
TI
5439/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5440 * one of two digital mic pins, e.g. on ALC272
5441 */
5442static void fixup_automic_adc(struct hda_codec *codec)
5443{
5444 struct alc_spec *spec = codec->spec;
5445 int i;
5446
5447 for (i = 0; i < spec->num_adc_nids; i++) {
5448 hda_nid_t cap = spec->capsrc_nids ?
5449 spec->capsrc_nids[i] : spec->adc_nids[i];
5450 int iidx, eidx;
5451
5452 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5453 if (iidx < 0)
5454 continue;
5455 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5456 if (eidx < 0)
5457 continue;
5458 spec->int_mic.mux_idx = iidx;
5459 spec->ext_mic.mux_idx = eidx;
5460 if (spec->capsrc_nids)
5461 spec->capsrc_nids += i;
5462 spec->adc_nids += i;
5463 spec->num_adc_nids = 1;
5464 return;
5465 }
5466 snd_printd(KERN_INFO "hda_codec: %s: "
5467 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5468 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5469 spec->auto_mic = 0; /* disable auto-mic to be sure */
5470}
5471
748cce43
TI
5472/* select or unmute the given capsrc route */
5473static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5474 int idx)
5475{
5476 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5477 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5478 HDA_AMP_MUTE, 0);
5479 } else {
5480 snd_hda_codec_write_cache(codec, cap, 0,
5481 AC_VERB_SET_CONNECT_SEL, idx);
5482 }
5483}
5484
840b64c0
TI
5485/* set the default connection to that pin */
5486static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5487{
5488 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5489 int i;
5490
eaa9b3a7
TI
5491 for (i = 0; i < spec->num_adc_nids; i++) {
5492 hda_nid_t cap = spec->capsrc_nids ?
5493 spec->capsrc_nids[i] : spec->adc_nids[i];
5494 int idx;
5495
5496 idx = get_connection_index(codec, cap, pin);
5497 if (idx < 0)
5498 continue;
748cce43 5499 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5500 return i; /* return the found index */
5501 }
5502 return -1; /* not found */
5503}
5504
5505/* choose the ADC/MUX containing the input pin and initialize the setup */
5506static void fixup_single_adc(struct hda_codec *codec)
5507{
5508 struct alc_spec *spec = codec->spec;
66ceeb6b 5509 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5510 int i;
5511
5512 /* search for the input pin; there must be only one */
66ceeb6b 5513 if (cfg->num_inputs != 1)
eaa9b3a7 5514 return;
66ceeb6b 5515 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5516 if (i >= 0) {
5517 /* use only this ADC */
5518 if (spec->capsrc_nids)
5519 spec->capsrc_nids += i;
5520 spec->adc_nids += i;
5521 spec->num_adc_nids = 1;
eaa9b3a7
TI
5522 }
5523}
5524
840b64c0
TI
5525/* initialize dual adcs */
5526static void fixup_dual_adc_switch(struct hda_codec *codec)
5527{
5528 struct alc_spec *spec = codec->spec;
5529 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5530 init_capsrc_for_pin(codec, spec->int_mic.pin);
5531}
5532
b59bdf3b 5533static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5534{
b59bdf3b 5535 struct alc_spec *spec = codec->spec;
a23b688f
TI
5536 static struct snd_kcontrol_new *caps[2][3] = {
5537 { alc_capture_mixer_nosrc1,
5538 alc_capture_mixer_nosrc2,
5539 alc_capture_mixer_nosrc3 },
5540 { alc_capture_mixer1,
5541 alc_capture_mixer2,
5542 alc_capture_mixer3 },
f9e336f6 5543 };
a23b688f 5544 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5545 int mux = 0;
840b64c0
TI
5546 int num_adcs = spec->num_adc_nids;
5547 if (spec->dual_adc_switch)
5548 fixup_dual_adc_switch(codec);
5549 else if (spec->auto_mic)
b59bdf3b 5550 fixup_automic_adc(codec);
eaa9b3a7
TI
5551 else if (spec->input_mux) {
5552 if (spec->input_mux->num_items > 1)
5553 mux = 1;
5554 else if (spec->input_mux->num_items == 1)
5555 fixup_single_adc(codec);
5556 }
840b64c0
TI
5557 if (spec->dual_adc_switch)
5558 num_adcs = 1;
5559 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5560 }
f9e336f6
TI
5561}
5562
6694635d
TI
5563/* fill adc_nids (and capsrc_nids) containing all active input pins */
5564static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5565 int num_nids)
5566{
5567 struct alc_spec *spec = codec->spec;
66ceeb6b 5568 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5569 int n;
5570 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5571
5572 for (n = 0; n < num_nids; n++) {
5573 hda_nid_t adc, cap;
5574 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5575 int nconns, i, j;
5576
5577 adc = nids[n];
5578 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5579 continue;
5580 cap = adc;
5581 nconns = snd_hda_get_connections(codec, cap, conn,
5582 ARRAY_SIZE(conn));
5583 if (nconns == 1) {
5584 cap = conn[0];
5585 nconns = snd_hda_get_connections(codec, cap, conn,
5586 ARRAY_SIZE(conn));
5587 }
5588 if (nconns <= 0)
5589 continue;
5590 if (!fallback_adc) {
5591 fallback_adc = adc;
5592 fallback_cap = cap;
5593 }
66ceeb6b
TI
5594 for (i = 0; i < cfg->num_inputs; i++) {
5595 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5596 for (j = 0; j < nconns; j++) {
5597 if (conn[j] == nid)
5598 break;
5599 }
5600 if (j >= nconns)
5601 break;
5602 }
66ceeb6b 5603 if (i >= cfg->num_inputs) {
6694635d
TI
5604 int num_adcs = spec->num_adc_nids;
5605 spec->private_adc_nids[num_adcs] = adc;
5606 spec->private_capsrc_nids[num_adcs] = cap;
5607 spec->num_adc_nids++;
5608 spec->adc_nids = spec->private_adc_nids;
5609 if (adc != cap)
5610 spec->capsrc_nids = spec->private_capsrc_nids;
5611 }
5612 }
5613 if (!spec->num_adc_nids) {
5614 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5615 " using fallback 0x%x\n",
5616 codec->chip_name, fallback_adc);
6694635d
TI
5617 spec->private_adc_nids[0] = fallback_adc;
5618 spec->adc_nids = spec->private_adc_nids;
5619 if (fallback_adc != fallback_cap) {
5620 spec->private_capsrc_nids[0] = fallback_cap;
5621 spec->capsrc_nids = spec->private_adc_nids;
5622 }
5623 }
5624}
5625
67d634c0 5626#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5627#define set_beep_amp(spec, nid, idx, dir) \
5628 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25
TI
5629
5630static struct snd_pci_quirk beep_white_list[] = {
5631 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5632 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
e096c8e6 5633 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5634 {}
5635};
5636
5637static inline int has_cdefine_beep(struct hda_codec *codec)
5638{
5639 struct alc_spec *spec = codec->spec;
5640 const struct snd_pci_quirk *q;
5641 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5642 if (q)
5643 return q->value;
5644 return spec->cdefine.enable_pcbeep;
5645}
67d634c0
TI
5646#else
5647#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5648#define has_cdefine_beep(codec) 0
67d634c0 5649#endif
45bdd1c1
TI
5650
5651/*
5652 * OK, here we have finally the patch for ALC880
5653 */
5654
1da177e4
LT
5655static int patch_alc880(struct hda_codec *codec)
5656{
5657 struct alc_spec *spec;
5658 int board_config;
df694daa 5659 int err;
1da177e4 5660
e560d8d8 5661 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5662 if (spec == NULL)
5663 return -ENOMEM;
5664
5665 codec->spec = spec;
5666
f5fcc13c
TI
5667 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5668 alc880_models,
5669 alc880_cfg_tbl);
5670 if (board_config < 0) {
9a11f1aa
TI
5671 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5672 codec->chip_name);
e9edcee0 5673 board_config = ALC880_AUTO;
1da177e4 5674 }
1da177e4 5675
e9edcee0
TI
5676 if (board_config == ALC880_AUTO) {
5677 /* automatic parse from the BIOS config */
5678 err = alc880_parse_auto_config(codec);
5679 if (err < 0) {
5680 alc_free(codec);
5681 return err;
f12ab1e0 5682 } else if (!err) {
9c7f852e
TI
5683 printk(KERN_INFO
5684 "hda_codec: Cannot set up configuration "
5685 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5686 board_config = ALC880_3ST;
5687 }
1da177e4
LT
5688 }
5689
680cd536
KK
5690 err = snd_hda_attach_beep_device(codec, 0x1);
5691 if (err < 0) {
5692 alc_free(codec);
5693 return err;
5694 }
5695
df694daa 5696 if (board_config != ALC880_AUTO)
e9c364c0 5697 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5698
1da177e4
LT
5699 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5700 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5701 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5702
1da177e4
LT
5703 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5704 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5705
f12ab1e0 5706 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5707 /* check whether NID 0x07 is valid */
54d17403 5708 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5709 /* get type */
a22d543a 5710 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5711 if (wcap != AC_WID_AUD_IN) {
5712 spec->adc_nids = alc880_adc_nids_alt;
5713 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5714 } else {
5715 spec->adc_nids = alc880_adc_nids;
5716 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5717 }
5718 }
b59bdf3b 5719 set_capture_mixer(codec);
45bdd1c1 5720 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5721
2134ea4f
TI
5722 spec->vmaster_nid = 0x0c;
5723
1da177e4 5724 codec->patch_ops = alc_patch_ops;
e9edcee0 5725 if (board_config == ALC880_AUTO)
ae6b813a 5726 spec->init_hook = alc880_auto_init;
cb53c626
TI
5727#ifdef CONFIG_SND_HDA_POWER_SAVE
5728 if (!spec->loopback.amplist)
5729 spec->loopback.amplist = alc880_loopbacks;
5730#endif
1da177e4
LT
5731
5732 return 0;
5733}
5734
e9edcee0 5735
1da177e4
LT
5736/*
5737 * ALC260 support
5738 */
5739
e9edcee0
TI
5740static hda_nid_t alc260_dac_nids[1] = {
5741 /* front */
5742 0x02,
5743};
5744
5745static hda_nid_t alc260_adc_nids[1] = {
5746 /* ADC0 */
5747 0x04,
5748};
5749
df694daa 5750static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5751 /* ADC1 */
5752 0x05,
5753};
5754
d57fdac0
JW
5755/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5756 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5757 */
5758static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5759 /* ADC0, ADC1 */
5760 0x04, 0x05
5761};
5762
e9edcee0
TI
5763#define ALC260_DIGOUT_NID 0x03
5764#define ALC260_DIGIN_NID 0x06
5765
5766static struct hda_input_mux alc260_capture_source = {
5767 .num_items = 4,
5768 .items = {
5769 { "Mic", 0x0 },
5770 { "Front Mic", 0x1 },
5771 { "Line", 0x2 },
5772 { "CD", 0x4 },
5773 },
5774};
5775
17e7aec6 5776/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5777 * headphone jack and the internal CD lines since these are the only pins at
5778 * which audio can appear. For flexibility, also allow the option of
5779 * recording the mixer output on the second ADC (ADC0 doesn't have a
5780 * connection to the mixer output).
a9430dd8 5781 */
a1e8d2da
JW
5782static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5783 {
5784 .num_items = 3,
5785 .items = {
5786 { "Mic/Line", 0x0 },
5787 { "CD", 0x4 },
5788 { "Headphone", 0x2 },
5789 },
a9430dd8 5790 },
a1e8d2da
JW
5791 {
5792 .num_items = 4,
5793 .items = {
5794 { "Mic/Line", 0x0 },
5795 { "CD", 0x4 },
5796 { "Headphone", 0x2 },
5797 { "Mixer", 0x5 },
5798 },
5799 },
5800
a9430dd8
JW
5801};
5802
a1e8d2da
JW
5803/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5804 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5805 */
a1e8d2da
JW
5806static struct hda_input_mux alc260_acer_capture_sources[2] = {
5807 {
5808 .num_items = 4,
5809 .items = {
5810 { "Mic", 0x0 },
5811 { "Line", 0x2 },
5812 { "CD", 0x4 },
5813 { "Headphone", 0x5 },
5814 },
5815 },
5816 {
5817 .num_items = 5,
5818 .items = {
5819 { "Mic", 0x0 },
5820 { "Line", 0x2 },
5821 { "CD", 0x4 },
5822 { "Headphone", 0x6 },
5823 { "Mixer", 0x5 },
5824 },
0bfc90e9
JW
5825 },
5826};
cc959489
MS
5827
5828/* Maxdata Favorit 100XS */
5829static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5830 {
5831 .num_items = 2,
5832 .items = {
5833 { "Line/Mic", 0x0 },
5834 { "CD", 0x4 },
5835 },
5836 },
5837 {
5838 .num_items = 3,
5839 .items = {
5840 { "Line/Mic", 0x0 },
5841 { "CD", 0x4 },
5842 { "Mixer", 0x5 },
5843 },
5844 },
5845};
5846
1da177e4
LT
5847/*
5848 * This is just place-holder, so there's something for alc_build_pcms to look
5849 * at when it calculates the maximum number of channels. ALC260 has no mixer
5850 * element which allows changing the channel mode, so the verb list is
5851 * never used.
5852 */
d2a6d7dc 5853static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5854 { 2, NULL },
5855};
5856
df694daa
KY
5857
5858/* Mixer combinations
5859 *
5860 * basic: base_output + input + pc_beep + capture
5861 * HP: base_output + input + capture_alt
5862 * HP_3013: hp_3013 + input + capture
5863 * fujitsu: fujitsu + capture
0bfc90e9 5864 * acer: acer + capture
df694daa
KY
5865 */
5866
5867static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5868 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5869 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5870 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5871 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5872 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5873 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5874 { } /* end */
f12ab1e0 5875};
1da177e4 5876
df694daa 5877static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5878 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5879 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5880 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5881 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5882 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5883 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5884 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5885 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5886 { } /* end */
5887};
5888
bec15c3a
TI
5889/* update HP, line and mono out pins according to the master switch */
5890static void alc260_hp_master_update(struct hda_codec *codec,
5891 hda_nid_t hp, hda_nid_t line,
5892 hda_nid_t mono)
5893{
5894 struct alc_spec *spec = codec->spec;
5895 unsigned int val = spec->master_sw ? PIN_HP : 0;
5896 /* change HP and line-out pins */
30cde0aa 5897 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5898 val);
30cde0aa 5899 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5900 val);
5901 /* mono (speaker) depending on the HP jack sense */
5902 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5903 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5904 val);
5905}
5906
5907static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5908 struct snd_ctl_elem_value *ucontrol)
5909{
5910 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5911 struct alc_spec *spec = codec->spec;
5912 *ucontrol->value.integer.value = spec->master_sw;
5913 return 0;
5914}
5915
5916static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5917 struct snd_ctl_elem_value *ucontrol)
5918{
5919 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5920 struct alc_spec *spec = codec->spec;
5921 int val = !!*ucontrol->value.integer.value;
5922 hda_nid_t hp, line, mono;
5923
5924 if (val == spec->master_sw)
5925 return 0;
5926 spec->master_sw = val;
5927 hp = (kcontrol->private_value >> 16) & 0xff;
5928 line = (kcontrol->private_value >> 8) & 0xff;
5929 mono = kcontrol->private_value & 0xff;
5930 alc260_hp_master_update(codec, hp, line, mono);
5931 return 1;
5932}
5933
5934static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5935 {
5936 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5937 .name = "Master Playback Switch",
5b0cb1d8 5938 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5939 .info = snd_ctl_boolean_mono_info,
5940 .get = alc260_hp_master_sw_get,
5941 .put = alc260_hp_master_sw_put,
5942 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5943 },
5944 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5945 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5946 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5947 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5948 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5949 HDA_OUTPUT),
5950 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5951 { } /* end */
5952};
5953
5954static struct hda_verb alc260_hp_unsol_verbs[] = {
5955 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5956 {},
5957};
5958
5959static void alc260_hp_automute(struct hda_codec *codec)
5960{
5961 struct alc_spec *spec = codec->spec;
bec15c3a 5962
864f92be 5963 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5964 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5965}
5966
5967static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5968{
5969 if ((res >> 26) == ALC880_HP_EVENT)
5970 alc260_hp_automute(codec);
5971}
5972
df694daa 5973static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5974 {
5975 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5976 .name = "Master Playback Switch",
5b0cb1d8 5977 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5978 .info = snd_ctl_boolean_mono_info,
5979 .get = alc260_hp_master_sw_get,
5980 .put = alc260_hp_master_sw_put,
30cde0aa 5981 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5982 },
df694daa
KY
5983 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5984 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5985 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5986 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5987 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5988 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
5989 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5990 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
5991 { } /* end */
5992};
5993
3f878308
KY
5994static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5995 .ops = &snd_hda_bind_vol,
5996 .values = {
5997 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5998 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5999 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6000 0
6001 },
6002};
6003
6004static struct hda_bind_ctls alc260_dc7600_bind_switch = {
6005 .ops = &snd_hda_bind_sw,
6006 .values = {
6007 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6008 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6009 0
6010 },
6011};
6012
6013static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6014 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6015 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6016 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6017 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6018 { } /* end */
6019};
6020
bec15c3a
TI
6021static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6022 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6023 {},
6024};
6025
6026static void alc260_hp_3013_automute(struct hda_codec *codec)
6027{
6028 struct alc_spec *spec = codec->spec;
bec15c3a 6029
864f92be 6030 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 6031 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
6032}
6033
6034static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
6035 unsigned int res)
6036{
6037 if ((res >> 26) == ALC880_HP_EVENT)
6038 alc260_hp_3013_automute(codec);
6039}
6040
3f878308
KY
6041static void alc260_hp_3012_automute(struct hda_codec *codec)
6042{
864f92be 6043 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 6044
3f878308
KY
6045 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6046 bits);
6047 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6048 bits);
6049 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6050 bits);
6051}
6052
6053static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
6054 unsigned int res)
6055{
6056 if ((res >> 26) == ALC880_HP_EVENT)
6057 alc260_hp_3012_automute(codec);
6058}
6059
6060/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
6061 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6062 */
c8b6bf9b 6063static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 6064 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6065 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 6066 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
6067 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6068 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6069 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6070 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 6071 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
6072 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6073 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
6074 { } /* end */
6075};
6076
a1e8d2da
JW
6077/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6078 * versions of the ALC260 don't act on requests to enable mic bias from NID
6079 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6080 * datasheet doesn't mention this restriction. At this stage it's not clear
6081 * whether this behaviour is intentional or is a hardware bug in chip
6082 * revisions available in early 2006. Therefore for now allow the
6083 * "Headphone Jack Mode" control to span all choices, but if it turns out
6084 * that the lack of mic bias for this NID is intentional we could change the
6085 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6086 *
6087 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6088 * don't appear to make the mic bias available from the "line" jack, even
6089 * though the NID used for this jack (0x14) can supply it. The theory is
6090 * that perhaps Acer have included blocking capacitors between the ALC260
6091 * and the output jack. If this turns out to be the case for all such
6092 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6093 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
6094 *
6095 * The C20x Tablet series have a mono internal speaker which is controlled
6096 * via the chip's Mono sum widget and pin complex, so include the necessary
6097 * controls for such models. On models without a "mono speaker" the control
6098 * won't do anything.
a1e8d2da 6099 */
0bfc90e9
JW
6100static struct snd_kcontrol_new alc260_acer_mixer[] = {
6101 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6102 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 6103 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 6104 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 6105 HDA_OUTPUT),
31bffaa9 6106 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 6107 HDA_INPUT),
0bfc90e9
JW
6108 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6109 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6110 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6111 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6112 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6113 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6114 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6115 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
6116 { } /* end */
6117};
6118
cc959489
MS
6119/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6120 */
6121static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6122 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6123 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6124 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6125 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6126 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6127 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6128 { } /* end */
6129};
6130
bc9f98a9
KY
6131/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6132 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6133 */
6134static struct snd_kcontrol_new alc260_will_mixer[] = {
6135 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6136 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6137 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6138 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6139 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6140 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6141 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6142 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6143 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6144 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
6145 { } /* end */
6146};
6147
6148/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6149 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6150 */
6151static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6152 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6153 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6154 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6155 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6156 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6157 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6158 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6159 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6160 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6161 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6162 { } /* end */
6163};
6164
df694daa
KY
6165/*
6166 * initialization verbs
6167 */
1da177e4
LT
6168static struct hda_verb alc260_init_verbs[] = {
6169 /* Line In pin widget for input */
05acb863 6170 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6171 /* CD pin widget for input */
05acb863 6172 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6173 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6174 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6175 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6176 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6177 /* LINE-2 is used for line-out in rear */
05acb863 6178 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6179 /* select line-out */
fd56f2db 6180 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6181 /* LINE-OUT pin */
05acb863 6182 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6183 /* enable HP */
05acb863 6184 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6185 /* enable Mono */
05acb863
TI
6186 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6187 /* mute capture amp left and right */
16ded525 6188 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6189 /* set connection select to line in (default select for this ADC) */
6190 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6191 /* mute capture amp left and right */
6192 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6193 /* set connection select to line in (default select for this ADC) */
6194 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6195 /* set vol=0 Line-Out mixer amp left and right */
6196 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6197 /* unmute pin widget amp left and right (no gain on this amp) */
6198 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6199 /* set vol=0 HP mixer amp left and right */
6200 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6201 /* unmute pin widget amp left and right (no gain on this amp) */
6202 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6203 /* set vol=0 Mono mixer amp left and right */
6204 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6205 /* unmute pin widget amp left and right (no gain on this amp) */
6206 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6207 /* unmute LINE-2 out pin */
6208 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6209 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6210 * Line In 2 = 0x03
6211 */
cb53c626
TI
6212 /* mute analog inputs */
6213 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6214 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6215 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6216 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6217 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6218 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6219 /* mute Front out path */
6220 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6221 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6222 /* mute Headphone out path */
6223 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6224 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6225 /* mute Mono out path */
6226 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6227 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6228 { }
6229};
6230
474167d6 6231#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
6232static struct hda_verb alc260_hp_init_verbs[] = {
6233 /* Headphone and output */
6234 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6235 /* mono output */
6236 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6237 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6238 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6239 /* Mic2 (front panel) pin widget for input and vref at 80% */
6240 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6241 /* Line In pin widget for input */
6242 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6243 /* Line-2 pin widget for output */
6244 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6245 /* CD pin widget for input */
6246 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6247 /* unmute amp left and right */
6248 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6249 /* set connection select to line in (default select for this ADC) */
6250 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6251 /* unmute Line-Out mixer amp left and right (volume = 0) */
6252 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6253 /* mute pin widget amp left and right (no gain on this amp) */
6254 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6255 /* unmute HP mixer amp left and right (volume = 0) */
6256 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6257 /* mute pin widget amp left and right (no gain on this amp) */
6258 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6259 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6260 * Line In 2 = 0x03
6261 */
cb53c626
TI
6262 /* mute analog inputs */
6263 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6264 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6265 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6266 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6267 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6268 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6269 /* Unmute Front out path */
6270 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6271 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6272 /* Unmute Headphone out path */
6273 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6274 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6275 /* Unmute Mono out path */
6276 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6277 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6278 { }
6279};
474167d6 6280#endif
df694daa
KY
6281
6282static struct hda_verb alc260_hp_3013_init_verbs[] = {
6283 /* Line out and output */
6284 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6285 /* mono output */
6286 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6287 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6288 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6289 /* Mic2 (front panel) pin widget for input and vref at 80% */
6290 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6291 /* Line In pin widget for input */
6292 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6293 /* Headphone pin widget for output */
6294 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6295 /* CD pin widget for input */
6296 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6297 /* unmute amp left and right */
6298 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6299 /* set connection select to line in (default select for this ADC) */
6300 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6301 /* unmute Line-Out mixer amp left and right (volume = 0) */
6302 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6303 /* mute pin widget amp left and right (no gain on this amp) */
6304 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6305 /* unmute HP mixer amp left and right (volume = 0) */
6306 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6307 /* mute pin widget amp left and right (no gain on this amp) */
6308 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6309 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6310 * Line In 2 = 0x03
6311 */
cb53c626
TI
6312 /* mute analog inputs */
6313 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6314 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6315 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6316 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6317 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6318 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6319 /* Unmute Front out path */
6320 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6321 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6322 /* Unmute Headphone out path */
6323 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6324 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6325 /* Unmute Mono out path */
6326 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6327 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6328 { }
6329};
6330
a9430dd8 6331/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6332 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6333 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
6334 */
6335static struct hda_verb alc260_fujitsu_init_verbs[] = {
6336 /* Disable all GPIOs */
6337 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6338 /* Internal speaker is connected to headphone pin */
6339 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6340 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6341 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6342 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6343 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6344 /* Ensure all other unused pins are disabled and muted. */
6345 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6346 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6347 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6348 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6349 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6350 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6351 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6352 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6353
6354 /* Disable digital (SPDIF) pins */
6355 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6356 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6357
ea1fb29a 6358 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6359 * when acting as an output.
6360 */
6361 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6362
f7ace40d 6363 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6364 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6365 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6366 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6367 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6368 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6369 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6370 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6371 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6372 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6373
f7ace40d
JW
6374 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6375 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6376 /* Unmute Line1 pin widget output buffer since it starts as an output.
6377 * If the pin mode is changed by the user the pin mode control will
6378 * take care of enabling the pin's input/output buffers as needed.
6379 * Therefore there's no need to enable the input buffer at this
6380 * stage.
cdcd9268 6381 */
f7ace40d 6382 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6383 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6384 * mixer ctrl)
6385 */
f7ace40d
JW
6386 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6387
6388 /* Mute capture amp left and right */
6389 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6390 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6391 * in (on mic1 pin)
6392 */
6393 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6394
6395 /* Do the same for the second ADC: mute capture input amp and
6396 * set ADC connection to line in (on mic1 pin)
6397 */
6398 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6399 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6400
6401 /* Mute all inputs to mixer widget (even unconnected ones) */
6402 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6403 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6404 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6405 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6406 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6407 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6408 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6409 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6410
6411 { }
a9430dd8
JW
6412};
6413
0bfc90e9
JW
6414/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6415 * similar laptops (adapted from Fujitsu init verbs).
6416 */
6417static struct hda_verb alc260_acer_init_verbs[] = {
6418 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6419 * the headphone jack. Turn this on and rely on the standard mute
6420 * methods whenever the user wants to turn these outputs off.
6421 */
6422 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6423 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6424 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6425 /* Internal speaker/Headphone jack is connected to Line-out pin */
6426 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6427 /* Internal microphone/Mic jack is connected to Mic1 pin */
6428 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6429 /* Line In jack is connected to Line1 pin */
6430 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6431 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6432 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6433 /* Ensure all other unused pins are disabled and muted. */
6434 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6435 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6436 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6437 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6438 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6439 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6440 /* Disable digital (SPDIF) pins */
6441 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6442 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6443
ea1fb29a 6444 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6445 * bus when acting as outputs.
6446 */
6447 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6448 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6449
6450 /* Start with output sum widgets muted and their output gains at min */
6451 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6452 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6453 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6454 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6455 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6456 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6457 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6458 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6459 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6460
f12ab1e0
TI
6461 /* Unmute Line-out pin widget amp left and right
6462 * (no equiv mixer ctrl)
6463 */
0bfc90e9 6464 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6465 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6466 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6467 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6468 * inputs. If the pin mode is changed by the user the pin mode control
6469 * will take care of enabling the pin's input/output buffers as needed.
6470 * Therefore there's no need to enable the input buffer at this
6471 * stage.
6472 */
6473 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6474 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6475
6476 /* Mute capture amp left and right */
6477 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6478 /* Set ADC connection select to match default mixer setting - mic
6479 * (on mic1 pin)
6480 */
6481 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6482
6483 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6484 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6485 */
6486 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6487 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6488
6489 /* Mute all inputs to mixer widget (even unconnected ones) */
6490 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6491 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6492 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6493 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6494 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6495 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6496 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6497 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6498
6499 { }
6500};
6501
cc959489
MS
6502/* Initialisation sequence for Maxdata Favorit 100XS
6503 * (adapted from Acer init verbs).
6504 */
6505static struct hda_verb alc260_favorit100_init_verbs[] = {
6506 /* GPIO 0 enables the output jack.
6507 * Turn this on and rely on the standard mute
6508 * methods whenever the user wants to turn these outputs off.
6509 */
6510 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6511 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6512 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6513 /* Line/Mic input jack is connected to Mic1 pin */
6514 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6515 /* Ensure all other unused pins are disabled and muted. */
6516 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6517 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6518 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6519 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6520 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6521 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6522 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6523 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6524 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6525 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6526 /* Disable digital (SPDIF) pins */
6527 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6528 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6529
6530 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6531 * bus when acting as outputs.
6532 */
6533 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6534 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6535
6536 /* Start with output sum widgets muted and their output gains at min */
6537 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6538 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6539 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6540 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6541 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6542 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6543 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6544 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6545 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6546
6547 /* Unmute Line-out pin widget amp left and right
6548 * (no equiv mixer ctrl)
6549 */
6550 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6551 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6552 * inputs. If the pin mode is changed by the user the pin mode control
6553 * will take care of enabling the pin's input/output buffers as needed.
6554 * Therefore there's no need to enable the input buffer at this
6555 * stage.
6556 */
6557 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6558
6559 /* Mute capture amp left and right */
6560 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6561 /* Set ADC connection select to match default mixer setting - mic
6562 * (on mic1 pin)
6563 */
6564 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6565
6566 /* Do similar with the second ADC: mute capture input amp and
6567 * set ADC connection to mic to match ALSA's default state.
6568 */
6569 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6570 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6571
6572 /* Mute all inputs to mixer widget (even unconnected ones) */
6573 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6574 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6575 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6576 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6577 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6578 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6579 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6580 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6581
6582 { }
6583};
6584
bc9f98a9
KY
6585static struct hda_verb alc260_will_verbs[] = {
6586 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6587 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6588 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6589 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6590 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6591 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6592 {}
6593};
6594
6595static struct hda_verb alc260_replacer_672v_verbs[] = {
6596 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6597 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6598 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6599
6600 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6601 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6602 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6603
6604 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6605 {}
6606};
6607
6608/* toggle speaker-output according to the hp-jack state */
6609static void alc260_replacer_672v_automute(struct hda_codec *codec)
6610{
6611 unsigned int present;
6612
6613 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6614 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6615 if (present) {
82beb8fd
TI
6616 snd_hda_codec_write_cache(codec, 0x01, 0,
6617 AC_VERB_SET_GPIO_DATA, 1);
6618 snd_hda_codec_write_cache(codec, 0x0f, 0,
6619 AC_VERB_SET_PIN_WIDGET_CONTROL,
6620 PIN_HP);
bc9f98a9 6621 } else {
82beb8fd
TI
6622 snd_hda_codec_write_cache(codec, 0x01, 0,
6623 AC_VERB_SET_GPIO_DATA, 0);
6624 snd_hda_codec_write_cache(codec, 0x0f, 0,
6625 AC_VERB_SET_PIN_WIDGET_CONTROL,
6626 PIN_OUT);
bc9f98a9
KY
6627 }
6628}
6629
6630static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6631 unsigned int res)
6632{
6633 if ((res >> 26) == ALC880_HP_EVENT)
6634 alc260_replacer_672v_automute(codec);
6635}
6636
3f878308
KY
6637static struct hda_verb alc260_hp_dc7600_verbs[] = {
6638 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6639 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6640 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6641 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6642 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6643 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6644 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6645 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6646 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6647 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6648 {}
6649};
6650
7cf51e48
JW
6651/* Test configuration for debugging, modelled after the ALC880 test
6652 * configuration.
6653 */
6654#ifdef CONFIG_SND_DEBUG
6655static hda_nid_t alc260_test_dac_nids[1] = {
6656 0x02,
6657};
6658static hda_nid_t alc260_test_adc_nids[2] = {
6659 0x04, 0x05,
6660};
a1e8d2da 6661/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6662 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6663 * is NID 0x04.
17e7aec6 6664 */
a1e8d2da
JW
6665static struct hda_input_mux alc260_test_capture_sources[2] = {
6666 {
6667 .num_items = 7,
6668 .items = {
6669 { "MIC1 pin", 0x0 },
6670 { "MIC2 pin", 0x1 },
6671 { "LINE1 pin", 0x2 },
6672 { "LINE2 pin", 0x3 },
6673 { "CD pin", 0x4 },
6674 { "LINE-OUT pin", 0x5 },
6675 { "HP-OUT pin", 0x6 },
6676 },
6677 },
6678 {
6679 .num_items = 8,
6680 .items = {
6681 { "MIC1 pin", 0x0 },
6682 { "MIC2 pin", 0x1 },
6683 { "LINE1 pin", 0x2 },
6684 { "LINE2 pin", 0x3 },
6685 { "CD pin", 0x4 },
6686 { "Mixer", 0x5 },
6687 { "LINE-OUT pin", 0x6 },
6688 { "HP-OUT pin", 0x7 },
6689 },
7cf51e48
JW
6690 },
6691};
6692static struct snd_kcontrol_new alc260_test_mixer[] = {
6693 /* Output driver widgets */
6694 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6695 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6696 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6697 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6698 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6699 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6700
a1e8d2da
JW
6701 /* Modes for retasking pin widgets
6702 * Note: the ALC260 doesn't seem to act on requests to enable mic
6703 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6704 * mention this restriction. At this stage it's not clear whether
6705 * this behaviour is intentional or is a hardware bug in chip
6706 * revisions available at least up until early 2006. Therefore for
6707 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6708 * choices, but if it turns out that the lack of mic bias for these
6709 * NIDs is intentional we could change their modes from
6710 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6711 */
7cf51e48
JW
6712 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6713 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6714 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6715 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6716 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6717 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6718
6719 /* Loopback mixer controls */
6720 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6721 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6722 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6723 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6724 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6725 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6726 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6727 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6728 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6729 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6730 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6731 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6732 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6733 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6734
6735 /* Controls for GPIO pins, assuming they are configured as outputs */
6736 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6737 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6738 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6739 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6740
92621f13
JW
6741 /* Switches to allow the digital IO pins to be enabled. The datasheet
6742 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6743 * make this output available should provide clarification.
92621f13
JW
6744 */
6745 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6746 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6747
f8225f6d
JW
6748 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6749 * this output to turn on an external amplifier.
6750 */
6751 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6752 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6753
7cf51e48
JW
6754 { } /* end */
6755};
6756static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6757 /* Enable all GPIOs as outputs with an initial value of 0 */
6758 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6759 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6760 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6761
7cf51e48
JW
6762 /* Enable retasking pins as output, initially without power amp */
6763 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6764 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6765 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6766 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6767 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6768 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6769
92621f13
JW
6770 /* Disable digital (SPDIF) pins initially, but users can enable
6771 * them via a mixer switch. In the case of SPDIF-out, this initverb
6772 * payload also sets the generation to 0, output to be in "consumer"
6773 * PCM format, copyright asserted, no pre-emphasis and no validity
6774 * control.
6775 */
7cf51e48
JW
6776 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6777 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6778
ea1fb29a 6779 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6780 * OUT1 sum bus when acting as an output.
6781 */
6782 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6783 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6784 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6785 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6786
6787 /* Start with output sum widgets muted and their output gains at min */
6788 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6789 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6790 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6791 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6792 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6793 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6794 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6795 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6796 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6797
cdcd9268
JW
6798 /* Unmute retasking pin widget output buffers since the default
6799 * state appears to be output. As the pin mode is changed by the
6800 * user the pin mode control will take care of enabling the pin's
6801 * input/output buffers as needed.
6802 */
7cf51e48
JW
6803 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6804 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6805 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6806 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6807 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6808 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6809 /* Also unmute the mono-out pin widget */
6810 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6811
7cf51e48
JW
6812 /* Mute capture amp left and right */
6813 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6814 /* Set ADC connection select to match default mixer setting (mic1
6815 * pin)
7cf51e48
JW
6816 */
6817 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6818
6819 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6820 * set ADC connection to mic1 pin
7cf51e48
JW
6821 */
6822 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6823 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6824
6825 /* Mute all inputs to mixer widget (even unconnected ones) */
6826 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6827 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6828 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6829 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6830 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6831 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6832 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6833 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6834
6835 { }
6836};
6837#endif
6838
6330079f
TI
6839#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6840#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6841
a3bcba38
TI
6842#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6843#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6844
df694daa
KY
6845/*
6846 * for BIOS auto-configuration
6847 */
16ded525 6848
df694daa 6849static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6850 const char *pfx, int *vol_bits)
df694daa
KY
6851{
6852 hda_nid_t nid_vol;
6853 unsigned long vol_val, sw_val;
df694daa
KY
6854 int err;
6855
6856 if (nid >= 0x0f && nid < 0x11) {
6857 nid_vol = nid - 0x7;
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 if (nid == 0x11) {
6861 nid_vol = nid - 0x7;
6862 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6863 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6864 } else if (nid >= 0x12 && nid <= 0x15) {
6865 nid_vol = 0x08;
6866 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6867 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6868 } else
6869 return 0; /* N/A */
ea1fb29a 6870
863b4518
TI
6871 if (!(*vol_bits & (1 << nid_vol))) {
6872 /* first control for the volume widget */
0afe5f89 6873 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6874 if (err < 0)
6875 return err;
6876 *vol_bits |= (1 << nid_vol);
6877 }
0afe5f89 6878 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6879 if (err < 0)
df694daa
KY
6880 return err;
6881 return 1;
6882}
6883
6884/* add playback controls from the parsed DAC table */
6885static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6886 const struct auto_pin_cfg *cfg)
6887{
6888 hda_nid_t nid;
6889 int err;
863b4518 6890 int vols = 0;
df694daa
KY
6891
6892 spec->multiout.num_dacs = 1;
6893 spec->multiout.dac_nids = spec->private_dac_nids;
6894 spec->multiout.dac_nids[0] = 0x02;
6895
6896 nid = cfg->line_out_pins[0];
6897 if (nid) {
23112d6d
TI
6898 const char *pfx;
6899 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6900 pfx = "Master";
6901 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6902 pfx = "Speaker";
6903 else
6904 pfx = "Front";
6905 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6906 if (err < 0)
6907 return err;
6908 }
6909
82bc955f 6910 nid = cfg->speaker_pins[0];
df694daa 6911 if (nid) {
863b4518 6912 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6913 if (err < 0)
6914 return err;
6915 }
6916
eb06ed8f 6917 nid = cfg->hp_pins[0];
df694daa 6918 if (nid) {
863b4518
TI
6919 err = alc260_add_playback_controls(spec, nid, "Headphone",
6920 &vols);
df694daa
KY
6921 if (err < 0)
6922 return err;
6923 }
f12ab1e0 6924 return 0;
df694daa
KY
6925}
6926
6927/* create playback/capture controls for input pins */
05f5f477 6928static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6929 const struct auto_pin_cfg *cfg)
6930{
05f5f477 6931 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6932}
6933
6934static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6935 hda_nid_t nid, int pin_type,
6936 int sel_idx)
6937{
f6c7e546 6938 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6939 /* need the manual connection? */
6940 if (nid >= 0x12) {
6941 int idx = nid - 0x12;
6942 snd_hda_codec_write(codec, idx + 0x0b, 0,
6943 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6944 }
6945}
6946
6947static void alc260_auto_init_multi_out(struct hda_codec *codec)
6948{
6949 struct alc_spec *spec = codec->spec;
6950 hda_nid_t nid;
6951
f12ab1e0 6952 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6953 if (nid) {
6954 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6955 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6956 }
ea1fb29a 6957
82bc955f 6958 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6959 if (nid)
6960 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6961
eb06ed8f 6962 nid = spec->autocfg.hp_pins[0];
df694daa 6963 if (nid)
baba8ee9 6964 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6965}
df694daa
KY
6966
6967#define ALC260_PIN_CD_NID 0x16
6968static void alc260_auto_init_analog_input(struct hda_codec *codec)
6969{
6970 struct alc_spec *spec = codec->spec;
66ceeb6b 6971 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
6972 int i;
6973
66ceeb6b
TI
6974 for (i = 0; i < cfg->num_inputs; i++) {
6975 hda_nid_t nid = cfg->inputs[i].pin;
df694daa 6976 if (nid >= 0x12) {
30ea098f 6977 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
6978 if (nid != ALC260_PIN_CD_NID &&
6979 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6980 snd_hda_codec_write(codec, nid, 0,
6981 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6982 AMP_OUT_MUTE);
6983 }
6984 }
6985}
6986
7f311a46
TI
6987#define alc260_auto_init_input_src alc880_auto_init_input_src
6988
df694daa
KY
6989/*
6990 * generic initialization of ADC, input mixers and output mixers
6991 */
6992static struct hda_verb alc260_volume_init_verbs[] = {
6993 /*
6994 * Unmute ADC0-1 and set the default input to mic-in
6995 */
6996 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6997 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6998 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6999 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 7000
df694daa
KY
7001 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7002 * mixer widget
f12ab1e0
TI
7003 * Note: PASD motherboards uses the Line In 2 as the input for
7004 * front panel mic (mic 2)
df694daa
KY
7005 */
7006 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
7007 /* mute analog inputs */
7008 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7009 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7010 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7011 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7012 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
7013
7014 /*
7015 * Set up output mixers (0x08 - 0x0a)
7016 */
7017 /* set vol=0 to output mixers */
7018 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7019 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7020 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7021 /* set up input amps for analog loopback */
7022 /* Amp Indices: DAC = 0, mixer = 1 */
7023 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7024 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7025 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7026 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7027 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7028 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 7029
df694daa
KY
7030 { }
7031};
7032
7033static int alc260_parse_auto_config(struct hda_codec *codec)
7034{
7035 struct alc_spec *spec = codec->spec;
df694daa
KY
7036 int err;
7037 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
7038
f12ab1e0
TI
7039 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7040 alc260_ignore);
7041 if (err < 0)
df694daa 7042 return err;
f12ab1e0
TI
7043 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7044 if (err < 0)
4a471b7d 7045 return err;
603c4019 7046 if (!spec->kctls.list)
df694daa 7047 return 0; /* can't find valid BIOS pin config */
05f5f477 7048 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 7049 if (err < 0)
df694daa
KY
7050 return err;
7051
7052 spec->multiout.max_channels = 2;
7053
0852d7a6 7054 if (spec->autocfg.dig_outs)
df694daa 7055 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 7056 if (spec->kctls.list)
d88897ea 7057 add_mixer(spec, spec->kctls.list);
df694daa 7058
d88897ea 7059 add_verb(spec, alc260_volume_init_verbs);
df694daa 7060
a1e8d2da 7061 spec->num_mux_defs = 1;
61b9b9b1 7062 spec->input_mux = &spec->private_imux[0];
df694daa 7063
6227cdce 7064 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 7065
df694daa
KY
7066 return 1;
7067}
7068
ae6b813a
TI
7069/* additional initialization for auto-configuration model */
7070static void alc260_auto_init(struct hda_codec *codec)
df694daa 7071{
f6c7e546 7072 struct alc_spec *spec = codec->spec;
df694daa
KY
7073 alc260_auto_init_multi_out(codec);
7074 alc260_auto_init_analog_input(codec);
7f311a46 7075 alc260_auto_init_input_src(codec);
757899ac 7076 alc_auto_init_digital(codec);
f6c7e546 7077 if (spec->unsol_event)
7fb0d78f 7078 alc_inithook(codec);
df694daa
KY
7079}
7080
cb53c626
TI
7081#ifdef CONFIG_SND_HDA_POWER_SAVE
7082static struct hda_amp_list alc260_loopbacks[] = {
7083 { 0x07, HDA_INPUT, 0 },
7084 { 0x07, HDA_INPUT, 1 },
7085 { 0x07, HDA_INPUT, 2 },
7086 { 0x07, HDA_INPUT, 3 },
7087 { 0x07, HDA_INPUT, 4 },
7088 { } /* end */
7089};
7090#endif
7091
fc091769
TI
7092/*
7093 * Pin config fixes
7094 */
7095enum {
7096 PINFIX_HP_DC5750,
7097};
7098
fc091769
TI
7099static const struct alc_fixup alc260_fixups[] = {
7100 [PINFIX_HP_DC5750] = {
b5bfbc67
TI
7101 .type = ALC_FIXUP_PINS,
7102 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
7103 { 0x11, 0x90130110 }, /* speaker */
7104 { }
7105 }
fc091769
TI
7106 },
7107};
7108
7109static struct snd_pci_quirk alc260_fixup_tbl[] = {
7110 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7111 {}
7112};
7113
df694daa
KY
7114/*
7115 * ALC260 configurations
7116 */
ea734963 7117static const char * const alc260_models[ALC260_MODEL_LAST] = {
f5fcc13c
TI
7118 [ALC260_BASIC] = "basic",
7119 [ALC260_HP] = "hp",
7120 [ALC260_HP_3013] = "hp-3013",
2922c9af 7121 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
7122 [ALC260_FUJITSU_S702X] = "fujitsu",
7123 [ALC260_ACER] = "acer",
bc9f98a9
KY
7124 [ALC260_WILL] = "will",
7125 [ALC260_REPLACER_672V] = "replacer",
cc959489 7126 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 7127#ifdef CONFIG_SND_DEBUG
f5fcc13c 7128 [ALC260_TEST] = "test",
7cf51e48 7129#endif
f5fcc13c
TI
7130 [ALC260_AUTO] = "auto",
7131};
7132
7133static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 7134 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 7135 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 7136 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 7137 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 7138 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 7139 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 7140 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 7141 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 7142 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
7143 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7144 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7145 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7146 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7147 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7148 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7149 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7150 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7151 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7152 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7153 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7154 {}
7155};
7156
7157static struct alc_config_preset alc260_presets[] = {
7158 [ALC260_BASIC] = {
7159 .mixers = { alc260_base_output_mixer,
45bdd1c1 7160 alc260_input_mixer },
df694daa
KY
7161 .init_verbs = { alc260_init_verbs },
7162 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7163 .dac_nids = alc260_dac_nids,
f9e336f6 7164 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7165 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7166 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7167 .channel_mode = alc260_modes,
7168 .input_mux = &alc260_capture_source,
7169 },
7170 [ALC260_HP] = {
bec15c3a 7171 .mixers = { alc260_hp_output_mixer,
f9e336f6 7172 alc260_input_mixer },
bec15c3a
TI
7173 .init_verbs = { alc260_init_verbs,
7174 alc260_hp_unsol_verbs },
df694daa
KY
7175 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7176 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7177 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7178 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7179 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7180 .channel_mode = alc260_modes,
7181 .input_mux = &alc260_capture_source,
bec15c3a
TI
7182 .unsol_event = alc260_hp_unsol_event,
7183 .init_hook = alc260_hp_automute,
df694daa 7184 },
3f878308
KY
7185 [ALC260_HP_DC7600] = {
7186 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7187 alc260_input_mixer },
3f878308
KY
7188 .init_verbs = { alc260_init_verbs,
7189 alc260_hp_dc7600_verbs },
7190 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7191 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7192 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7193 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7194 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7195 .channel_mode = alc260_modes,
7196 .input_mux = &alc260_capture_source,
7197 .unsol_event = alc260_hp_3012_unsol_event,
7198 .init_hook = alc260_hp_3012_automute,
7199 },
df694daa
KY
7200 [ALC260_HP_3013] = {
7201 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7202 alc260_input_mixer },
bec15c3a
TI
7203 .init_verbs = { alc260_hp_3013_init_verbs,
7204 alc260_hp_3013_unsol_verbs },
df694daa
KY
7205 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7206 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7207 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7208 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7209 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7210 .channel_mode = alc260_modes,
7211 .input_mux = &alc260_capture_source,
bec15c3a
TI
7212 .unsol_event = alc260_hp_3013_unsol_event,
7213 .init_hook = alc260_hp_3013_automute,
df694daa
KY
7214 },
7215 [ALC260_FUJITSU_S702X] = {
f9e336f6 7216 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7217 .init_verbs = { alc260_fujitsu_init_verbs },
7218 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7219 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7220 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7221 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7222 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7223 .channel_mode = alc260_modes,
a1e8d2da
JW
7224 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7225 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7226 },
0bfc90e9 7227 [ALC260_ACER] = {
f9e336f6 7228 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7229 .init_verbs = { alc260_acer_init_verbs },
7230 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7231 .dac_nids = alc260_dac_nids,
7232 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7233 .adc_nids = alc260_dual_adc_nids,
7234 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7235 .channel_mode = alc260_modes,
a1e8d2da
JW
7236 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7237 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7238 },
cc959489
MS
7239 [ALC260_FAVORIT100] = {
7240 .mixers = { alc260_favorit100_mixer },
7241 .init_verbs = { alc260_favorit100_init_verbs },
7242 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7243 .dac_nids = alc260_dac_nids,
7244 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7245 .adc_nids = alc260_dual_adc_nids,
7246 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7247 .channel_mode = alc260_modes,
7248 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7249 .input_mux = alc260_favorit100_capture_sources,
7250 },
bc9f98a9 7251 [ALC260_WILL] = {
f9e336f6 7252 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7253 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7254 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7255 .dac_nids = alc260_dac_nids,
7256 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7257 .adc_nids = alc260_adc_nids,
7258 .dig_out_nid = ALC260_DIGOUT_NID,
7259 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7260 .channel_mode = alc260_modes,
7261 .input_mux = &alc260_capture_source,
7262 },
7263 [ALC260_REPLACER_672V] = {
f9e336f6 7264 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7265 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7266 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7267 .dac_nids = alc260_dac_nids,
7268 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7269 .adc_nids = alc260_adc_nids,
7270 .dig_out_nid = ALC260_DIGOUT_NID,
7271 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7272 .channel_mode = alc260_modes,
7273 .input_mux = &alc260_capture_source,
7274 .unsol_event = alc260_replacer_672v_unsol_event,
7275 .init_hook = alc260_replacer_672v_automute,
7276 },
7cf51e48
JW
7277#ifdef CONFIG_SND_DEBUG
7278 [ALC260_TEST] = {
f9e336f6 7279 .mixers = { alc260_test_mixer },
7cf51e48
JW
7280 .init_verbs = { alc260_test_init_verbs },
7281 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7282 .dac_nids = alc260_test_dac_nids,
7283 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7284 .adc_nids = alc260_test_adc_nids,
7285 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7286 .channel_mode = alc260_modes,
a1e8d2da
JW
7287 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7288 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7289 },
7290#endif
df694daa
KY
7291};
7292
7293static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7294{
7295 struct alc_spec *spec;
df694daa 7296 int err, board_config;
1da177e4 7297
e560d8d8 7298 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7299 if (spec == NULL)
7300 return -ENOMEM;
7301
7302 codec->spec = spec;
7303
f5fcc13c
TI
7304 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7305 alc260_models,
7306 alc260_cfg_tbl);
7307 if (board_config < 0) {
9a11f1aa 7308 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7309 codec->chip_name);
df694daa 7310 board_config = ALC260_AUTO;
16ded525 7311 }
1da177e4 7312
b5bfbc67
TI
7313 if (board_config == ALC260_AUTO) {
7314 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7315 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7316 }
fc091769 7317
df694daa
KY
7318 if (board_config == ALC260_AUTO) {
7319 /* automatic parse from the BIOS config */
7320 err = alc260_parse_auto_config(codec);
7321 if (err < 0) {
7322 alc_free(codec);
7323 return err;
f12ab1e0 7324 } else if (!err) {
9c7f852e
TI
7325 printk(KERN_INFO
7326 "hda_codec: Cannot set up configuration "
7327 "from BIOS. Using base mode...\n");
df694daa
KY
7328 board_config = ALC260_BASIC;
7329 }
a9430dd8 7330 }
e9edcee0 7331
680cd536
KK
7332 err = snd_hda_attach_beep_device(codec, 0x1);
7333 if (err < 0) {
7334 alc_free(codec);
7335 return err;
7336 }
7337
df694daa 7338 if (board_config != ALC260_AUTO)
e9c364c0 7339 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7340
1da177e4
LT
7341 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7342 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7343 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7344
a3bcba38
TI
7345 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7346 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7347
4ef0ef19
TI
7348 if (!spec->adc_nids && spec->input_mux) {
7349 /* check whether NID 0x04 is valid */
7350 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7351 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7352 /* get type */
7353 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7354 spec->adc_nids = alc260_adc_nids_alt;
7355 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7356 } else {
7357 spec->adc_nids = alc260_adc_nids;
7358 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7359 }
7360 }
b59bdf3b 7361 set_capture_mixer(codec);
45bdd1c1 7362 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7363
b5bfbc67 7364 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
fc091769 7365
2134ea4f
TI
7366 spec->vmaster_nid = 0x08;
7367
1da177e4 7368 codec->patch_ops = alc_patch_ops;
df694daa 7369 if (board_config == ALC260_AUTO)
ae6b813a 7370 spec->init_hook = alc260_auto_init;
cb53c626
TI
7371#ifdef CONFIG_SND_HDA_POWER_SAVE
7372 if (!spec->loopback.amplist)
7373 spec->loopback.amplist = alc260_loopbacks;
7374#endif
1da177e4
LT
7375
7376 return 0;
7377}
7378
e9edcee0 7379
1da177e4 7380/*
4953550a 7381 * ALC882/883/885/888/889 support
1da177e4
LT
7382 *
7383 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7384 * configuration. Each pin widget can choose any input DACs and a mixer.
7385 * Each ADC is connected from a mixer of all inputs. This makes possible
7386 * 6-channel independent captures.
7387 *
7388 * In addition, an independent DAC for the multi-playback (not used in this
7389 * driver yet).
7390 */
df694daa
KY
7391#define ALC882_DIGOUT_NID 0x06
7392#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7393#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7394#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7395#define ALC1200_DIGOUT_NID 0x10
7396
1da177e4 7397
d2a6d7dc 7398static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7399 { 8, NULL }
7400};
7401
4953550a 7402/* DACs */
1da177e4
LT
7403static hda_nid_t alc882_dac_nids[4] = {
7404 /* front, rear, clfe, rear_surr */
7405 0x02, 0x03, 0x04, 0x05
7406};
4953550a 7407#define alc883_dac_nids alc882_dac_nids
1da177e4 7408
4953550a 7409/* ADCs */
df694daa
KY
7410#define alc882_adc_nids alc880_adc_nids
7411#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
7412#define alc883_adc_nids alc882_adc_nids_alt
7413static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7414static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7415#define alc889_adc_nids alc880_adc_nids
1da177e4 7416
e1406348
TI
7417static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7418static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
7419#define alc883_capsrc_nids alc882_capsrc_nids_alt
7420static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7421#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7422
1da177e4
LT
7423/* input MUX */
7424/* FIXME: should be a matrix-type input source selection */
7425
7426static struct hda_input_mux alc882_capture_source = {
7427 .num_items = 4,
7428 .items = {
7429 { "Mic", 0x0 },
7430 { "Front Mic", 0x1 },
7431 { "Line", 0x2 },
7432 { "CD", 0x4 },
7433 },
7434};
41d5545d 7435
4953550a
TI
7436#define alc883_capture_source alc882_capture_source
7437
87a8c370
JK
7438static struct hda_input_mux alc889_capture_source = {
7439 .num_items = 3,
7440 .items = {
7441 { "Front Mic", 0x0 },
7442 { "Mic", 0x3 },
7443 { "Line", 0x2 },
7444 },
7445};
7446
41d5545d
KS
7447static struct hda_input_mux mb5_capture_source = {
7448 .num_items = 3,
7449 .items = {
7450 { "Mic", 0x1 },
b8f171e7 7451 { "Line", 0x7 },
41d5545d
KS
7452 { "CD", 0x4 },
7453 },
7454};
7455
e458b1fa
LY
7456static struct hda_input_mux macmini3_capture_source = {
7457 .num_items = 2,
7458 .items = {
7459 { "Line", 0x2 },
7460 { "CD", 0x4 },
7461 },
7462};
7463
4953550a
TI
7464static struct hda_input_mux alc883_3stack_6ch_intel = {
7465 .num_items = 4,
7466 .items = {
7467 { "Mic", 0x1 },
7468 { "Front Mic", 0x0 },
7469 { "Line", 0x2 },
7470 { "CD", 0x4 },
7471 },
7472};
7473
7474static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7475 .num_items = 2,
7476 .items = {
7477 { "Mic", 0x1 },
7478 { "Line", 0x2 },
7479 },
7480};
7481
7482static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7483 .num_items = 4,
7484 .items = {
7485 { "Mic", 0x0 },
28c4edb7 7486 { "Internal Mic", 0x1 },
4953550a
TI
7487 { "Line", 0x2 },
7488 { "CD", 0x4 },
7489 },
7490};
7491
7492static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7493 .num_items = 2,
7494 .items = {
7495 { "Mic", 0x0 },
28c4edb7 7496 { "Internal Mic", 0x1 },
4953550a
TI
7497 },
7498};
7499
7500static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7501 .num_items = 3,
7502 .items = {
7503 { "Mic", 0x0 },
7504 { "Front Mic", 0x1 },
7505 { "Line", 0x4 },
7506 },
7507};
7508
7509static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7510 .num_items = 2,
7511 .items = {
7512 { "Mic", 0x0 },
7513 { "Line", 0x2 },
7514 },
7515};
7516
7517static struct hda_input_mux alc889A_mb31_capture_source = {
7518 .num_items = 2,
7519 .items = {
7520 { "Mic", 0x0 },
7521 /* Front Mic (0x01) unused */
7522 { "Line", 0x2 },
7523 /* Line 2 (0x03) unused */
af901ca1 7524 /* CD (0x04) unused? */
4953550a
TI
7525 },
7526};
7527
b7cccc52
JM
7528static struct hda_input_mux alc889A_imac91_capture_source = {
7529 .num_items = 2,
7530 .items = {
7531 { "Mic", 0x01 },
7532 { "Line", 0x2 }, /* Not sure! */
7533 },
7534};
7535
4953550a
TI
7536/*
7537 * 2ch mode
7538 */
7539static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7540 { 2, NULL }
7541};
7542
272a527c
KY
7543/*
7544 * 2ch mode
7545 */
7546static struct hda_verb alc882_3ST_ch2_init[] = {
7547 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7548 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7549 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7550 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7551 { } /* end */
7552};
7553
4953550a
TI
7554/*
7555 * 4ch mode
7556 */
7557static struct hda_verb alc882_3ST_ch4_init[] = {
7558 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7559 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7560 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7561 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7562 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7563 { } /* end */
7564};
7565
272a527c
KY
7566/*
7567 * 6ch mode
7568 */
7569static struct hda_verb alc882_3ST_ch6_init[] = {
7570 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7571 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7572 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7573 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7574 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7575 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7576 { } /* end */
7577};
7578
4953550a 7579static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7580 { 2, alc882_3ST_ch2_init },
4953550a 7581 { 4, alc882_3ST_ch4_init },
272a527c
KY
7582 { 6, alc882_3ST_ch6_init },
7583};
7584
4953550a
TI
7585#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7586
a65cc60f 7587/*
7588 * 2ch mode
7589 */
7590static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7591 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7592 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7593 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7594 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7595 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7596 { } /* end */
7597};
7598
7599/*
7600 * 4ch mode
7601 */
7602static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7603 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7604 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7605 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7606 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7607 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7608 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7609 { } /* end */
7610};
7611
7612/*
7613 * 6ch mode
7614 */
7615static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7616 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7617 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7618 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7619 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7620 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7621 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7622 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7623 { } /* end */
7624};
7625
7626static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7627 { 2, alc883_3ST_ch2_clevo_init },
7628 { 4, alc883_3ST_ch4_clevo_init },
7629 { 6, alc883_3ST_ch6_clevo_init },
7630};
7631
7632
df694daa
KY
7633/*
7634 * 6ch mode
7635 */
7636static struct hda_verb alc882_sixstack_ch6_init[] = {
7637 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7638 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7639 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7640 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7641 { } /* end */
7642};
7643
7644/*
7645 * 8ch mode
7646 */
7647static struct hda_verb alc882_sixstack_ch8_init[] = {
7648 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7649 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7650 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7651 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7652 { } /* end */
7653};
7654
7655static struct hda_channel_mode alc882_sixstack_modes[2] = {
7656 { 6, alc882_sixstack_ch6_init },
7657 { 8, alc882_sixstack_ch8_init },
7658};
7659
76e6f5a9
RH
7660
7661/* Macbook Air 2,1 */
7662
7663static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7664 { 2, NULL },
7665};
7666
87350ad0 7667/*
def319f9 7668 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7669 */
7670
7671/*
7672 * 2ch mode
7673 */
7674static struct hda_verb alc885_mbp_ch2_init[] = {
7675 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7676 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7677 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7678 { } /* end */
7679};
7680
7681/*
a3f730af 7682 * 4ch mode
87350ad0 7683 */
a3f730af 7684static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7685 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7686 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7687 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7688 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7689 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7690 { } /* end */
7691};
7692
a3f730af 7693static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7694 { 2, alc885_mbp_ch2_init },
a3f730af 7695 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7696};
7697
92b9de83
KS
7698/*
7699 * 2ch
7700 * Speakers/Woofer/HP = Front
7701 * LineIn = Input
7702 */
7703static struct hda_verb alc885_mb5_ch2_init[] = {
7704 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7705 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7706 { } /* end */
7707};
7708
7709/*
7710 * 6ch mode
7711 * Speakers/HP = Front
7712 * Woofer = LFE
7713 * LineIn = Surround
7714 */
7715static struct hda_verb alc885_mb5_ch6_init[] = {
7716 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7717 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7718 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7719 { } /* end */
7720};
7721
7722static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7723 { 2, alc885_mb5_ch2_init },
7724 { 6, alc885_mb5_ch6_init },
7725};
87350ad0 7726
d01aecdf 7727#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7728
7729/*
7730 * 2ch mode
7731 */
7732static struct hda_verb alc883_4ST_ch2_init[] = {
7733 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7734 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7735 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7736 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7737 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7738 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7739 { } /* end */
7740};
7741
7742/*
7743 * 4ch mode
7744 */
7745static struct hda_verb alc883_4ST_ch4_init[] = {
7746 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7747 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7748 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7749 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7750 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7751 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7752 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7753 { } /* end */
7754};
7755
7756/*
7757 * 6ch mode
7758 */
7759static struct hda_verb alc883_4ST_ch6_init[] = {
7760 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7761 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7762 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7763 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7764 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7765 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7766 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7767 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7768 { } /* end */
7769};
7770
7771/*
7772 * 8ch mode
7773 */
7774static struct hda_verb alc883_4ST_ch8_init[] = {
7775 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7776 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7777 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7778 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7779 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7780 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7781 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7782 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7783 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7784 { } /* end */
7785};
7786
7787static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7788 { 2, alc883_4ST_ch2_init },
7789 { 4, alc883_4ST_ch4_init },
7790 { 6, alc883_4ST_ch6_init },
7791 { 8, alc883_4ST_ch8_init },
7792};
7793
7794
7795/*
7796 * 2ch mode
7797 */
7798static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7799 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7800 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7801 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7802 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7803 { } /* end */
7804};
7805
7806/*
7807 * 4ch mode
7808 */
7809static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7810 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7811 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7812 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7813 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7814 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7815 { } /* end */
7816};
7817
7818/*
7819 * 6ch mode
7820 */
7821static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7822 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7823 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7824 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7825 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7826 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7827 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7828 { } /* end */
7829};
7830
7831static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7832 { 2, alc883_3ST_ch2_intel_init },
7833 { 4, alc883_3ST_ch4_intel_init },
7834 { 6, alc883_3ST_ch6_intel_init },
7835};
7836
dd7714c9
WF
7837/*
7838 * 2ch mode
7839 */
7840static struct hda_verb alc889_ch2_intel_init[] = {
7841 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7842 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7843 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7844 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7845 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7846 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7847 { } /* end */
7848};
7849
87a8c370
JK
7850/*
7851 * 6ch mode
7852 */
7853static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7854 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7855 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7856 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7857 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7858 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7859 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7860 { } /* end */
7861};
7862
7863/*
7864 * 8ch mode
7865 */
7866static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7867 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7868 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7869 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7870 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7871 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7872 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7873 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7874 { } /* end */
7875};
7876
dd7714c9
WF
7877static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7878 { 2, alc889_ch2_intel_init },
87a8c370
JK
7879 { 6, alc889_ch6_intel_init },
7880 { 8, alc889_ch8_intel_init },
7881};
7882
4953550a
TI
7883/*
7884 * 6ch mode
7885 */
7886static struct hda_verb alc883_sixstack_ch6_init[] = {
7887 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7888 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7889 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7890 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7891 { } /* end */
7892};
7893
7894/*
7895 * 8ch mode
7896 */
7897static struct hda_verb alc883_sixstack_ch8_init[] = {
7898 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7899 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7900 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7901 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7902 { } /* end */
7903};
7904
7905static struct hda_channel_mode alc883_sixstack_modes[2] = {
7906 { 6, alc883_sixstack_ch6_init },
7907 { 8, alc883_sixstack_ch8_init },
7908};
7909
7910
1da177e4
LT
7911/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7912 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7913 */
c8b6bf9b 7914static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7915 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7916 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7917 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7918 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7919 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7920 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7921 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7922 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7923 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7924 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7925 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7926 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7927 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7928 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7929 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7930 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 7931 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1da177e4
LT
7932 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7933 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 7934 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1da177e4 7935 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7936 { } /* end */
7937};
7938
76e6f5a9
RH
7939/* Macbook Air 2,1 same control for HP and internal Speaker */
7940
7941static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7942 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7943 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7944 { }
7945};
7946
7947
87350ad0 7948static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7949 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7950 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7951 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7952 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7953 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7954 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7955 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7956 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7957 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5f99f86a
DH
7958 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
7959 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
87350ad0
TI
7960 { } /* end */
7961};
41d5545d
KS
7962
7963static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
7964 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7965 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7966 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7967 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7968 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7969 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
7970 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7971 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
7972 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7973 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
7974 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7975 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
7976 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
7977 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
41d5545d
KS
7978 { } /* end */
7979};
92b9de83 7980
e458b1fa
LY
7981static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7982 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7983 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7984 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7985 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7986 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7987 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7988 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7989 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7990 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7991 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
5f99f86a 7992 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
e458b1fa
LY
7993 { } /* end */
7994};
7995
4b7e1803 7996static struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
7997 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7998 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
7999 { } /* end */
8000};
8001
8002
bdd148a3
KY
8003static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8004 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8005 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8006 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8007 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8008 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8009 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8010 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8011 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3 8012 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
8013 { } /* end */
8014};
8015
272a527c
KY
8016static struct snd_kcontrol_new alc882_targa_mixer[] = {
8017 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8018 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8019 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8020 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8021 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8022 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8023 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8024 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8025 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8026 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8027 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8028 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8029 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272a527c
KY
8030 { } /* end */
8031};
8032
8033/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8034 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8035 */
8036static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8037 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8038 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8039 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8040 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8041 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8042 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8043 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8044 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8045 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8046 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8047 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8048 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8049 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8050 { } /* end */
8051};
8052
914759b7
TI
8053static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8054 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8055 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8056 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8057 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8058 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8059 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8060 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8061 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8062 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
914759b7 8063 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
8064 { } /* end */
8065};
8066
df694daa
KY
8067static struct snd_kcontrol_new alc882_chmode_mixer[] = {
8068 {
8069 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8070 .name = "Channel Mode",
8071 .info = alc_ch_mode_info,
8072 .get = alc_ch_mode_get,
8073 .put = alc_ch_mode_put,
8074 },
8075 { } /* end */
8076};
8077
4953550a 8078static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 8079 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
8080 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8081 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8082 /* Rear mixer */
05acb863
TI
8083 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8084 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8085 /* CLFE mixer */
05acb863
TI
8086 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8087 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8088 /* Side mixer */
05acb863
TI
8089 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8090 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8091
e9edcee0 8092 /* Front Pin: output 0 (0x0c) */
05acb863 8093 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8094 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8095 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 8096 /* Rear Pin: output 1 (0x0d) */
05acb863 8097 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8098 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8099 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 8100 /* CLFE Pin: output 2 (0x0e) */
05acb863 8101 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8102 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8103 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 8104 /* Side Pin: output 3 (0x0f) */
05acb863 8105 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8106 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8107 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 8108 /* Mic (rear) pin: input vref at 80% */
16ded525 8109 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8110 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8111 /* Front Mic pin: input vref at 80% */
16ded525 8112 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8113 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8114 /* Line In pin: input */
05acb863 8115 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
8116 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8117 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8118 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8119 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8120 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 8121 /* CD pin widget for input */
05acb863 8122 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
8123
8124 /* FIXME: use matrix-type input source selection */
8125 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 8126 /* Input mixer2 */
05acb863 8127 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 8128 /* Input mixer3 */
05acb863 8129 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
8130 /* ADC2: mute amp left and right */
8131 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8132 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
8133 /* ADC3: mute amp left and right */
8134 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8135 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
8136
8137 { }
8138};
8139
4953550a
TI
8140static struct hda_verb alc882_adc1_init_verbs[] = {
8141 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8142 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8143 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8144 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8145 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8146 /* ADC1: mute amp left and right */
8147 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8148 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8149 { }
8150};
8151
4b146cb0
TI
8152static struct hda_verb alc882_eapd_verbs[] = {
8153 /* change to EAPD mode */
8154 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8155 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8156 { }
4b146cb0
TI
8157};
8158
87a8c370
JK
8159static struct hda_verb alc889_eapd_verbs[] = {
8160 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8161 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8162 { }
8163};
8164
6732bd0d
WF
8165static struct hda_verb alc_hp15_unsol_verbs[] = {
8166 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8167 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8168 {}
8169};
87a8c370
JK
8170
8171static struct hda_verb alc885_init_verbs[] = {
8172 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8173 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8174 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8175 /* Rear mixer */
88102f3f
KY
8176 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8177 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8178 /* CLFE mixer */
88102f3f
KY
8179 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8180 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8181 /* Side mixer */
88102f3f
KY
8182 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8183 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8184
8185 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8186 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8187 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8188 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8189 /* Front Pin: output 0 (0x0c) */
8190 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8191 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8192 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8193 /* Rear Pin: output 1 (0x0d) */
8194 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8195 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8196 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8197 /* CLFE Pin: output 2 (0x0e) */
8198 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8199 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8200 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8201 /* Side Pin: output 3 (0x0f) */
8202 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8203 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8204 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8205 /* Mic (rear) pin: input vref at 80% */
8206 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8207 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8208 /* Front Mic pin: input vref at 80% */
8209 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8210 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8211 /* Line In pin: input */
8212 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8213 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8214
8215 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8216 /* Input mixer1 */
88102f3f 8217 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8218 /* Input mixer2 */
8219 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8220 /* Input mixer3 */
88102f3f 8221 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8222 /* ADC2: mute amp left and right */
8223 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8224 /* ADC3: mute amp left and right */
8225 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8226
8227 { }
8228};
8229
8230static struct hda_verb alc885_init_input_verbs[] = {
8231 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8232 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8233 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8234 { }
8235};
8236
8237
8238/* Unmute Selector 24h and set the default input to front mic */
8239static struct hda_verb alc889_init_input_verbs[] = {
8240 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8241 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8242 { }
8243};
8244
8245
4953550a
TI
8246#define alc883_init_verbs alc882_base_init_verbs
8247
9102cd1c
TD
8248/* Mac Pro test */
8249static struct snd_kcontrol_new alc882_macpro_mixer[] = {
8250 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8251 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8252 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8253 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8254 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8255 /* FIXME: this looks suspicious...
d355c82a
JK
8256 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8257 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8258 */
9102cd1c
TD
8259 { } /* end */
8260};
8261
8262static struct hda_verb alc882_macpro_init_verbs[] = {
8263 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8264 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8265 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8266 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8267 /* Front Pin: output 0 (0x0c) */
8268 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8269 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8270 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8271 /* Front Mic pin: input vref at 80% */
8272 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8273 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8274 /* Speaker: output */
8275 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8276 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8277 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8278 /* Headphone output (output 0 - 0x0c) */
8279 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8280 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8281 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8282
8283 /* FIXME: use matrix-type input source selection */
8284 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8285 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8286 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8287 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8288 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8289 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8290 /* Input mixer2 */
8291 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8292 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8293 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8294 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8295 /* Input mixer3 */
8296 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8297 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8298 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8299 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8300 /* ADC1: mute amp left and right */
8301 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8302 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8303 /* ADC2: mute amp left and right */
8304 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8305 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8306 /* ADC3: mute amp left and right */
8307 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8308 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8309
8310 { }
8311};
f12ab1e0 8312
41d5545d
KS
8313/* Macbook 5,1 */
8314static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8315 /* DACs */
8316 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8317 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8318 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8319 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8320 /* Front mixer */
41d5545d
KS
8321 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8322 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8323 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8324 /* Surround mixer */
8325 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8326 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8327 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8328 /* LFE mixer */
8329 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8330 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8331 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8332 /* HP mixer */
8333 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8334 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8335 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8336 /* Front Pin (0x0c) */
41d5545d
KS
8337 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8338 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8339 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8340 /* LFE Pin (0x0e) */
8341 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8342 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8343 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8344 /* HP Pin (0x0f) */
41d5545d
KS
8345 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8346 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8347 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8348 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8349 /* Front Mic pin: input vref at 80% */
8350 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8351 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8352 /* Line In pin */
8353 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8354 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8355
b8f171e7
AM
8356 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8357 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8358 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8359 { }
8360};
8361
e458b1fa
LY
8362/* Macmini 3,1 */
8363static struct hda_verb alc885_macmini3_init_verbs[] = {
8364 /* DACs */
8365 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8366 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8367 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8368 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8369 /* Front mixer */
8370 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8371 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8372 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8373 /* Surround mixer */
8374 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8375 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8376 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8377 /* LFE mixer */
8378 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8379 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8380 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8381 /* HP mixer */
8382 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8383 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8384 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8385 /* Front Pin (0x0c) */
8386 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8387 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8388 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8389 /* LFE Pin (0x0e) */
8390 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8391 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8392 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8393 /* HP Pin (0x0f) */
8394 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8395 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8396 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8397 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8398 /* Line In pin */
8399 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8400 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8401
8402 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8403 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8404 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8405 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8406 { }
8407};
8408
76e6f5a9
RH
8409
8410static struct hda_verb alc885_mba21_init_verbs[] = {
8411 /*Internal and HP Speaker Mixer*/
8412 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8413 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8415 /*Internal Speaker Pin (0x0c)*/
8416 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8417 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8418 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8419 /* HP Pin: output 0 (0x0e) */
8420 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8421 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8422 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8423 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8424 /* Line in (is hp when jack connected)*/
8425 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8426 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8427
8428 { }
8429 };
8430
8431
87350ad0
TI
8432/* Macbook Pro rev3 */
8433static struct hda_verb alc885_mbp3_init_verbs[] = {
8434 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8435 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8436 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8437 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8438 /* Rear mixer */
8439 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8440 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8441 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8442 /* HP mixer */
8443 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8444 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8445 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8446 /* Front Pin: output 0 (0x0c) */
8447 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8448 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8449 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8450 /* HP Pin: output 0 (0x0e) */
87350ad0 8451 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8452 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8453 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8454 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8455 /* Mic (rear) pin: input vref at 80% */
8456 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8457 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8458 /* Front Mic pin: input vref at 80% */
8459 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8460 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8461 /* Line In pin: use output 1 when in LineOut mode */
8462 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8463 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8464 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8465
8466 /* FIXME: use matrix-type input source selection */
8467 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8468 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8469 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8470 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8471 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8472 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8473 /* Input mixer2 */
8474 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8475 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8476 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8477 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8478 /* Input mixer3 */
8479 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8480 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8481 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8482 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8483 /* ADC1: mute amp left and right */
8484 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8485 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8486 /* ADC2: mute amp left and right */
8487 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8488 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8489 /* ADC3: mute amp left and right */
8490 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8491 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8492
8493 { }
8494};
8495
4b7e1803
JM
8496/* iMac 9,1 */
8497static struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8498 /* Internal Speaker Pin (0x0c) */
8499 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8500 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8501 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8502 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8503 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8504 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8505 /* HP Pin: Rear */
4b7e1803
JM
8506 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8507 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8508 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8509 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8510 /* Line in Rear */
8511 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8512 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8513 /* Front Mic pin: input vref at 80% */
8514 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8515 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8516 /* Rear mixer */
8517 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8518 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8519 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8520 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8521 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8522 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8523 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8524 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8525 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8526 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8527 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8528 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8529 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8530 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8531 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8532 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8533 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8534 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8535 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8536 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8537 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8538 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8539 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8540 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8541 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8542 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8543 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8544 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8545 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8546 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8547 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8548 { }
8549};
8550
c54728d8
NF
8551/* iMac 24 mixer. */
8552static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8553 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8554 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8555 { } /* end */
8556};
8557
8558/* iMac 24 init verbs. */
8559static struct hda_verb alc885_imac24_init_verbs[] = {
8560 /* Internal speakers: output 0 (0x0c) */
8561 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8562 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8563 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8564 /* Internal speakers: output 0 (0x0c) */
8565 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8566 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8567 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8568 /* Headphone: output 0 (0x0c) */
8569 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8570 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8571 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8572 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8573 /* Front Mic: input vref at 80% */
8574 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8575 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8576 { }
8577};
8578
8579/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8580static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8581{
a9fd4f3f 8582 struct alc_spec *spec = codec->spec;
c54728d8 8583
a9fd4f3f
TI
8584 spec->autocfg.hp_pins[0] = 0x14;
8585 spec->autocfg.speaker_pins[0] = 0x18;
8586 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8587}
8588
9d54f08b
TI
8589#define alc885_mb5_setup alc885_imac24_setup
8590#define alc885_macmini3_setup alc885_imac24_setup
8591
76e6f5a9
RH
8592/* Macbook Air 2,1 */
8593static void alc885_mba21_setup(struct hda_codec *codec)
8594{
8595 struct alc_spec *spec = codec->spec;
8596
8597 spec->autocfg.hp_pins[0] = 0x14;
8598 spec->autocfg.speaker_pins[0] = 0x18;
8599}
8600
8601
8602
4f5d1706 8603static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8604{
a9fd4f3f 8605 struct alc_spec *spec = codec->spec;
87350ad0 8606
a9fd4f3f
TI
8607 spec->autocfg.hp_pins[0] = 0x15;
8608 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8609}
8610
9d54f08b 8611static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8612{
9d54f08b 8613 struct alc_spec *spec = codec->spec;
4b7e1803 8614
9d54f08b 8615 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8616 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8617 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8618}
87350ad0 8619
272a527c
KY
8620static struct hda_verb alc882_targa_verbs[] = {
8621 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8622 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8623
8624 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8625 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8626
272a527c
KY
8627 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8628 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8629 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8630
8631 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8632 { } /* end */
8633};
8634
8635/* toggle speaker-output according to the hp-jack state */
8636static void alc882_targa_automute(struct hda_codec *codec)
8637{
a9fd4f3f
TI
8638 struct alc_spec *spec = codec->spec;
8639 alc_automute_amp(codec);
82beb8fd 8640 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8641 spec->jack_present ? 1 : 3);
8642}
8643
4f5d1706 8644static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8645{
8646 struct alc_spec *spec = codec->spec;
8647
8648 spec->autocfg.hp_pins[0] = 0x14;
8649 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8650}
8651
8652static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8653{
a9fd4f3f 8654 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8655 alc882_targa_automute(codec);
272a527c
KY
8656}
8657
8658static struct hda_verb alc882_asus_a7j_verbs[] = {
8659 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8660 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8661
8662 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8663 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8664 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8665
272a527c
KY
8666 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8667 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8668 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8669
8670 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8671 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8672 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8673 { } /* end */
8674};
8675
914759b7
TI
8676static struct hda_verb alc882_asus_a7m_verbs[] = {
8677 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8678 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8679
8680 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8681 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8682 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8683
914759b7
TI
8684 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8685 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8686 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8687
8688 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8689 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8690 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8691 { } /* end */
8692};
8693
9102cd1c
TD
8694static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8695{
8696 unsigned int gpiostate, gpiomask, gpiodir;
8697
8698 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8699 AC_VERB_GET_GPIO_DATA, 0);
8700
8701 if (!muted)
8702 gpiostate |= (1 << pin);
8703 else
8704 gpiostate &= ~(1 << pin);
8705
8706 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8707 AC_VERB_GET_GPIO_MASK, 0);
8708 gpiomask |= (1 << pin);
8709
8710 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8711 AC_VERB_GET_GPIO_DIRECTION, 0);
8712 gpiodir |= (1 << pin);
8713
8714
8715 snd_hda_codec_write(codec, codec->afg, 0,
8716 AC_VERB_SET_GPIO_MASK, gpiomask);
8717 snd_hda_codec_write(codec, codec->afg, 0,
8718 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8719
8720 msleep(1);
8721
8722 snd_hda_codec_write(codec, codec->afg, 0,
8723 AC_VERB_SET_GPIO_DATA, gpiostate);
8724}
8725
7debbe51
TI
8726/* set up GPIO at initialization */
8727static void alc885_macpro_init_hook(struct hda_codec *codec)
8728{
8729 alc882_gpio_mute(codec, 0, 0);
8730 alc882_gpio_mute(codec, 1, 0);
8731}
8732
8733/* set up GPIO and update auto-muting at initialization */
8734static void alc885_imac24_init_hook(struct hda_codec *codec)
8735{
8736 alc885_macpro_init_hook(codec);
4f5d1706 8737 alc_automute_amp(codec);
7debbe51
TI
8738}
8739
df694daa
KY
8740/*
8741 * generic initialization of ADC, input mixers and output mixers
8742 */
4953550a 8743static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8744 /*
8745 * Unmute ADC0-2 and set the default input to mic-in
8746 */
4953550a
TI
8747 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8748 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8749 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8750 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8751
4953550a
TI
8752 /*
8753 * Set up output mixers (0x0c - 0x0f)
8754 */
8755 /* set vol=0 to output mixers */
8756 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8757 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8758 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8759 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8760 /* set up input amps for analog loopback */
8761 /* Amp Indices: DAC = 0, mixer = 1 */
8762 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8763 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8764 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8765 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8766 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8767 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8768 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8769 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8770 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8771 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8772
4953550a
TI
8773 /* FIXME: use matrix-type input source selection */
8774 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8775 /* Input mixer2 */
88102f3f 8776 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8777 /* Input mixer3 */
88102f3f 8778 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8779 { }
9c7f852e
TI
8780};
8781
eb4c41d3
TS
8782/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8783static struct hda_verb alc889A_mb31_ch2_init[] = {
8784 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8785 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8786 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8787 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8788 { } /* end */
8789};
8790
8791/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8792static struct hda_verb alc889A_mb31_ch4_init[] = {
8793 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8794 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8795 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8796 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8797 { } /* end */
8798};
8799
8800/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8801static struct hda_verb alc889A_mb31_ch5_init[] = {
8802 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8803 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8804 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8805 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8806 { } /* end */
8807};
8808
8809/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8810static struct hda_verb alc889A_mb31_ch6_init[] = {
8811 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8812 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8813 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8814 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8815 { } /* end */
8816};
8817
8818static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8819 { 2, alc889A_mb31_ch2_init },
8820 { 4, alc889A_mb31_ch4_init },
8821 { 5, alc889A_mb31_ch5_init },
8822 { 6, alc889A_mb31_ch6_init },
8823};
8824
b373bdeb
AN
8825static struct hda_verb alc883_medion_eapd_verbs[] = {
8826 /* eanable EAPD on medion laptop */
8827 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8828 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8829 { }
8830};
8831
4953550a 8832#define alc883_base_mixer alc882_base_mixer
834be88d 8833
a8848bd6
AS
8834static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8835 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8836 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8837 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8838 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8839 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8840 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8841 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8842 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8843 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
a8848bd6
AS
8844 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8845 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8846 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
a8848bd6 8847 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8848 { } /* end */
8849};
8850
0c4cc443 8851static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8852 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8853 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8854 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8855 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8856 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8857 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
368c7a95 8858 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8859 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8860 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8861 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8862 { } /* end */
8863};
8864
fb97dc67
J
8865static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8866 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8867 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8868 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8869 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8870 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8871 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
fb97dc67 8872 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8873 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8874 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8875 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8876 { } /* end */
8877};
8878
9c7f852e
TI
8879static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8880 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8881 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8882 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8883 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8884 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8885 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8886 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8887 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8888 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8889 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8890 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8891 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8892 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8893 { } /* end */
8894};
df694daa 8895
9c7f852e
TI
8896static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8897 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8898 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8899 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8900 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8901 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8902 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8903 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8904 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8905 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8906 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8907 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8908 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8909 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8910 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8911 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8912 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8913 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8914 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8915 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8916 { } /* end */
8917};
8918
17bba1b7
J
8919static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8920 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8921 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8922 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8923 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8924 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8925 HDA_OUTPUT),
8926 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8927 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8928 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8929 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8930 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8931 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8932 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8933 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8934 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8935 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
17bba1b7
J
8936 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8937 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8938 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
17bba1b7 8939 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8940 { } /* end */
8941};
8942
87a8c370
JK
8943static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8944 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8945 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8946 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8947 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8948 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8949 HDA_OUTPUT),
8950 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8951 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8952 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8953 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8954 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8955 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8956 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8957 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8958 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
5f99f86a 8959 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
87a8c370
JK
8960 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8961 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8962 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
87a8c370
JK
8963 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8964 { } /* end */
8965};
8966
d1d985f0 8967static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8968 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8969 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8970 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8971 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8972 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8973 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8974 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8975 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8976 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8977 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8978 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8979 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8980 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8981 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8982 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
c07584c8
TD
8983 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8984 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8985 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
c07584c8 8986 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
8987 { } /* end */
8988};
8989
c259249f 8990static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 8991 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8992 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8993 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8994 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8995 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8996 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8997 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8998 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8999 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9000 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9001 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9002 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9003 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9004 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9005 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9006 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9007 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 9008 { } /* end */
f12ab1e0 9009};
ccc656ce 9010
c259249f 9011static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 9012 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9013 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9014 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9015 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9016 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9017 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9018 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9019 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9020 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9021 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9022 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9023 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 9024 { } /* end */
f12ab1e0 9025};
ccc656ce 9026
b99dba34
TI
9027static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9028 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9029 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
28c4edb7 9030 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9031 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9032 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
b99dba34
TI
9033 { } /* end */
9034};
9035
bc9f98a9
KY
9036static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9037 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9038 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
9039 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9040 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
9041 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9042 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9043 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bc9f98a9 9044 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 9045 { } /* end */
f12ab1e0 9046};
bc9f98a9 9047
272a527c
KY
9048static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9049 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9050 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9051 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9052 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9053 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9054 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9055 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
9056 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9057 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c 9058 { } /* end */
ea1fb29a 9059};
272a527c 9060
7ad7b218
MC
9061static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9062 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9063 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9064 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9065 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9066 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9067 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9068 { } /* end */
9069};
9070
9071static struct hda_verb alc883_medion_wim2160_verbs[] = {
9072 /* Unmute front mixer */
9073 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9074 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9075
9076 /* Set speaker pin to front mixer */
9077 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9078
9079 /* Init headphone pin */
9080 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9081 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9082 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9083 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9084
9085 { } /* end */
9086};
9087
9088/* toggle speaker-output according to the hp-jack state */
9089static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9090{
9091 struct alc_spec *spec = codec->spec;
9092
9093 spec->autocfg.hp_pins[0] = 0x1a;
9094 spec->autocfg.speaker_pins[0] = 0x15;
9095}
9096
2880a867 9097static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
9098 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9099 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 9100 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
9101 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9102 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6 9103 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9104 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d1a991a6 9105 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 9106 { } /* end */
d1a991a6 9107};
2880a867 9108
d2fd4b09
TV
9109static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9110 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 9111 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
9112 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9113 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
9114 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9115 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9116 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9117 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d2fd4b09
TV
9118 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9119 { } /* end */
9120};
9121
e2757d5e
KY
9122static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9123 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9124 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9125 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9126 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9127 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9128 0x0d, 1, 0x0, HDA_OUTPUT),
9129 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9130 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9131 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9132 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9133 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
9134 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9135 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9136 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9137 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9138 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9139 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e2757d5e
KY
9140 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9141 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9142 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
e2757d5e 9143 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9144 { } /* end */
9145};
9146
eb4c41d3
TS
9147static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9148 /* Output mixers */
9149 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9150 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9151 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9152 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9153 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9154 HDA_OUTPUT),
9155 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9156 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9157 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9158 /* Output switches */
9159 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9160 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9161 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9162 /* Boost mixers */
5f99f86a
DH
9163 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9164 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
eb4c41d3
TS
9165 /* Input mixers */
9166 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9167 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9168 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9169 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9170 { } /* end */
9171};
9172
3e1647c5
GG
9173static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9174 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9175 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9176 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9177 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9178 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
3e1647c5
GG
9179 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9180 { } /* end */
9181};
9182
e2757d5e
KY
9183static struct hda_bind_ctls alc883_bind_cap_vol = {
9184 .ops = &snd_hda_bind_vol,
9185 .values = {
9186 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9187 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9188 0
9189 },
9190};
9191
9192static struct hda_bind_ctls alc883_bind_cap_switch = {
9193 .ops = &snd_hda_bind_sw,
9194 .values = {
9195 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9196 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9197 0
9198 },
9199};
9200
9201static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9202 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9203 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9204 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9205 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9206 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9207 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9208 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
4953550a
TI
9209 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9210 { } /* end */
9211};
df694daa 9212
4953550a
TI
9213static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9214 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9215 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9216 {
9217 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9218 /* .name = "Capture Source", */
9219 .name = "Input Source",
9220 .count = 1,
9221 .info = alc_mux_enum_info,
9222 .get = alc_mux_enum_get,
9223 .put = alc_mux_enum_put,
9224 },
9225 { } /* end */
9226};
9c7f852e 9227
4953550a
TI
9228static struct snd_kcontrol_new alc883_chmode_mixer[] = {
9229 {
9230 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9231 .name = "Channel Mode",
9232 .info = alc_ch_mode_info,
9233 .get = alc_ch_mode_get,
9234 .put = alc_ch_mode_put,
9235 },
9236 { } /* end */
9c7f852e
TI
9237};
9238
a8848bd6 9239/* toggle speaker-output according to the hp-jack state */
4f5d1706 9240static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9241{
a9fd4f3f 9242 struct alc_spec *spec = codec->spec;
a8848bd6 9243
a9fd4f3f
TI
9244 spec->autocfg.hp_pins[0] = 0x15;
9245 spec->autocfg.speaker_pins[0] = 0x14;
9246 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
9247}
9248
a8848bd6
AS
9249static struct hda_verb alc883_mitac_verbs[] = {
9250 /* HP */
9251 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9252 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9253 /* Subwoofer */
9254 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9255 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9256
9257 /* enable unsolicited event */
9258 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9259 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9260
9261 { } /* end */
9262};
9263
a65cc60f 9264static struct hda_verb alc883_clevo_m540r_verbs[] = {
9265 /* HP */
9266 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9267 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9268 /* Int speaker */
9269 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9270
9271 /* enable unsolicited event */
9272 /*
9273 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9274 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9275 */
9276
9277 { } /* end */
9278};
9279
0c4cc443 9280static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9281 /* HP */
9282 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9283 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9284 /* Int speaker */
9285 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9286 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9287
9288 /* enable unsolicited event */
9289 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9290 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9291
9292 { } /* end */
9293};
9294
fb97dc67
J
9295static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9296 /* HP */
9297 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9298 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9299 /* Subwoofer */
9300 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9301 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9302
9303 /* enable unsolicited event */
9304 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9305
9306 { } /* end */
9307};
9308
c259249f 9309static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9310 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9311 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9312
9313 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9314 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9315
64a8be74
DH
9316/* Connect Line-Out side jack (SPDIF) to Side */
9317 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9318 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9319 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9320/* Connect Mic jack to CLFE */
9321 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9322 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9323 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9324/* Connect Line-in jack to Surround */
9325 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9326 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9327 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9328/* Connect HP out jack to Front */
9329 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9330 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9331 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9332
9333 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9334
9335 { } /* end */
9336};
9337
bc9f98a9
KY
9338static struct hda_verb alc883_lenovo_101e_verbs[] = {
9339 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9340 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9341 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9342 { } /* end */
9343};
9344
272a527c
KY
9345static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9346 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9347 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9348 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9349 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9350 { } /* end */
9351};
9352
9353static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9354 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9355 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9356 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9357 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9358 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9359 { } /* end */
9360};
9361
189609ae
KY
9362static struct hda_verb alc883_haier_w66_verbs[] = {
9363 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9364 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9365
9366 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9367
9368 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9369 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9370 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9371 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9372 { } /* end */
9373};
9374
e2757d5e
KY
9375static struct hda_verb alc888_lenovo_sky_verbs[] = {
9376 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9377 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9378 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9379 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9380 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9381 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9382 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9383 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9384 { } /* end */
9385};
9386
8718b700
HRK
9387static struct hda_verb alc888_6st_dell_verbs[] = {
9388 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9389 { }
9390};
9391
3e1647c5
GG
9392static struct hda_verb alc883_vaiott_verbs[] = {
9393 /* HP */
9394 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9395 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9396
9397 /* enable unsolicited event */
9398 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9399
9400 { } /* end */
9401};
9402
4f5d1706 9403static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9404{
a9fd4f3f 9405 struct alc_spec *spec = codec->spec;
8718b700 9406
a9fd4f3f
TI
9407 spec->autocfg.hp_pins[0] = 0x1b;
9408 spec->autocfg.speaker_pins[0] = 0x14;
9409 spec->autocfg.speaker_pins[1] = 0x16;
9410 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
9411}
9412
4723c022 9413static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9414 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9415 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9416 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9417 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9418 { } /* end */
5795b9e6
CM
9419};
9420
3ea0d7cf
HRK
9421/*
9422 * 2ch mode
9423 */
4723c022 9424static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9425 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9426 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9427 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9428 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9429 { } /* end */
8341de60
CM
9430};
9431
3ea0d7cf
HRK
9432/*
9433 * 4ch mode
9434 */
9435static struct hda_verb alc888_3st_hp_4ch_init[] = {
9436 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9437 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9438 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9439 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9440 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9441 { } /* end */
9442};
9443
9444/*
9445 * 6ch mode
9446 */
4723c022 9447static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9448 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9449 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9450 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9451 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9452 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9453 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9454 { } /* end */
8341de60
CM
9455};
9456
3ea0d7cf 9457static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9458 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9459 { 4, alc888_3st_hp_4ch_init },
4723c022 9460 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9461};
9462
272a527c
KY
9463/* toggle front-jack and RCA according to the hp-jack state */
9464static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9465{
864f92be 9466 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 9467
47fd830a
TI
9468 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9469 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9470 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9471 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
9472}
9473
9474/* toggle RCA according to the front-jack state */
9475static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9476{
864f92be 9477 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 9478
47fd830a
TI
9479 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9480 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 9481}
47fd830a 9482
272a527c
KY
9483static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9484 unsigned int res)
9485{
9486 if ((res >> 26) == ALC880_HP_EVENT)
9487 alc888_lenovo_ms7195_front_automute(codec);
9488 if ((res >> 26) == ALC880_FRONT_EVENT)
9489 alc888_lenovo_ms7195_rca_automute(codec);
9490}
9491
272a527c 9492/* toggle speaker-output according to the hp-jack state */
dc427170 9493static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
272a527c 9494{
a9fd4f3f 9495 struct alc_spec *spec = codec->spec;
272a527c 9496
a9fd4f3f
TI
9497 spec->autocfg.hp_pins[0] = 0x14;
9498 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
9499}
9500
ccc656ce 9501/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9502#define alc883_targa_init_hook alc882_targa_init_hook
9503#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9504
4f5d1706 9505static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9506{
a9fd4f3f
TI
9507 struct alc_spec *spec = codec->spec;
9508
9509 spec->autocfg.hp_pins[0] = 0x15;
9510 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
9511}
9512
9513static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9514{
a9fd4f3f 9515 alc_automute_amp(codec);
eeb43387 9516 alc88x_simple_mic_automute(codec);
0c4cc443
HRK
9517}
9518
9519static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9520 unsigned int res)
9521{
0c4cc443 9522 switch (res >> 26) {
0c4cc443 9523 case ALC880_MIC_EVENT:
eeb43387 9524 alc88x_simple_mic_automute(codec);
0c4cc443 9525 break;
a9fd4f3f
TI
9526 default:
9527 alc_automute_amp_unsol_event(codec, res);
9528 break;
0c4cc443 9529 }
368c7a95
J
9530}
9531
fb97dc67 9532/* toggle speaker-output according to the hp-jack state */
4f5d1706 9533static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9534{
a9fd4f3f 9535 struct alc_spec *spec = codec->spec;
fb97dc67 9536
a9fd4f3f
TI
9537 spec->autocfg.hp_pins[0] = 0x14;
9538 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9539}
9540
4f5d1706 9541static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9542{
a9fd4f3f 9543 struct alc_spec *spec = codec->spec;
189609ae 9544
a9fd4f3f
TI
9545 spec->autocfg.hp_pins[0] = 0x1b;
9546 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9547}
9548
bc9f98a9
KY
9549static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9550{
864f92be 9551 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9552
47fd830a
TI
9553 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9554 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9555}
9556
9557static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9558{
864f92be 9559 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9560
47fd830a
TI
9561 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9562 HDA_AMP_MUTE, bits);
9563 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9564 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9565}
9566
9567static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9568 unsigned int res)
9569{
9570 if ((res >> 26) == ALC880_HP_EVENT)
9571 alc883_lenovo_101e_all_automute(codec);
9572 if ((res >> 26) == ALC880_FRONT_EVENT)
9573 alc883_lenovo_101e_ispeaker_automute(codec);
9574}
9575
676a9b53 9576/* toggle speaker-output according to the hp-jack state */
4f5d1706 9577static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9578{
a9fd4f3f 9579 struct alc_spec *spec = codec->spec;
676a9b53 9580
a9fd4f3f
TI
9581 spec->autocfg.hp_pins[0] = 0x14;
9582 spec->autocfg.speaker_pins[0] = 0x15;
9583 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9584}
9585
d1a991a6
KY
9586static struct hda_verb alc883_acer_eapd_verbs[] = {
9587 /* HP Pin: output 0 (0x0c) */
9588 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9589 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9590 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9591 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9592 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9593 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9594 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9595 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9596 /* eanable EAPD on medion laptop */
9597 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9598 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9599 /* enable unsolicited event */
9600 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9601 { }
9602};
9603
4f5d1706 9604static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9605{
a9fd4f3f 9606 struct alc_spec *spec = codec->spec;
5795b9e6 9607
a9fd4f3f
TI
9608 spec->autocfg.hp_pins[0] = 0x1b;
9609 spec->autocfg.speaker_pins[0] = 0x14;
9610 spec->autocfg.speaker_pins[1] = 0x15;
9611 spec->autocfg.speaker_pins[2] = 0x16;
9612 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9613}
9614
4f5d1706 9615static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9616{
a9fd4f3f 9617 struct alc_spec *spec = codec->spec;
e2757d5e 9618
a9fd4f3f
TI
9619 spec->autocfg.hp_pins[0] = 0x1b;
9620 spec->autocfg.speaker_pins[0] = 0x14;
9621 spec->autocfg.speaker_pins[1] = 0x15;
9622 spec->autocfg.speaker_pins[2] = 0x16;
9623 spec->autocfg.speaker_pins[3] = 0x17;
9624 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9625}
9626
4f5d1706 9627static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9628{
9629 struct alc_spec *spec = codec->spec;
9630
9631 spec->autocfg.hp_pins[0] = 0x15;
9632 spec->autocfg.speaker_pins[0] = 0x14;
9633 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9634}
9635
e2757d5e
KY
9636static struct hda_verb alc888_asus_m90v_verbs[] = {
9637 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9638 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9639 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9640 /* enable unsolicited event */
9641 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9642 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9643 { } /* end */
9644};
9645
4f5d1706 9646static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9647{
a9fd4f3f 9648 struct alc_spec *spec = codec->spec;
e2757d5e 9649
a9fd4f3f
TI
9650 spec->autocfg.hp_pins[0] = 0x1b;
9651 spec->autocfg.speaker_pins[0] = 0x14;
9652 spec->autocfg.speaker_pins[1] = 0x15;
9653 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9654 spec->ext_mic.pin = 0x18;
9655 spec->int_mic.pin = 0x19;
9656 spec->ext_mic.mux_idx = 0;
9657 spec->int_mic.mux_idx = 1;
9658 spec->auto_mic = 1;
e2757d5e
KY
9659}
9660
9661static struct hda_verb alc888_asus_eee1601_verbs[] = {
9662 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9663 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9664 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9665 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9666 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9667 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9668 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9669 /* enable unsolicited event */
9670 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9671 { } /* end */
9672};
9673
e2757d5e
KY
9674static void alc883_eee1601_inithook(struct hda_codec *codec)
9675{
a9fd4f3f
TI
9676 struct alc_spec *spec = codec->spec;
9677
9678 spec->autocfg.hp_pins[0] = 0x14;
9679 spec->autocfg.speaker_pins[0] = 0x1b;
9680 alc_automute_pin(codec);
e2757d5e
KY
9681}
9682
eb4c41d3
TS
9683static struct hda_verb alc889A_mb31_verbs[] = {
9684 /* Init rear pin (used as headphone output) */
9685 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9686 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9687 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9688 /* Init line pin (used as output in 4ch and 6ch mode) */
9689 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9690 /* Init line 2 pin (used as headphone out by default) */
9691 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9692 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9693 { } /* end */
9694};
9695
9696/* Mute speakers according to the headphone jack state */
9697static void alc889A_mb31_automute(struct hda_codec *codec)
9698{
9699 unsigned int present;
9700
9701 /* Mute only in 2ch or 4ch mode */
9702 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9703 == 0x00) {
864f92be 9704 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9705 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9706 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9707 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9708 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9709 }
9710}
9711
9712static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9713{
9714 if ((res >> 26) == ALC880_HP_EVENT)
9715 alc889A_mb31_automute(codec);
9716}
9717
4953550a 9718
cb53c626 9719#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9720#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9721#endif
9722
def319f9 9723/* pcm configuration: identical with ALC880 */
4953550a
TI
9724#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9725#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9726#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9727#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9728
9729static hda_nid_t alc883_slave_dig_outs[] = {
9730 ALC1200_DIGOUT_NID, 0,
9731};
9732
9733static hda_nid_t alc1200_slave_dig_outs[] = {
9734 ALC883_DIGOUT_NID, 0,
9735};
9c7f852e
TI
9736
9737/*
9738 * configuration and preset
9739 */
ea734963 9740static const char * const alc882_models[ALC882_MODEL_LAST] = {
4953550a
TI
9741 [ALC882_3ST_DIG] = "3stack-dig",
9742 [ALC882_6ST_DIG] = "6stack-dig",
9743 [ALC882_ARIMA] = "arima",
9744 [ALC882_W2JC] = "w2jc",
9745 [ALC882_TARGA] = "targa",
9746 [ALC882_ASUS_A7J] = "asus-a7j",
9747 [ALC882_ASUS_A7M] = "asus-a7m",
9748 [ALC885_MACPRO] = "macpro",
9749 [ALC885_MB5] = "mb5",
e458b1fa 9750 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9751 [ALC885_MBA21] = "mba21",
4953550a
TI
9752 [ALC885_MBP3] = "mbp3",
9753 [ALC885_IMAC24] = "imac24",
4b7e1803 9754 [ALC885_IMAC91] = "imac91",
4953550a 9755 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9756 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9757 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9758 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9759 [ALC883_TARGA_DIG] = "targa-dig",
9760 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9761 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9762 [ALC883_ACER] = "acer",
2880a867 9763 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9764 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9765 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9766 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9767 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9768 [ALC883_MEDION] = "medion",
7ad7b218 9769 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9770 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9771 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9772 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9773 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9774 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9775 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9776 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9777 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9778 [ALC883_MITAC] = "mitac",
a65cc60f 9779 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9780 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9781 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9782 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9783 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9784 [ALC889A_INTEL] = "intel-alc889a",
9785 [ALC889_INTEL] = "intel-x58",
3ab90935 9786 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9787 [ALC889A_MB31] = "mb31",
3e1647c5 9788 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9789 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9790};
9791
4953550a
TI
9792static struct snd_pci_quirk alc882_cfg_tbl[] = {
9793 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9794
ac3e3741 9795 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9796 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9797 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9798 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9799 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9800 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9801 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9802 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9803 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9804 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9805 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9806 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9807 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9808 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9809 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9810 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9811 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9812 ALC888_ACER_ASPIRE_6530G),
cc374c47 9813 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9814 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9815 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9816 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9817 /* default Acer -- disabled as it causes more problems.
9818 * model=auto should work fine now
9819 */
9820 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9821
5795b9e6 9822 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9823
febe3375 9824 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9825 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9826 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9827 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9828 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9829 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9830
9831 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9832 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9833 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9834 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9835 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9836 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9837 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9838 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9839 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9840 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9841 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9842
9843 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9844 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9845 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9846 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9847 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9848 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9849 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9850 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9851 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9852
6f3bf657 9853 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9854 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9855 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9856 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9857 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9858 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9859 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9860 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9861 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9862 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9863 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9864 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9865 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9866 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9867 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9868 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9869 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9870 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9871 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9872 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9873 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9874 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9875 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9876 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9877 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9878 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9879 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9880 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9881 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9882 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9883 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9884
ac3e3741 9885 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9886 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9887 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9888 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9889 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9890 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9891 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9892 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9893 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9894 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9895 ALC883_FUJITSU_PI2515),
bfb53037 9896 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9897 ALC888_FUJITSU_XA3530),
272a527c 9898 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9899 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9900 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9901 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9902 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
959973b9 9903 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9904 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9905 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9906
17bba1b7
J
9907 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9908 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9909 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9910 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9911 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9912 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9913 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9914
4953550a 9915 {}
f3cd3f5d
WF
9916};
9917
4953550a
TI
9918/* codec SSID table for Intel Mac */
9919static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9920 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9921 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9922 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9923 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9924 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9925 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9926 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 9927 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 9928 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 9929 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 9930 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
9931 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9932 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9933 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9934 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9935 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 9936 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
9937 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9938 * so apparently no perfect solution yet
4953550a
TI
9939 */
9940 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9941 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9942 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9943 {} /* terminator */
b25c9da1
WF
9944};
9945
4953550a
TI
9946static struct alc_config_preset alc882_presets[] = {
9947 [ALC882_3ST_DIG] = {
9948 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9949 .init_verbs = { alc882_base_init_verbs,
9950 alc882_adc1_init_verbs },
4953550a
TI
9951 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9952 .dac_nids = alc882_dac_nids,
9953 .dig_out_nid = ALC882_DIGOUT_NID,
9954 .dig_in_nid = ALC882_DIGIN_NID,
9955 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9956 .channel_mode = alc882_ch_modes,
9957 .need_dac_fix = 1,
9958 .input_mux = &alc882_capture_source,
9959 },
9960 [ALC882_6ST_DIG] = {
9961 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9962 .init_verbs = { alc882_base_init_verbs,
9963 alc882_adc1_init_verbs },
4953550a
TI
9964 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9965 .dac_nids = alc882_dac_nids,
9966 .dig_out_nid = ALC882_DIGOUT_NID,
9967 .dig_in_nid = ALC882_DIGIN_NID,
9968 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9969 .channel_mode = alc882_sixstack_modes,
9970 .input_mux = &alc882_capture_source,
9971 },
9972 [ALC882_ARIMA] = {
9973 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9974 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9975 alc882_eapd_verbs },
4953550a
TI
9976 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9977 .dac_nids = alc882_dac_nids,
9978 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9979 .channel_mode = alc882_sixstack_modes,
9980 .input_mux = &alc882_capture_source,
9981 },
9982 [ALC882_W2JC] = {
9983 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9984 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9985 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
9986 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9987 .dac_nids = alc882_dac_nids,
9988 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9989 .channel_mode = alc880_threestack_modes,
9990 .need_dac_fix = 1,
9991 .input_mux = &alc882_capture_source,
9992 .dig_out_nid = ALC882_DIGOUT_NID,
9993 },
76e6f5a9
RH
9994 [ALC885_MBA21] = {
9995 .mixers = { alc885_mba21_mixer },
9996 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9997 .num_dacs = 2,
9998 .dac_nids = alc882_dac_nids,
9999 .channel_mode = alc885_mba21_ch_modes,
10000 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10001 .input_mux = &alc882_capture_source,
10002 .unsol_event = alc_automute_amp_unsol_event,
10003 .setup = alc885_mba21_setup,
10004 .init_hook = alc_automute_amp,
10005 },
4953550a
TI
10006 [ALC885_MBP3] = {
10007 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10008 .init_verbs = { alc885_mbp3_init_verbs,
10009 alc880_gpio1_init_verbs },
be0ae923 10010 .num_dacs = 2,
4953550a 10011 .dac_nids = alc882_dac_nids,
be0ae923
TI
10012 .hp_nid = 0x04,
10013 .channel_mode = alc885_mbp_4ch_modes,
10014 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
10015 .input_mux = &alc882_capture_source,
10016 .dig_out_nid = ALC882_DIGOUT_NID,
10017 .dig_in_nid = ALC882_DIGIN_NID,
10018 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10019 .setup = alc885_mbp3_setup,
10020 .init_hook = alc_automute_amp,
4953550a
TI
10021 },
10022 [ALC885_MB5] = {
10023 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10024 .init_verbs = { alc885_mb5_init_verbs,
10025 alc880_gpio1_init_verbs },
10026 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10027 .dac_nids = alc882_dac_nids,
10028 .channel_mode = alc885_mb5_6ch_modes,
10029 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10030 .input_mux = &mb5_capture_source,
10031 .dig_out_nid = ALC882_DIGOUT_NID,
10032 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10033 .unsol_event = alc_automute_amp_unsol_event,
10034 .setup = alc885_mb5_setup,
10035 .init_hook = alc_automute_amp,
4953550a 10036 },
e458b1fa
LY
10037 [ALC885_MACMINI3] = {
10038 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10039 .init_verbs = { alc885_macmini3_init_verbs,
10040 alc880_gpio1_init_verbs },
10041 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10042 .dac_nids = alc882_dac_nids,
10043 .channel_mode = alc885_macmini3_6ch_modes,
10044 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10045 .input_mux = &macmini3_capture_source,
10046 .dig_out_nid = ALC882_DIGOUT_NID,
10047 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10048 .unsol_event = alc_automute_amp_unsol_event,
10049 .setup = alc885_macmini3_setup,
10050 .init_hook = alc_automute_amp,
e458b1fa 10051 },
4953550a
TI
10052 [ALC885_MACPRO] = {
10053 .mixers = { alc882_macpro_mixer },
10054 .init_verbs = { alc882_macpro_init_verbs },
10055 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10056 .dac_nids = alc882_dac_nids,
10057 .dig_out_nid = ALC882_DIGOUT_NID,
10058 .dig_in_nid = ALC882_DIGIN_NID,
10059 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10060 .channel_mode = alc882_ch_modes,
10061 .input_mux = &alc882_capture_source,
10062 .init_hook = alc885_macpro_init_hook,
10063 },
10064 [ALC885_IMAC24] = {
10065 .mixers = { alc885_imac24_mixer },
10066 .init_verbs = { alc885_imac24_init_verbs },
10067 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10068 .dac_nids = alc882_dac_nids,
10069 .dig_out_nid = ALC882_DIGOUT_NID,
10070 .dig_in_nid = ALC882_DIGIN_NID,
10071 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10072 .channel_mode = alc882_ch_modes,
10073 .input_mux = &alc882_capture_source,
10074 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 10075 .setup = alc885_imac24_setup,
4953550a
TI
10076 .init_hook = alc885_imac24_init_hook,
10077 },
4b7e1803 10078 [ALC885_IMAC91] = {
b7cccc52 10079 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
10080 .init_verbs = { alc885_imac91_init_verbs,
10081 alc880_gpio1_init_verbs },
10082 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10083 .dac_nids = alc882_dac_nids,
b7cccc52
JM
10084 .channel_mode = alc885_mba21_ch_modes,
10085 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10086 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
10087 .dig_out_nid = ALC882_DIGOUT_NID,
10088 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10089 .unsol_event = alc_automute_amp_unsol_event,
10090 .setup = alc885_imac91_setup,
10091 .init_hook = alc_automute_amp,
4b7e1803 10092 },
4953550a
TI
10093 [ALC882_TARGA] = {
10094 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 10095 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 10096 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
10097 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10098 .dac_nids = alc882_dac_nids,
10099 .dig_out_nid = ALC882_DIGOUT_NID,
10100 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10101 .adc_nids = alc882_adc_nids,
10102 .capsrc_nids = alc882_capsrc_nids,
10103 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10104 .channel_mode = alc882_3ST_6ch_modes,
10105 .need_dac_fix = 1,
10106 .input_mux = &alc882_capture_source,
10107 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
10108 .setup = alc882_targa_setup,
10109 .init_hook = alc882_targa_automute,
4953550a
TI
10110 },
10111 [ALC882_ASUS_A7J] = {
10112 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10113 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10114 alc882_asus_a7j_verbs},
4953550a
TI
10115 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10116 .dac_nids = alc882_dac_nids,
10117 .dig_out_nid = ALC882_DIGOUT_NID,
10118 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10119 .adc_nids = alc882_adc_nids,
10120 .capsrc_nids = alc882_capsrc_nids,
10121 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10122 .channel_mode = alc882_3ST_6ch_modes,
10123 .need_dac_fix = 1,
10124 .input_mux = &alc882_capture_source,
10125 },
10126 [ALC882_ASUS_A7M] = {
10127 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10128 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10129 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10130 alc882_asus_a7m_verbs },
10131 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10132 .dac_nids = alc882_dac_nids,
10133 .dig_out_nid = ALC882_DIGOUT_NID,
10134 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10135 .channel_mode = alc880_threestack_modes,
10136 .need_dac_fix = 1,
10137 .input_mux = &alc882_capture_source,
10138 },
9c7f852e
TI
10139 [ALC883_3ST_2ch_DIG] = {
10140 .mixers = { alc883_3ST_2ch_mixer },
10141 .init_verbs = { alc883_init_verbs },
10142 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10143 .dac_nids = alc883_dac_nids,
10144 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10145 .dig_in_nid = ALC883_DIGIN_NID,
10146 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10147 .channel_mode = alc883_3ST_2ch_modes,
10148 .input_mux = &alc883_capture_source,
10149 },
10150 [ALC883_3ST_6ch_DIG] = {
10151 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10152 .init_verbs = { alc883_init_verbs },
10153 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10154 .dac_nids = alc883_dac_nids,
10155 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10156 .dig_in_nid = ALC883_DIGIN_NID,
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 },
9c7f852e
TI
10162 [ALC883_3ST_6ch] = {
10163 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10164 .init_verbs = { alc883_init_verbs },
10165 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10166 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10167 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10168 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10169 .need_dac_fix = 1,
9c7f852e 10170 .input_mux = &alc883_capture_source,
f12ab1e0 10171 },
17bba1b7
J
10172 [ALC883_3ST_6ch_INTEL] = {
10173 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10174 .init_verbs = { alc883_init_verbs },
10175 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10176 .dac_nids = alc883_dac_nids,
10177 .dig_out_nid = ALC883_DIGOUT_NID,
10178 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10179 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10180 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10181 .channel_mode = alc883_3ST_6ch_intel_modes,
10182 .need_dac_fix = 1,
10183 .input_mux = &alc883_3stack_6ch_intel,
10184 },
87a8c370
JK
10185 [ALC889A_INTEL] = {
10186 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10187 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10188 alc_hp15_unsol_verbs },
87a8c370
JK
10189 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10190 .dac_nids = alc883_dac_nids,
10191 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10192 .adc_nids = alc889_adc_nids,
10193 .dig_out_nid = ALC883_DIGOUT_NID,
10194 .dig_in_nid = ALC883_DIGIN_NID,
10195 .slave_dig_outs = alc883_slave_dig_outs,
10196 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10197 .channel_mode = alc889_8ch_intel_modes,
10198 .capsrc_nids = alc889_capsrc_nids,
10199 .input_mux = &alc889_capture_source,
4f5d1706
TI
10200 .setup = alc889_automute_setup,
10201 .init_hook = alc_automute_amp,
6732bd0d 10202 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10203 .need_dac_fix = 1,
10204 },
10205 [ALC889_INTEL] = {
10206 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10207 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10208 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10209 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10210 .dac_nids = alc883_dac_nids,
10211 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10212 .adc_nids = alc889_adc_nids,
10213 .dig_out_nid = ALC883_DIGOUT_NID,
10214 .dig_in_nid = ALC883_DIGIN_NID,
10215 .slave_dig_outs = alc883_slave_dig_outs,
10216 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10217 .channel_mode = alc889_8ch_intel_modes,
10218 .capsrc_nids = alc889_capsrc_nids,
10219 .input_mux = &alc889_capture_source,
4f5d1706 10220 .setup = alc889_automute_setup,
6732bd0d
WF
10221 .init_hook = alc889_intel_init_hook,
10222 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10223 .need_dac_fix = 1,
10224 },
9c7f852e
TI
10225 [ALC883_6ST_DIG] = {
10226 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10227 .init_verbs = { alc883_init_verbs },
10228 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10229 .dac_nids = alc883_dac_nids,
10230 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10231 .dig_in_nid = ALC883_DIGIN_NID,
10232 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10233 .channel_mode = alc883_sixstack_modes,
10234 .input_mux = &alc883_capture_source,
10235 },
ccc656ce 10236 [ALC883_TARGA_DIG] = {
c259249f 10237 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10238 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10239 alc883_targa_verbs},
ccc656ce
KY
10240 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10241 .dac_nids = alc883_dac_nids,
10242 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10243 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10244 .channel_mode = alc883_3ST_6ch_modes,
10245 .need_dac_fix = 1,
10246 .input_mux = &alc883_capture_source,
c259249f 10247 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10248 .setup = alc882_targa_setup,
10249 .init_hook = alc882_targa_automute,
ccc656ce
KY
10250 },
10251 [ALC883_TARGA_2ch_DIG] = {
c259249f 10252 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10253 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10254 alc883_targa_verbs},
ccc656ce
KY
10255 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10256 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10257 .adc_nids = alc883_adc_nids_alt,
10258 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10259 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10260 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10261 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10262 .channel_mode = alc883_3ST_2ch_modes,
10263 .input_mux = &alc883_capture_source,
c259249f 10264 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10265 .setup = alc882_targa_setup,
10266 .init_hook = alc882_targa_automute,
ccc656ce 10267 },
64a8be74 10268 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10269 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10270 alc883_chmode_mixer },
64a8be74 10271 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10272 alc883_targa_verbs },
64a8be74
DH
10273 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10274 .dac_nids = alc883_dac_nids,
10275 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10276 .adc_nids = alc883_adc_nids_rev,
10277 .capsrc_nids = alc883_capsrc_nids_rev,
10278 .dig_out_nid = ALC883_DIGOUT_NID,
10279 .dig_in_nid = ALC883_DIGIN_NID,
10280 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10281 .channel_mode = alc883_4ST_8ch_modes,
10282 .need_dac_fix = 1,
10283 .input_mux = &alc883_capture_source,
c259249f 10284 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10285 .setup = alc882_targa_setup,
10286 .init_hook = alc882_targa_automute,
64a8be74 10287 },
bab282b9 10288 [ALC883_ACER] = {
676a9b53 10289 .mixers = { alc883_base_mixer },
bab282b9
VA
10290 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10291 * and the headphone jack. Turn this on and rely on the
10292 * standard mute methods whenever the user wants to turn
10293 * these outputs off.
10294 */
10295 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10296 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10297 .dac_nids = alc883_dac_nids,
bab282b9
VA
10298 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10299 .channel_mode = alc883_3ST_2ch_modes,
10300 .input_mux = &alc883_capture_source,
10301 },
2880a867 10302 [ALC883_ACER_ASPIRE] = {
676a9b53 10303 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10304 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10305 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10306 .dac_nids = alc883_dac_nids,
10307 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10308 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10309 .channel_mode = alc883_3ST_2ch_modes,
10310 .input_mux = &alc883_capture_source,
a9fd4f3f 10311 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10312 .setup = alc883_acer_aspire_setup,
10313 .init_hook = alc_automute_amp,
d1a991a6 10314 },
5b2d1eca 10315 [ALC888_ACER_ASPIRE_4930G] = {
460c92fa 10316 .mixers = { alc888_acer_aspire_4930g_mixer,
5b2d1eca
VP
10317 alc883_chmode_mixer },
10318 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10319 alc888_acer_aspire_4930g_verbs },
10320 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10321 .dac_nids = alc883_dac_nids,
10322 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10323 .adc_nids = alc883_adc_nids_rev,
10324 .capsrc_nids = alc883_capsrc_nids_rev,
10325 .dig_out_nid = ALC883_DIGOUT_NID,
10326 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10327 .channel_mode = alc883_3ST_6ch_modes,
10328 .need_dac_fix = 1,
973b8cb0 10329 .const_channel_count = 6,
5b2d1eca 10330 .num_mux_defs =
ef8ef5fb
VP
10331 ARRAY_SIZE(alc888_2_capture_sources),
10332 .input_mux = alc888_2_capture_sources,
d2fd4b09 10333 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10334 .setup = alc888_acer_aspire_4930g_setup,
10335 .init_hook = alc_automute_amp,
d2fd4b09
TV
10336 },
10337 [ALC888_ACER_ASPIRE_6530G] = {
10338 .mixers = { alc888_acer_aspire_6530_mixer },
10339 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10340 alc888_acer_aspire_6530g_verbs },
10341 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10342 .dac_nids = alc883_dac_nids,
10343 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10344 .adc_nids = alc883_adc_nids_rev,
10345 .capsrc_nids = alc883_capsrc_nids_rev,
10346 .dig_out_nid = ALC883_DIGOUT_NID,
10347 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10348 .channel_mode = alc883_3ST_2ch_modes,
10349 .num_mux_defs =
10350 ARRAY_SIZE(alc888_2_capture_sources),
10351 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 10352 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10353 .setup = alc888_acer_aspire_6530g_setup,
10354 .init_hook = alc_automute_amp,
5b2d1eca 10355 },
3b315d70 10356 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10357 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10358 alc883_chmode_mixer },
10359 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10360 alc889_acer_aspire_8930g_verbs,
10361 alc889_eapd_verbs},
3b315d70
HM
10362 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10363 .dac_nids = alc883_dac_nids,
018df418
HM
10364 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10365 .adc_nids = alc889_adc_nids,
10366 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10367 .dig_out_nid = ALC883_DIGOUT_NID,
10368 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10369 .channel_mode = alc883_3ST_6ch_modes,
10370 .need_dac_fix = 1,
10371 .const_channel_count = 6,
10372 .num_mux_defs =
018df418
HM
10373 ARRAY_SIZE(alc889_capture_sources),
10374 .input_mux = alc889_capture_sources,
3b315d70 10375 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10376 .setup = alc889_acer_aspire_8930g_setup,
10377 .init_hook = alc_automute_amp,
f5de24b0 10378#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10379 .power_hook = alc_power_eapd,
f5de24b0 10380#endif
3b315d70 10381 },
fc86f954
DK
10382 [ALC888_ACER_ASPIRE_7730G] = {
10383 .mixers = { alc883_3ST_6ch_mixer,
10384 alc883_chmode_mixer },
10385 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10386 alc888_acer_aspire_7730G_verbs },
10387 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10388 .dac_nids = alc883_dac_nids,
10389 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10390 .adc_nids = alc883_adc_nids_rev,
10391 .capsrc_nids = alc883_capsrc_nids_rev,
10392 .dig_out_nid = ALC883_DIGOUT_NID,
10393 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10394 .channel_mode = alc883_3ST_6ch_modes,
10395 .need_dac_fix = 1,
10396 .const_channel_count = 6,
10397 .input_mux = &alc883_capture_source,
10398 .unsol_event = alc_automute_amp_unsol_event,
d9477207 10399 .setup = alc888_acer_aspire_7730g_setup,
fc86f954
DK
10400 .init_hook = alc_automute_amp,
10401 },
c07584c8
TD
10402 [ALC883_MEDION] = {
10403 .mixers = { alc883_fivestack_mixer,
10404 alc883_chmode_mixer },
10405 .init_verbs = { alc883_init_verbs,
b373bdeb 10406 alc883_medion_eapd_verbs },
c07584c8
TD
10407 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10408 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10409 .adc_nids = alc883_adc_nids_alt,
10410 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10411 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10412 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10413 .channel_mode = alc883_sixstack_modes,
10414 .input_mux = &alc883_capture_source,
b373bdeb 10415 },
7ad7b218
MC
10416 [ALC883_MEDION_WIM2160] = {
10417 .mixers = { alc883_medion_wim2160_mixer },
10418 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10419 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10420 .dac_nids = alc883_dac_nids,
10421 .dig_out_nid = ALC883_DIGOUT_NID,
10422 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10423 .adc_nids = alc883_adc_nids,
10424 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10425 .channel_mode = alc883_3ST_2ch_modes,
10426 .input_mux = &alc883_capture_source,
10427 .unsol_event = alc_automute_amp_unsol_event,
10428 .setup = alc883_medion_wim2160_setup,
10429 .init_hook = alc_automute_amp,
10430 },
b373bdeb 10431 [ALC883_LAPTOP_EAPD] = {
676a9b53 10432 .mixers = { alc883_base_mixer },
b373bdeb
AN
10433 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10434 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10435 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10436 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10437 .channel_mode = alc883_3ST_2ch_modes,
10438 .input_mux = &alc883_capture_source,
10439 },
a65cc60f 10440 [ALC883_CLEVO_M540R] = {
10441 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10442 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10443 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10444 .dac_nids = alc883_dac_nids,
10445 .dig_out_nid = ALC883_DIGOUT_NID,
10446 .dig_in_nid = ALC883_DIGIN_NID,
10447 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10448 .channel_mode = alc883_3ST_6ch_clevo_modes,
10449 .need_dac_fix = 1,
10450 .input_mux = &alc883_capture_source,
10451 /* This machine has the hardware HP auto-muting, thus
10452 * we need no software mute via unsol event
10453 */
10454 },
0c4cc443
HRK
10455 [ALC883_CLEVO_M720] = {
10456 .mixers = { alc883_clevo_m720_mixer },
10457 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10458 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10459 .dac_nids = alc883_dac_nids,
10460 .dig_out_nid = ALC883_DIGOUT_NID,
10461 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10462 .channel_mode = alc883_3ST_2ch_modes,
10463 .input_mux = &alc883_capture_source,
0c4cc443 10464 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10465 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10466 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10467 },
bc9f98a9
KY
10468 [ALC883_LENOVO_101E_2ch] = {
10469 .mixers = { alc883_lenovo_101e_2ch_mixer},
10470 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10471 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10472 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10473 .adc_nids = alc883_adc_nids_alt,
10474 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10475 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10476 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10477 .channel_mode = alc883_3ST_2ch_modes,
10478 .input_mux = &alc883_lenovo_101e_capture_source,
10479 .unsol_event = alc883_lenovo_101e_unsol_event,
10480 .init_hook = alc883_lenovo_101e_all_automute,
10481 },
272a527c
KY
10482 [ALC883_LENOVO_NB0763] = {
10483 .mixers = { alc883_lenovo_nb0763_mixer },
10484 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10485 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10486 .dac_nids = alc883_dac_nids,
272a527c
KY
10487 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10488 .channel_mode = alc883_3ST_2ch_modes,
10489 .need_dac_fix = 1,
10490 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 10491 .unsol_event = alc_automute_amp_unsol_event,
dc427170 10492 .setup = alc883_lenovo_nb0763_setup,
4f5d1706 10493 .init_hook = alc_automute_amp,
272a527c
KY
10494 },
10495 [ALC888_LENOVO_MS7195_DIG] = {
10496 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10497 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10498 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10499 .dac_nids = alc883_dac_nids,
10500 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10501 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10502 .channel_mode = alc883_3ST_6ch_modes,
10503 .need_dac_fix = 1,
10504 .input_mux = &alc883_capture_source,
10505 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10506 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
10507 },
10508 [ALC883_HAIER_W66] = {
c259249f 10509 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10510 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10511 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10512 .dac_nids = alc883_dac_nids,
10513 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10514 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10515 .channel_mode = alc883_3ST_2ch_modes,
10516 .input_mux = &alc883_capture_source,
a9fd4f3f 10517 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10518 .setup = alc883_haier_w66_setup,
10519 .init_hook = alc_automute_amp,
eea6419e 10520 },
4723c022 10521 [ALC888_3ST_HP] = {
eea6419e 10522 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10523 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10524 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10525 .dac_nids = alc883_dac_nids,
4723c022
CM
10526 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10527 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10528 .need_dac_fix = 1,
10529 .input_mux = &alc883_capture_source,
a9fd4f3f 10530 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10531 .setup = alc888_3st_hp_setup,
10532 .init_hook = alc_automute_amp,
8341de60 10533 },
5795b9e6 10534 [ALC888_6ST_DELL] = {
f24dbdc6 10535 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10536 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10537 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10538 .dac_nids = alc883_dac_nids,
10539 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10540 .dig_in_nid = ALC883_DIGIN_NID,
10541 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10542 .channel_mode = alc883_sixstack_modes,
10543 .input_mux = &alc883_capture_source,
a9fd4f3f 10544 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10545 .setup = alc888_6st_dell_setup,
10546 .init_hook = alc_automute_amp,
5795b9e6 10547 },
a8848bd6
AS
10548 [ALC883_MITAC] = {
10549 .mixers = { alc883_mitac_mixer },
10550 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10551 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10552 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10553 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10554 .channel_mode = alc883_3ST_2ch_modes,
10555 .input_mux = &alc883_capture_source,
a9fd4f3f 10556 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10557 .setup = alc883_mitac_setup,
10558 .init_hook = alc_automute_amp,
a8848bd6 10559 },
fb97dc67
J
10560 [ALC883_FUJITSU_PI2515] = {
10561 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10562 .init_verbs = { alc883_init_verbs,
10563 alc883_2ch_fujitsu_pi2515_verbs},
10564 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10565 .dac_nids = alc883_dac_nids,
10566 .dig_out_nid = ALC883_DIGOUT_NID,
10567 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10568 .channel_mode = alc883_3ST_2ch_modes,
10569 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10570 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10571 .setup = alc883_2ch_fujitsu_pi2515_setup,
10572 .init_hook = alc_automute_amp,
fb97dc67 10573 },
ef8ef5fb
VP
10574 [ALC888_FUJITSU_XA3530] = {
10575 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10576 .init_verbs = { alc883_init_verbs,
10577 alc888_fujitsu_xa3530_verbs },
10578 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10579 .dac_nids = alc883_dac_nids,
10580 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10581 .adc_nids = alc883_adc_nids_rev,
10582 .capsrc_nids = alc883_capsrc_nids_rev,
10583 .dig_out_nid = ALC883_DIGOUT_NID,
10584 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10585 .channel_mode = alc888_4ST_8ch_intel_modes,
10586 .num_mux_defs =
10587 ARRAY_SIZE(alc888_2_capture_sources),
10588 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10589 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10590 .setup = alc888_fujitsu_xa3530_setup,
10591 .init_hook = alc_automute_amp,
ef8ef5fb 10592 },
e2757d5e
KY
10593 [ALC888_LENOVO_SKY] = {
10594 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10595 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10596 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10597 .dac_nids = alc883_dac_nids,
10598 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10599 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10600 .channel_mode = alc883_sixstack_modes,
10601 .need_dac_fix = 1,
10602 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10603 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10604 .setup = alc888_lenovo_sky_setup,
10605 .init_hook = alc_automute_amp,
e2757d5e
KY
10606 },
10607 [ALC888_ASUS_M90V] = {
10608 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10609 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10610 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10611 .dac_nids = alc883_dac_nids,
10612 .dig_out_nid = ALC883_DIGOUT_NID,
10613 .dig_in_nid = ALC883_DIGIN_NID,
10614 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10615 .channel_mode = alc883_3ST_6ch_modes,
10616 .need_dac_fix = 1,
10617 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10618 .unsol_event = alc_sku_unsol_event,
10619 .setup = alc883_mode2_setup,
10620 .init_hook = alc_inithook,
e2757d5e
KY
10621 },
10622 [ALC888_ASUS_EEE1601] = {
10623 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10624 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10625 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10626 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10627 .dac_nids = alc883_dac_nids,
10628 .dig_out_nid = ALC883_DIGOUT_NID,
10629 .dig_in_nid = ALC883_DIGIN_NID,
10630 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10631 .channel_mode = alc883_3ST_2ch_modes,
10632 .need_dac_fix = 1,
10633 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10634 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10635 .init_hook = alc883_eee1601_inithook,
10636 },
3ab90935
WF
10637 [ALC1200_ASUS_P5Q] = {
10638 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10639 .init_verbs = { alc883_init_verbs },
10640 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10641 .dac_nids = alc883_dac_nids,
10642 .dig_out_nid = ALC1200_DIGOUT_NID,
10643 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10644 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10645 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10646 .channel_mode = alc883_sixstack_modes,
10647 .input_mux = &alc883_capture_source,
10648 },
eb4c41d3
TS
10649 [ALC889A_MB31] = {
10650 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10651 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10652 alc880_gpio1_init_verbs },
10653 .adc_nids = alc883_adc_nids,
10654 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10655 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10656 .dac_nids = alc883_dac_nids,
10657 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10658 .channel_mode = alc889A_mb31_6ch_modes,
10659 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10660 .input_mux = &alc889A_mb31_capture_source,
10661 .dig_out_nid = ALC883_DIGOUT_NID,
10662 .unsol_event = alc889A_mb31_unsol_event,
10663 .init_hook = alc889A_mb31_automute,
10664 },
3e1647c5
GG
10665 [ALC883_SONY_VAIO_TT] = {
10666 .mixers = { alc883_vaiott_mixer },
10667 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10668 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10669 .dac_nids = alc883_dac_nids,
10670 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10671 .channel_mode = alc883_3ST_2ch_modes,
10672 .input_mux = &alc883_capture_source,
10673 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10674 .setup = alc883_vaiott_setup,
10675 .init_hook = alc_automute_amp,
3e1647c5 10676 },
9c7f852e
TI
10677};
10678
10679
4953550a
TI
10680/*
10681 * Pin config fixes
10682 */
10683enum {
954a29c8 10684 PINFIX_ABIT_AW9D_MAX,
32eea388 10685 PINFIX_LENOVO_Y530,
954a29c8 10686 PINFIX_PB_M5210,
c3d226ab 10687 PINFIX_ACER_ASPIRE_7736,
4953550a
TI
10688};
10689
f8f25ba3
TI
10690static const struct alc_fixup alc882_fixups[] = {
10691 [PINFIX_ABIT_AW9D_MAX] = {
b5bfbc67
TI
10692 .type = ALC_FIXUP_PINS,
10693 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
10694 { 0x15, 0x01080104 }, /* side */
10695 { 0x16, 0x01011012 }, /* rear */
10696 { 0x17, 0x01016011 }, /* clfe */
10697 { }
10698 }
f8f25ba3 10699 },
32eea388
DH
10700 [PINFIX_LENOVO_Y530] = {
10701 .type = ALC_FIXUP_PINS,
10702 .v.pins = (const struct alc_pincfg[]) {
10703 { 0x15, 0x99130112 }, /* rear int speakers */
10704 { 0x16, 0x99130111 }, /* subwoofer */
10705 { }
10706 }
10707 },
954a29c8 10708 [PINFIX_PB_M5210] = {
b5bfbc67
TI
10709 .type = ALC_FIXUP_VERBS,
10710 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
10711 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10712 {}
10713 }
954a29c8 10714 },
c3d226ab 10715 [PINFIX_ACER_ASPIRE_7736] = {
b5bfbc67
TI
10716 .type = ALC_FIXUP_SKU,
10717 .v.sku = ALC_FIXUP_SKU_IGNORE,
c3d226ab 10718 },
4953550a
TI
10719};
10720
f8f25ba3 10721static struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10722 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
32eea388 10723 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
4953550a 10724 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
c3d226ab 10725 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
4953550a
TI
10726 {}
10727};
10728
9c7f852e
TI
10729/*
10730 * BIOS auto configuration
10731 */
05f5f477
TI
10732static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10733 const struct auto_pin_cfg *cfg)
10734{
10735 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10736}
10737
4953550a 10738static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10739 hda_nid_t nid, int pin_type,
489008cd 10740 hda_nid_t dac)
9c7f852e 10741{
f12ab1e0
TI
10742 int idx;
10743
489008cd 10744 /* set as output */
f6c7e546 10745 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10746
10747 if (dac == 0x25)
9c7f852e 10748 idx = 4;
489008cd
TI
10749 else if (dac >= 0x02 && dac <= 0x05)
10750 idx = dac - 2;
f9700d5a 10751 else
489008cd 10752 return;
9c7f852e 10753 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
10754}
10755
4953550a 10756static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10757{
10758 struct alc_spec *spec = codec->spec;
10759 int i;
10760
10761 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10762 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10763 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10764 if (nid)
4953550a 10765 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 10766 spec->multiout.dac_nids[i]);
9c7f852e
TI
10767 }
10768}
10769
4953550a 10770static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10771{
10772 struct alc_spec *spec = codec->spec;
489008cd 10773 hda_nid_t pin, dac;
5855fb80 10774 int i;
9c7f852e 10775
5855fb80
TI
10776 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
10777 pin = spec->autocfg.hp_pins[i];
10778 if (!pin)
10779 break;
489008cd
TI
10780 dac = spec->multiout.hp_nid;
10781 if (!dac)
10782 dac = spec->multiout.dac_nids[0]; /* to front */
10783 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10784 }
5855fb80
TI
10785 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
10786 pin = spec->autocfg.speaker_pins[i];
10787 if (!pin)
10788 break;
489008cd
TI
10789 dac = spec->multiout.extra_out_nid[0];
10790 if (!dac)
10791 dac = spec->multiout.dac_nids[0]; /* to front */
10792 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10793 }
9c7f852e
TI
10794}
10795
4953550a 10796static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10797{
10798 struct alc_spec *spec = codec->spec;
66ceeb6b 10799 struct auto_pin_cfg *cfg = &spec->autocfg;
9c7f852e
TI
10800 int i;
10801
66ceeb6b
TI
10802 for (i = 0; i < cfg->num_inputs; i++) {
10803 hda_nid_t nid = cfg->inputs[i].pin;
30ea098f 10804 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
4953550a
TI
10805 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10806 snd_hda_codec_write(codec, nid, 0,
10807 AC_VERB_SET_AMP_GAIN_MUTE,
10808 AMP_OUT_MUTE);
10809 }
10810}
10811
10812static void alc882_auto_init_input_src(struct hda_codec *codec)
10813{
10814 struct alc_spec *spec = codec->spec;
10815 int c;
10816
10817 for (c = 0; c < spec->num_adc_nids; c++) {
10818 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10819 hda_nid_t nid = spec->capsrc_nids[c];
10820 unsigned int mux_idx;
10821 const struct hda_input_mux *imux;
10822 int conns, mute, idx, item;
10823
10824 conns = snd_hda_get_connections(codec, nid, conn_list,
10825 ARRAY_SIZE(conn_list));
10826 if (conns < 0)
10827 continue;
10828 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10829 imux = &spec->input_mux[mux_idx];
5311114d
TI
10830 if (!imux->num_items && mux_idx > 0)
10831 imux = &spec->input_mux[0];
4953550a
TI
10832 for (idx = 0; idx < conns; idx++) {
10833 /* if the current connection is the selected one,
10834 * unmute it as default - otherwise mute it
10835 */
10836 mute = AMP_IN_MUTE(idx);
10837 for (item = 0; item < imux->num_items; item++) {
10838 if (imux->items[item].index == idx) {
10839 if (spec->cur_mux[c] == item)
10840 mute = AMP_IN_UNMUTE(idx);
10841 break;
10842 }
10843 }
10844 /* check if we have a selector or mixer
10845 * we could check for the widget type instead, but
10846 * just check for Amp-In presence (in case of mixer
10847 * without amp-in there is something wrong, this
10848 * function shouldn't be used or capsrc nid is wrong)
10849 */
10850 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10851 snd_hda_codec_write(codec, nid, 0,
10852 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10853 mute);
10854 else if (mute != AMP_IN_MUTE(idx))
10855 snd_hda_codec_write(codec, nid, 0,
10856 AC_VERB_SET_CONNECT_SEL,
10857 idx);
9c7f852e
TI
10858 }
10859 }
10860}
10861
4953550a
TI
10862/* add mic boosts if needed */
10863static int alc_auto_add_mic_boost(struct hda_codec *codec)
10864{
10865 struct alc_spec *spec = codec->spec;
66ceeb6b 10866 struct auto_pin_cfg *cfg = &spec->autocfg;
5322bf27 10867 int i, err;
53e8c323 10868 int type_idx = 0;
4953550a 10869 hda_nid_t nid;
5322bf27 10870 const char *prev_label = NULL;
4953550a 10871
66ceeb6b 10872 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 10873 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
10874 break;
10875 nid = cfg->inputs[i].pin;
10876 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
5322bf27
DH
10877 const char *label;
10878 char boost_label[32];
10879
10880 label = hda_get_autocfg_input_label(codec, cfg, i);
10881 if (prev_label && !strcmp(label, prev_label))
53e8c323
TI
10882 type_idx++;
10883 else
10884 type_idx = 0;
5322bf27
DH
10885 prev_label = label;
10886
10887 snprintf(boost_label, sizeof(boost_label),
10888 "%s Boost Volume", label);
10889 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10890 boost_label, type_idx,
4953550a 10891 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
10892 if (err < 0)
10893 return err;
10894 }
4953550a
TI
10895 }
10896 return 0;
10897}
f511b01c 10898
9c7f852e 10899/* almost identical with ALC880 parser... */
4953550a 10900static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10901{
10902 struct alc_spec *spec = codec->spec;
05f5f477 10903 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 10904 int err;
9c7f852e 10905
05f5f477
TI
10906 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10907 alc882_ignore);
9c7f852e
TI
10908 if (err < 0)
10909 return err;
05f5f477
TI
10910 if (!spec->autocfg.line_outs)
10911 return 0; /* can't find valid BIOS pin config */
776e184e 10912
05f5f477
TI
10913 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10914 if (err < 0)
10915 return err;
569ed348 10916 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
10917 if (err < 0)
10918 return err;
10919 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10920 "Headphone");
05f5f477
TI
10921 if (err < 0)
10922 return err;
10923 err = alc880_auto_create_extra_out(spec,
10924 spec->autocfg.speaker_pins[0],
10925 "Speaker");
10926 if (err < 0)
10927 return err;
05f5f477 10928 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10929 if (err < 0)
10930 return err;
10931
05f5f477
TI
10932 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10933
757899ac 10934 alc_auto_parse_digital(codec);
05f5f477
TI
10935
10936 if (spec->kctls.list)
10937 add_mixer(spec, spec->kctls.list);
10938
10939 add_verb(spec, alc883_auto_init_verbs);
4953550a 10940 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10941 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10942 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10943
05f5f477
TI
10944 spec->num_mux_defs = 1;
10945 spec->input_mux = &spec->private_imux[0];
10946
6227cdce 10947 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10948
10949 err = alc_auto_add_mic_boost(codec);
10950 if (err < 0)
10951 return err;
61b9b9b1 10952
776e184e 10953 return 1; /* config found */
9c7f852e
TI
10954}
10955
10956/* additional initialization for auto-configuration model */
4953550a 10957static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10958{
f6c7e546 10959 struct alc_spec *spec = codec->spec;
4953550a
TI
10960 alc882_auto_init_multi_out(codec);
10961 alc882_auto_init_hp_out(codec);
10962 alc882_auto_init_analog_input(codec);
10963 alc882_auto_init_input_src(codec);
757899ac 10964 alc_auto_init_digital(codec);
f6c7e546 10965 if (spec->unsol_event)
7fb0d78f 10966 alc_inithook(codec);
9c7f852e
TI
10967}
10968
4953550a 10969static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10970{
10971 struct alc_spec *spec;
10972 int err, board_config;
10973
10974 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10975 if (spec == NULL)
10976 return -ENOMEM;
10977
10978 codec->spec = spec;
10979
4953550a
TI
10980 switch (codec->vendor_id) {
10981 case 0x10ec0882:
10982 case 0x10ec0885:
10983 break;
10984 default:
10985 /* ALC883 and variants */
10986 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10987 break;
10988 }
2c3bf9ab 10989
4953550a
TI
10990 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10991 alc882_models,
10992 alc882_cfg_tbl);
10993
10994 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10995 board_config = snd_hda_check_board_codec_sid_config(codec,
10996 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10997
10998 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 10999 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
11000 codec->chip_name);
11001 board_config = ALC882_AUTO;
9c7f852e
TI
11002 }
11003
b5bfbc67
TI
11004 if (board_config == ALC882_AUTO) {
11005 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11006 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11007 }
4953550a 11008
90622917
DH
11009 alc_auto_parse_customize_define(codec);
11010
4953550a 11011 if (board_config == ALC882_AUTO) {
9c7f852e 11012 /* automatic parse from the BIOS config */
4953550a 11013 err = alc882_parse_auto_config(codec);
9c7f852e
TI
11014 if (err < 0) {
11015 alc_free(codec);
11016 return err;
f12ab1e0 11017 } else if (!err) {
9c7f852e
TI
11018 printk(KERN_INFO
11019 "hda_codec: Cannot set up configuration "
11020 "from BIOS. Using base mode...\n");
4953550a 11021 board_config = ALC882_3ST_DIG;
9c7f852e
TI
11022 }
11023 }
11024
dc1eae25 11025 if (has_cdefine_beep(codec)) {
8af2591d
TI
11026 err = snd_hda_attach_beep_device(codec, 0x1);
11027 if (err < 0) {
11028 alc_free(codec);
11029 return err;
11030 }
680cd536
KK
11031 }
11032
4953550a 11033 if (board_config != ALC882_AUTO)
e9c364c0 11034 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 11035
4953550a
TI
11036 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11037 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11038 /* FIXME: setup DAC5 */
11039 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11040 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11041
11042 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11043 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11044
4953550a 11045 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 11046 int i, j;
4953550a
TI
11047 spec->num_adc_nids = 0;
11048 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 11049 const struct hda_input_mux *imux = spec->input_mux;
4953550a 11050 hda_nid_t cap;
d11f74c6 11051 hda_nid_t items[16];
4953550a
TI
11052 hda_nid_t nid = alc882_adc_nids[i];
11053 unsigned int wcap = get_wcaps(codec, nid);
11054 /* get type */
a22d543a 11055 wcap = get_wcaps_type(wcap);
4953550a
TI
11056 if (wcap != AC_WID_AUD_IN)
11057 continue;
11058 spec->private_adc_nids[spec->num_adc_nids] = nid;
11059 err = snd_hda_get_connections(codec, nid, &cap, 1);
11060 if (err < 0)
11061 continue;
d11f74c6
TI
11062 err = snd_hda_get_connections(codec, cap, items,
11063 ARRAY_SIZE(items));
11064 if (err < 0)
11065 continue;
11066 for (j = 0; j < imux->num_items; j++)
11067 if (imux->items[j].index >= err)
11068 break;
11069 if (j < imux->num_items)
11070 continue;
4953550a
TI
11071 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11072 spec->num_adc_nids++;
61b9b9b1 11073 }
4953550a
TI
11074 spec->adc_nids = spec->private_adc_nids;
11075 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
11076 }
11077
b59bdf3b 11078 set_capture_mixer(codec);
da00c244 11079
dc1eae25 11080 if (has_cdefine_beep(codec))
da00c244 11081 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 11082
b5bfbc67 11083 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 11084
2134ea4f
TI
11085 spec->vmaster_nid = 0x0c;
11086
9c7f852e 11087 codec->patch_ops = alc_patch_ops;
4953550a
TI
11088 if (board_config == ALC882_AUTO)
11089 spec->init_hook = alc882_auto_init;
bf1b0225
KY
11090
11091 alc_init_jacks(codec);
cb53c626
TI
11092#ifdef CONFIG_SND_HDA_POWER_SAVE
11093 if (!spec->loopback.amplist)
4953550a 11094 spec->loopback.amplist = alc882_loopbacks;
cb53c626 11095#endif
9c7f852e
TI
11096
11097 return 0;
11098}
11099
4953550a 11100
9c7f852e
TI
11101/*
11102 * ALC262 support
11103 */
11104
11105#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11106#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11107
11108#define alc262_dac_nids alc260_dac_nids
11109#define alc262_adc_nids alc882_adc_nids
11110#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
11111#define alc262_capsrc_nids alc882_capsrc_nids
11112#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
11113
11114#define alc262_modes alc260_modes
11115#define alc262_capture_source alc882_capture_source
11116
4e555fe5
KY
11117static hda_nid_t alc262_dmic_adc_nids[1] = {
11118 /* ADC0 */
11119 0x09
11120};
11121
11122static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11123
9c7f852e
TI
11124static struct snd_kcontrol_new alc262_base_mixer[] = {
11125 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11126 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11127 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11128 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11129 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11130 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11131 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11132 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11133 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11134 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11135 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11136 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11137 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11138 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11139 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11140 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11141 { } /* end */
11142};
11143
ce875f07
TI
11144/* update HP, line and mono-out pins according to the master switch */
11145static void alc262_hp_master_update(struct hda_codec *codec)
11146{
11147 struct alc_spec *spec = codec->spec;
11148 int val = spec->master_sw;
11149
11150 /* HP & line-out */
11151 snd_hda_codec_write_cache(codec, 0x1b, 0,
11152 AC_VERB_SET_PIN_WIDGET_CONTROL,
11153 val ? PIN_HP : 0);
11154 snd_hda_codec_write_cache(codec, 0x15, 0,
11155 AC_VERB_SET_PIN_WIDGET_CONTROL,
11156 val ? PIN_HP : 0);
11157 /* mono (speaker) depending on the HP jack sense */
11158 val = val && !spec->jack_present;
11159 snd_hda_codec_write_cache(codec, 0x16, 0,
11160 AC_VERB_SET_PIN_WIDGET_CONTROL,
11161 val ? PIN_OUT : 0);
11162}
11163
11164static void alc262_hp_bpc_automute(struct hda_codec *codec)
11165{
11166 struct alc_spec *spec = codec->spec;
864f92be
WF
11167
11168 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
11169 alc262_hp_master_update(codec);
11170}
11171
11172static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
11173{
11174 if ((res >> 26) != ALC880_HP_EVENT)
11175 return;
11176 alc262_hp_bpc_automute(codec);
11177}
11178
11179static void alc262_hp_wildwest_automute(struct hda_codec *codec)
11180{
11181 struct alc_spec *spec = codec->spec;
864f92be
WF
11182
11183 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
11184 alc262_hp_master_update(codec);
11185}
11186
11187static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
11188 unsigned int res)
11189{
11190 if ((res >> 26) != ALC880_HP_EVENT)
11191 return;
11192 alc262_hp_wildwest_automute(codec);
11193}
11194
b72519b5 11195#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
11196
11197static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
11198 struct snd_ctl_elem_value *ucontrol)
11199{
11200 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11201 struct alc_spec *spec = codec->spec;
11202 int val = !!*ucontrol->value.integer.value;
11203
11204 if (val == spec->master_sw)
11205 return 0;
11206 spec->master_sw = val;
11207 alc262_hp_master_update(codec);
11208 return 1;
11209}
11210
b72519b5
TI
11211#define ALC262_HP_MASTER_SWITCH \
11212 { \
11213 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11214 .name = "Master Playback Switch", \
11215 .info = snd_ctl_boolean_mono_info, \
11216 .get = alc262_hp_master_sw_get, \
11217 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11218 }, \
11219 { \
11220 .iface = NID_MAPPING, \
11221 .name = "Master Playback Switch", \
11222 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11223 }
11224
5b0cb1d8 11225
9c7f852e 11226static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11227 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11228 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11229 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11230 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11231 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11232 HDA_OUTPUT),
11233 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11234 HDA_OUTPUT),
9c7f852e
TI
11235 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11236 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11237 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11238 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11239 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11240 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11241 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11242 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11243 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11244 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11245 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11246 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11247 { } /* end */
11248};
11249
cd7509a4 11250static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11251 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11252 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11253 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11254 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11255 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11256 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11257 HDA_OUTPUT),
11258 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11259 HDA_OUTPUT),
cd7509a4
KY
11260 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11261 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5f99f86a 11262 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11263 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11264 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11265 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11266 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11267 { } /* end */
11268};
11269
11270static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11271 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11272 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11273 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11274 { } /* end */
11275};
11276
66d2a9d6 11277/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11278static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11279{
11280 struct alc_spec *spec = codec->spec;
66d2a9d6 11281
a9fd4f3f 11282 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11283 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
11284}
11285
66d2a9d6 11286static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11287 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11288 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11289 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11290 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11291 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11292 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11293 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
66d2a9d6
KY
11294 { } /* end */
11295};
11296
11297static struct hda_verb alc262_hp_t5735_verbs[] = {
11298 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11299 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11300
11301 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11302 { }
11303};
11304
8c427226 11305static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11306 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11307 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11308 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11309 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11310 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11311 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11312 { } /* end */
11313};
11314
11315static struct hda_verb alc262_hp_rp5700_verbs[] = {
11316 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11317 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11318 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11319 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11320 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11321 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11322 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11323 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11324 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11325 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11326 {}
11327};
11328
11329static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11330 .num_items = 1,
11331 .items = {
11332 { "Line", 0x1 },
11333 },
11334};
11335
42171c17
TI
11336/* bind hp and internal speaker mute (with plug check) as master switch */
11337static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 11338{
42171c17
TI
11339 struct alc_spec *spec = codec->spec;
11340 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11341 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11342 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11343 unsigned int mute;
0724ea2a 11344
42171c17
TI
11345 /* HP */
11346 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11347 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11348 HDA_AMP_MUTE, mute);
11349 /* mute internal speaker per jack sense */
11350 if (spec->jack_present)
11351 mute = HDA_AMP_MUTE;
11352 if (line_nid)
11353 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11354 HDA_AMP_MUTE, mute);
11355 if (speaker_nid && speaker_nid != line_nid)
11356 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 11357 HDA_AMP_MUTE, mute);
42171c17
TI
11358}
11359
11360#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11361
11362static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11363 struct snd_ctl_elem_value *ucontrol)
11364{
11365 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11366 struct alc_spec *spec = codec->spec;
11367 int val = !!*ucontrol->value.integer.value;
11368
11369 if (val == spec->master_sw)
11370 return 0;
11371 spec->master_sw = val;
11372 alc262_hippo_master_update(codec);
11373 return 1;
11374}
11375
11376#define ALC262_HIPPO_MASTER_SWITCH \
11377 { \
11378 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11379 .name = "Master Playback Switch", \
11380 .info = snd_ctl_boolean_mono_info, \
11381 .get = alc262_hippo_master_sw_get, \
11382 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11383 }, \
11384 { \
11385 .iface = NID_MAPPING, \
11386 .name = "Master Playback Switch", \
11387 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11388 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11389 }
42171c17
TI
11390
11391static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11392 ALC262_HIPPO_MASTER_SWITCH,
11393 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11394 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11395 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11396 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11397 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11398 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11399 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11400 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11401 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11402 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11403 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11404 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11405 { } /* end */
11406};
11407
11408static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11409 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11410 ALC262_HIPPO_MASTER_SWITCH,
11411 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11412 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11413 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11414 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11415 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11416 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11417 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11418 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11419 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11420 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11421 { } /* end */
11422};
11423
11424/* mute/unmute internal speaker according to the hp jack and mute state */
11425static void alc262_hippo_automute(struct hda_codec *codec)
11426{
11427 struct alc_spec *spec = codec->spec;
11428 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 11429
864f92be 11430 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 11431 alc262_hippo_master_update(codec);
0724ea2a 11432}
5b31954e 11433
42171c17
TI
11434static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11435{
11436 if ((res >> 26) != ALC880_HP_EVENT)
11437 return;
11438 alc262_hippo_automute(codec);
11439}
11440
4f5d1706 11441static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11442{
11443 struct alc_spec *spec = codec->spec;
11444
11445 spec->autocfg.hp_pins[0] = 0x15;
11446 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11447}
11448
4f5d1706 11449static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11450{
11451 struct alc_spec *spec = codec->spec;
11452
11453 spec->autocfg.hp_pins[0] = 0x1b;
11454 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11455}
11456
11457
272a527c 11458static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11459 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11460 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11461 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11462 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11463 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11464 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11465 { } /* end */
11466};
11467
83c34218 11468static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11469 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11470 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11471 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11472 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11473 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11474 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11475 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11476 { } /* end */
11477};
272a527c 11478
ba340e82
TV
11479static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11480 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11481 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11482 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11483 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11484 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11485 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11486 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11487 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11488 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ba340e82
TV
11489 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11490 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11491 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
ba340e82
TV
11492 { } /* end */
11493};
11494
11495static struct hda_verb alc262_tyan_verbs[] = {
11496 /* Headphone automute */
11497 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11498 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11499 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11500
11501 /* P11 AUX_IN, white 4-pin connector */
11502 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11503 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11504 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11505 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11506
11507 {}
11508};
11509
11510/* unsolicited event for HP jack sensing */
4f5d1706 11511static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11512{
a9fd4f3f 11513 struct alc_spec *spec = codec->spec;
ba340e82 11514
a9fd4f3f
TI
11515 spec->autocfg.hp_pins[0] = 0x1b;
11516 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
11517}
11518
ba340e82 11519
9c7f852e
TI
11520#define alc262_capture_mixer alc882_capture_mixer
11521#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11522
11523/*
11524 * generic initialization of ADC, input mixers and output mixers
11525 */
11526static struct hda_verb alc262_init_verbs[] = {
11527 /*
11528 * Unmute ADC0-2 and set the default input to mic-in
11529 */
11530 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11531 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11532 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11533 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11534 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11535 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11536
cb53c626 11537 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11538 * mixer widget
f12ab1e0
TI
11539 * Note: PASD motherboards uses the Line In 2 as the input for
11540 * front panel mic (mic 2)
9c7f852e
TI
11541 */
11542 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11543 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11544 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11545 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11546 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11547 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11548
11549 /*
df694daa
KY
11550 * Set up output mixers (0x0c - 0x0e)
11551 */
11552 /* set vol=0 to output mixers */
11553 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11554 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11555 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11556 /* set up input amps for analog loopback */
11557 /* Amp Indices: DAC = 0, mixer = 1 */
11558 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11559 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11560 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11561 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11562 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11563 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11564
11565 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11566 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11567 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11568 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11569 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11570 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11571
11572 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11573 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11574 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11575 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11576 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11577
df694daa
KY
11578 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11579 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11580
df694daa
KY
11581 /* FIXME: use matrix-type input source selection */
11582 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11583 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11584 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11585 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11586 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11587 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11588 /* Input mixer2 */
11589 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11590 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11591 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11592 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11593 /* Input mixer3 */
11594 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11595 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11596 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11597 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11598
11599 { }
11600};
1da177e4 11601
4e555fe5
KY
11602static struct hda_verb alc262_eapd_verbs[] = {
11603 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11604 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11605 { }
11606};
11607
ccc656ce
KY
11608static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11609 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11610 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11611 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11612
11613 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11614 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11615 {}
11616};
11617
272a527c
KY
11618static struct hda_verb alc262_sony_unsol_verbs[] = {
11619 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11620 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11621 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11622
11623 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11624 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11625 {}
272a527c
KY
11626};
11627
4e555fe5
KY
11628static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11629 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11630 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11631 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11632 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11633 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11634 { } /* end */
11635};
11636
11637static struct hda_verb alc262_toshiba_s06_verbs[] = {
11638 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11639 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11640 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11641 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11642 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11643 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11644 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11645 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11646 {}
11647};
11648
4f5d1706 11649static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11650{
a9fd4f3f
TI
11651 struct alc_spec *spec = codec->spec;
11652
11653 spec->autocfg.hp_pins[0] = 0x15;
11654 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11655 spec->ext_mic.pin = 0x18;
11656 spec->ext_mic.mux_idx = 0;
11657 spec->int_mic.pin = 0x12;
11658 spec->int_mic.mux_idx = 9;
11659 spec->auto_mic = 1;
4e555fe5
KY
11660}
11661
e8f9ae2a
PT
11662/*
11663 * nec model
11664 * 0x15 = headphone
11665 * 0x16 = internal speaker
11666 * 0x18 = external mic
11667 */
11668
11669static struct snd_kcontrol_new alc262_nec_mixer[] = {
11670 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11671 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11672
11673 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11674 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11675 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e8f9ae2a
PT
11676
11677 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11678 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11679 { } /* end */
11680};
11681
11682static struct hda_verb alc262_nec_verbs[] = {
11683 /* Unmute Speaker */
11684 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11685
11686 /* Headphone */
11687 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11688 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11689
11690 /* External mic to headphone */
11691 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11692 /* External mic to speaker */
11693 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11694 {}
11695};
11696
834be88d
TI
11697/*
11698 * fujitsu model
5d9fab2d
TV
11699 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11700 * 0x1b = port replicator headphone out
834be88d
TI
11701 */
11702
11703#define ALC_HP_EVENT 0x37
11704
11705static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11706 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11707 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11708 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11709 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11710 {}
11711};
11712
0e31daf7
J
11713static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11714 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11715 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11716 {}
11717};
11718
e2595322
DC
11719static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11720 /* Front Mic pin: input vref at 50% */
11721 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11722 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11723 {}
11724};
11725
834be88d 11726static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11727 .num_items = 3,
834be88d
TI
11728 .items = {
11729 { "Mic", 0x0 },
28c4edb7 11730 { "Internal Mic", 0x1 },
834be88d
TI
11731 { "CD", 0x4 },
11732 },
11733};
11734
9c7f852e
TI
11735static struct hda_input_mux alc262_HP_capture_source = {
11736 .num_items = 5,
11737 .items = {
11738 { "Mic", 0x0 },
accbe498 11739 { "Front Mic", 0x1 },
9c7f852e
TI
11740 { "Line", 0x2 },
11741 { "CD", 0x4 },
11742 { "AUX IN", 0x6 },
11743 },
11744};
11745
accbe498 11746static struct hda_input_mux alc262_HP_D7000_capture_source = {
11747 .num_items = 4,
11748 .items = {
11749 { "Mic", 0x0 },
11750 { "Front Mic", 0x2 },
11751 { "Line", 0x1 },
11752 { "CD", 0x4 },
11753 },
11754};
11755
ebc7a406 11756/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11757static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11758{
11759 struct alc_spec *spec = codec->spec;
11760 unsigned int mute;
11761
f12ab1e0 11762 if (force || !spec->sense_updated) {
864f92be
WF
11763 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11764 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11765 spec->sense_updated = 1;
11766 }
ebc7a406
TI
11767 /* unmute internal speaker only if both HPs are unplugged and
11768 * master switch is on
11769 */
11770 if (spec->jack_present)
11771 mute = HDA_AMP_MUTE;
11772 else
834be88d 11773 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11774 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11775 HDA_AMP_MUTE, mute);
834be88d
TI
11776}
11777
11778/* unsolicited event for HP jack sensing */
11779static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11780 unsigned int res)
11781{
11782 if ((res >> 26) != ALC_HP_EVENT)
11783 return;
11784 alc262_fujitsu_automute(codec, 1);
11785}
11786
ebc7a406
TI
11787static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11788{
11789 alc262_fujitsu_automute(codec, 1);
11790}
11791
834be88d 11792/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11793static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11794 .ops = &snd_hda_bind_vol,
11795 .values = {
11796 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11797 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11798 0
11799 },
11800};
834be88d 11801
0e31daf7
J
11802/* mute/unmute internal speaker according to the hp jack and mute state */
11803static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11804{
11805 struct alc_spec *spec = codec->spec;
11806 unsigned int mute;
11807
11808 if (force || !spec->sense_updated) {
864f92be 11809 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11810 spec->sense_updated = 1;
11811 }
11812 if (spec->jack_present) {
11813 /* mute internal speaker */
11814 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11815 HDA_AMP_MUTE, HDA_AMP_MUTE);
11816 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11817 HDA_AMP_MUTE, HDA_AMP_MUTE);
11818 } else {
11819 /* unmute internal speaker if necessary */
11820 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11821 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11822 HDA_AMP_MUTE, mute);
11823 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11824 HDA_AMP_MUTE, mute);
11825 }
11826}
11827
11828/* unsolicited event for HP jack sensing */
11829static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11830 unsigned int res)
11831{
11832 if ((res >> 26) != ALC_HP_EVENT)
11833 return;
11834 alc262_lenovo_3000_automute(codec, 1);
11835}
11836
8de56b7d
TI
11837static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11838 int dir, int idx, long *valp)
11839{
11840 int i, change = 0;
11841
11842 for (i = 0; i < 2; i++, valp++)
11843 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11844 HDA_AMP_MUTE,
11845 *valp ? 0 : HDA_AMP_MUTE);
11846 return change;
11847}
11848
834be88d
TI
11849/* bind hp and internal speaker mute (with plug check) */
11850static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11851 struct snd_ctl_elem_value *ucontrol)
11852{
11853 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11854 long *valp = ucontrol->value.integer.value;
11855 int change;
11856
8de56b7d
TI
11857 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11858 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11859 if (change)
11860 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11861 return change;
11862}
11863
11864static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11865 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11866 {
11867 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11868 .name = "Master Playback Switch",
5e26dfd0 11869 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11870 .info = snd_hda_mixer_amp_switch_info,
11871 .get = snd_hda_mixer_amp_switch_get,
11872 .put = alc262_fujitsu_master_sw_put,
11873 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11874 },
5b0cb1d8
JK
11875 {
11876 .iface = NID_MAPPING,
11877 .name = "Master Playback Switch",
11878 .private_value = 0x1b,
11879 },
834be88d
TI
11880 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11881 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11882 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
834be88d
TI
11883 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11884 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11885 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11886 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11887 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11888 { } /* end */
11889};
11890
0e31daf7
J
11891/* bind hp and internal speaker mute (with plug check) */
11892static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11893 struct snd_ctl_elem_value *ucontrol)
11894{
11895 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11896 long *valp = ucontrol->value.integer.value;
11897 int change;
11898
8de56b7d 11899 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11900 if (change)
11901 alc262_lenovo_3000_automute(codec, 0);
11902 return change;
11903}
11904
11905static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11906 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11907 {
11908 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11909 .name = "Master Playback Switch",
5e26dfd0 11910 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11911 .info = snd_hda_mixer_amp_switch_info,
11912 .get = snd_hda_mixer_amp_switch_get,
11913 .put = alc262_lenovo_3000_master_sw_put,
11914 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11915 },
11916 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11917 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11918 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
0e31daf7
J
11919 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11920 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11921 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11922 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11923 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
0e31daf7
J
11924 { } /* end */
11925};
11926
9f99a638
HM
11927static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11928 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11929 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11930 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11931 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11932 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9f99a638
HM
11933 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11934 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11935 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9f99a638
HM
11936 { } /* end */
11937};
11938
304dcaac
TI
11939/* additional init verbs for Benq laptops */
11940static struct hda_verb alc262_EAPD_verbs[] = {
11941 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11942 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11943 {}
11944};
11945
83c34218
KY
11946static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11947 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11948 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11949
11950 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11951 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11952 {}
11953};
11954
f651b50b
TD
11955/* Samsung Q1 Ultra Vista model setup */
11956static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11957 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11958 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11959 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11960 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
11961 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11962 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
f651b50b
TD
11963 { } /* end */
11964};
11965
11966static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11967 /* output mixer */
11968 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11969 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11970 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11971 /* speaker */
11972 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11973 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11974 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11975 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11976 /* HP */
f651b50b 11977 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11978 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11979 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11980 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11981 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11982 /* internal mic */
11983 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11984 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11985 /* ADC, choose mic */
11986 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11987 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11988 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11989 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11990 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11991 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11992 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11993 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11994 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11995 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
11996 {}
11997};
11998
f651b50b
TD
11999/* mute/unmute internal speaker according to the hp jack and mute state */
12000static void alc262_ultra_automute(struct hda_codec *codec)
12001{
12002 struct alc_spec *spec = codec->spec;
12003 unsigned int mute;
f651b50b 12004
bb9f76cd
TI
12005 mute = 0;
12006 /* auto-mute only when HP is used as HP */
12007 if (!spec->cur_mux[0]) {
864f92be 12008 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
12009 if (spec->jack_present)
12010 mute = HDA_AMP_MUTE;
f651b50b 12011 }
bb9f76cd
TI
12012 /* mute/unmute internal speaker */
12013 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12014 HDA_AMP_MUTE, mute);
12015 /* mute/unmute HP */
12016 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12017 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
12018}
12019
12020/* unsolicited event for HP jack sensing */
12021static void alc262_ultra_unsol_event(struct hda_codec *codec,
12022 unsigned int res)
12023{
12024 if ((res >> 26) != ALC880_HP_EVENT)
12025 return;
12026 alc262_ultra_automute(codec);
12027}
12028
bb9f76cd
TI
12029static struct hda_input_mux alc262_ultra_capture_source = {
12030 .num_items = 2,
12031 .items = {
12032 { "Mic", 0x1 },
12033 { "Headphone", 0x7 },
12034 },
12035};
12036
12037static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12038 struct snd_ctl_elem_value *ucontrol)
12039{
12040 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12041 struct alc_spec *spec = codec->spec;
12042 int ret;
12043
54cbc9ab 12044 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
12045 if (!ret)
12046 return 0;
12047 /* reprogram the HP pin as mic or HP according to the input source */
12048 snd_hda_codec_write_cache(codec, 0x15, 0,
12049 AC_VERB_SET_PIN_WIDGET_CONTROL,
12050 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12051 alc262_ultra_automute(codec); /* mute/unmute HP */
12052 return ret;
12053}
12054
12055static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12056 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12057 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12058 {
12059 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12060 .name = "Capture Source",
54cbc9ab
TI
12061 .info = alc_mux_enum_info,
12062 .get = alc_mux_enum_get,
bb9f76cd
TI
12063 .put = alc262_ultra_mux_enum_put,
12064 },
5b0cb1d8
JK
12065 {
12066 .iface = NID_MAPPING,
12067 .name = "Capture Source",
12068 .private_value = 0x15,
12069 },
bb9f76cd
TI
12070 { } /* end */
12071};
12072
c3fc1f50
TI
12073/* We use two mixers depending on the output pin; 0x16 is a mono output
12074 * and thus it's bound with a different mixer.
12075 * This function returns which mixer amp should be used.
12076 */
12077static int alc262_check_volbit(hda_nid_t nid)
12078{
12079 if (!nid)
12080 return 0;
12081 else if (nid == 0x16)
12082 return 2;
12083 else
12084 return 1;
12085}
12086
12087static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12088 const char *pfx, int *vbits, int idx)
c3fc1f50 12089{
c3fc1f50
TI
12090 unsigned long val;
12091 int vbit;
12092
12093 vbit = alc262_check_volbit(nid);
12094 if (!vbit)
12095 return 0;
12096 if (*vbits & vbit) /* a volume control for this mixer already there */
12097 return 0;
12098 *vbits |= vbit;
c3fc1f50
TI
12099 if (vbit == 2)
12100 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12101 else
12102 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 12103 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
12104}
12105
12106static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12107 const char *pfx, int idx)
c3fc1f50 12108{
c3fc1f50
TI
12109 unsigned long val;
12110
12111 if (!nid)
12112 return 0;
c3fc1f50
TI
12113 if (nid == 0x16)
12114 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12115 else
12116 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 12117 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
12118}
12119
df694daa 12120/* add playback controls from the parsed DAC table */
f12ab1e0
TI
12121static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12122 const struct auto_pin_cfg *cfg)
df694daa 12123{
c3fc1f50
TI
12124 const char *pfx;
12125 int vbits;
033688a5 12126 int i, err;
df694daa
KY
12127
12128 spec->multiout.num_dacs = 1; /* only use one dac */
12129 spec->multiout.dac_nids = spec->private_dac_nids;
12130 spec->multiout.dac_nids[0] = 2;
12131
bcb2f0f5
TI
12132 pfx = alc_get_line_out_pfx(cfg, true);
12133 if (!pfx)
c3fc1f50 12134 pfx = "Front";
033688a5
TI
12135 for (i = 0; i < 2; i++) {
12136 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12137 if (err < 0)
12138 return err;
12139 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12140 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12141 "Speaker", i);
12142 if (err < 0)
12143 return err;
12144 }
12145 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12146 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12147 "Headphone", i);
12148 if (err < 0)
12149 return err;
12150 }
12151 }
df694daa 12152
c3fc1f50
TI
12153 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12154 alc262_check_volbit(cfg->speaker_pins[0]) |
12155 alc262_check_volbit(cfg->hp_pins[0]);
12156 if (vbits == 1 || vbits == 2)
12157 pfx = "Master"; /* only one mixer is used */
c3fc1f50 12158 vbits = 0;
033688a5
TI
12159 for (i = 0; i < 2; i++) {
12160 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12161 &vbits, i);
12162 if (err < 0)
12163 return err;
12164 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12165 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12166 "Speaker", &vbits, i);
12167 if (err < 0)
12168 return err;
12169 }
12170 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12171 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12172 "Headphone", &vbits, i);
12173 if (err < 0)
12174 return err;
12175 }
12176 }
f12ab1e0 12177 return 0;
df694daa
KY
12178}
12179
05f5f477 12180#define alc262_auto_create_input_ctls \
eaa9b3a7 12181 alc882_auto_create_input_ctls
df694daa
KY
12182
12183/*
12184 * generic initialization of ADC, input mixers and output mixers
12185 */
12186static struct hda_verb alc262_volume_init_verbs[] = {
12187 /*
12188 * Unmute ADC0-2 and set the default input to mic-in
12189 */
12190 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12191 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12192 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12193 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12194 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12195 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12196
cb53c626 12197 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 12198 * mixer widget
f12ab1e0
TI
12199 * Note: PASD motherboards uses the Line In 2 as the input for
12200 * front panel mic (mic 2)
df694daa
KY
12201 */
12202 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12203 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12204 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12205 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12206 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12207 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
12208
12209 /*
12210 * Set up output mixers (0x0c - 0x0f)
12211 */
12212 /* set vol=0 to output mixers */
12213 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12214 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12215 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 12216
df694daa
KY
12217 /* set up input amps for analog loopback */
12218 /* Amp Indices: DAC = 0, mixer = 1 */
12219 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12221 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12222 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12223 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12224 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12225
12226 /* FIXME: use matrix-type input source selection */
12227 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12228 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12229 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12230 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12231 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12232 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12233 /* Input mixer2 */
12234 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12235 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12236 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12237 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12238 /* Input mixer3 */
12239 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12240 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12241 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12242 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12243
12244 { }
12245};
12246
9c7f852e
TI
12247static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12248 /*
12249 * Unmute ADC0-2 and set the default input to mic-in
12250 */
12251 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12252 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12253 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12254 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12255 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12256 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12257
cb53c626 12258 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12259 * mixer widget
f12ab1e0
TI
12260 * Note: PASD motherboards uses the Line In 2 as the input for
12261 * front panel mic (mic 2)
9c7f852e
TI
12262 */
12263 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12264 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12265 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12266 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12267 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12268 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12269 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12270 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12271
9c7f852e
TI
12272 /*
12273 * Set up output mixers (0x0c - 0x0e)
12274 */
12275 /* set vol=0 to output mixers */
12276 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12277 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12278 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12279
12280 /* set up input amps for analog loopback */
12281 /* Amp Indices: DAC = 0, mixer = 1 */
12282 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12283 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12284 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12285 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12286 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12287 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12288
ce875f07 12289 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12290 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12291 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12292
12293 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12294 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12295
12296 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12297 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12298
12299 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12300 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12301 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12302 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12303 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12304
0e4835c1 12305 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12306 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12307 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12308 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12309 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12310 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12311
12312
12313 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12314 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12315 /* Input mixer1: only unmute Mic */
9c7f852e 12316 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12317 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12318 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12319 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12320 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12321 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12322 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12323 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12324 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12325 /* Input mixer2 */
12326 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12327 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12328 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12329 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12330 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12331 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12332 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12333 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12334 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12335 /* Input mixer3 */
12336 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12337 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12338 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12339 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12340 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12341 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12342 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12343 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12344 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12345
ce875f07
TI
12346 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12347
9c7f852e
TI
12348 { }
12349};
12350
cd7509a4
KY
12351static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12352 /*
12353 * Unmute ADC0-2 and set the default input to mic-in
12354 */
12355 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12356 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12357 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12358 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12359 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12360 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12361
cb53c626 12362 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12363 * mixer widget
12364 * Note: PASD motherboards uses the Line In 2 as the input for front
12365 * panel mic (mic 2)
12366 */
12367 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12368 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12369 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12370 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12371 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12372 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12373 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12374 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12375 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12376 /*
12377 * Set up output mixers (0x0c - 0x0e)
12378 */
12379 /* set vol=0 to output mixers */
12380 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12381 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12382 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12383
12384 /* set up input amps for analog loopback */
12385 /* Amp Indices: DAC = 0, mixer = 1 */
12386 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12387 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12388 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12389 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12390 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12391 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12392
12393
12394 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12395 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12396 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12397 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12398 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12399 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12400 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12401
12402 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12403 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12404
12405 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12406 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12407
12408 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12409 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12410 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12411 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12412 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12413 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12414
12415 /* FIXME: use matrix-type input source selection */
12416 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12417 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12418 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12419 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12420 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12421 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12422 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12423 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12424 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12425 /* Input mixer2 */
12426 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12427 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12428 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12429 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12430 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12431 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12432 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12433 /* Input mixer3 */
12434 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12435 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12436 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12437 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12438 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12439 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12440 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12441
ce875f07
TI
12442 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12443
cd7509a4
KY
12444 { }
12445};
12446
9f99a638
HM
12447static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12448
12449 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12450 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12451 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12452
12453 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12454 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12455 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12456 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12457
12458 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12459 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12460 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12461 {}
12462};
12463
18675e42
TI
12464/*
12465 * Pin config fixes
12466 */
12467enum {
12468 PINFIX_FSC_H270,
12469};
12470
12471static const struct alc_fixup alc262_fixups[] = {
12472 [PINFIX_FSC_H270] = {
b5bfbc67
TI
12473 .type = ALC_FIXUP_PINS,
12474 .v.pins = (const struct alc_pincfg[]) {
18675e42
TI
12475 { 0x14, 0x99130110 }, /* speaker */
12476 { 0x15, 0x0221142f }, /* front HP */
12477 { 0x1b, 0x0121141f }, /* rear HP */
12478 { }
12479 }
12480 },
18675e42
TI
12481};
12482
12483static struct snd_pci_quirk alc262_fixup_tbl[] = {
12484 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12485 {}
12486};
12487
9f99a638 12488
cb53c626
TI
12489#ifdef CONFIG_SND_HDA_POWER_SAVE
12490#define alc262_loopbacks alc880_loopbacks
12491#endif
12492
def319f9 12493/* pcm configuration: identical with ALC880 */
df694daa
KY
12494#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12495#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12496#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12497#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12498
12499/*
12500 * BIOS auto configuration
12501 */
12502static int alc262_parse_auto_config(struct hda_codec *codec)
12503{
12504 struct alc_spec *spec = codec->spec;
12505 int err;
12506 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12507
f12ab1e0
TI
12508 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12509 alc262_ignore);
12510 if (err < 0)
df694daa 12511 return err;
e64f14f4 12512 if (!spec->autocfg.line_outs) {
0852d7a6 12513 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12514 spec->multiout.max_channels = 2;
12515 spec->no_analog = 1;
12516 goto dig_only;
12517 }
df694daa 12518 return 0; /* can't find valid BIOS pin config */
e64f14f4 12519 }
f12ab1e0
TI
12520 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12521 if (err < 0)
12522 return err;
05f5f477 12523 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12524 if (err < 0)
df694daa
KY
12525 return err;
12526
12527 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12528
e64f14f4 12529 dig_only:
757899ac 12530 alc_auto_parse_digital(codec);
df694daa 12531
603c4019 12532 if (spec->kctls.list)
d88897ea 12533 add_mixer(spec, spec->kctls.list);
df694daa 12534
d88897ea 12535 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12536 spec->num_mux_defs = 1;
61b9b9b1 12537 spec->input_mux = &spec->private_imux[0];
df694daa 12538
776e184e
TI
12539 err = alc_auto_add_mic_boost(codec);
12540 if (err < 0)
12541 return err;
12542
6227cdce 12543 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12544
df694daa
KY
12545 return 1;
12546}
12547
12548#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12549#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12550#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12551#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12552
12553
12554/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12555static void alc262_auto_init(struct hda_codec *codec)
df694daa 12556{
f6c7e546 12557 struct alc_spec *spec = codec->spec;
df694daa
KY
12558 alc262_auto_init_multi_out(codec);
12559 alc262_auto_init_hp_out(codec);
12560 alc262_auto_init_analog_input(codec);
f511b01c 12561 alc262_auto_init_input_src(codec);
757899ac 12562 alc_auto_init_digital(codec);
f6c7e546 12563 if (spec->unsol_event)
7fb0d78f 12564 alc_inithook(codec);
df694daa
KY
12565}
12566
12567/*
12568 * configuration and preset
12569 */
ea734963 12570static const char * const alc262_models[ALC262_MODEL_LAST] = {
f5fcc13c
TI
12571 [ALC262_BASIC] = "basic",
12572 [ALC262_HIPPO] = "hippo",
12573 [ALC262_HIPPO_1] = "hippo_1",
12574 [ALC262_FUJITSU] = "fujitsu",
12575 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12576 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12577 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12578 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12579 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12580 [ALC262_BENQ_T31] = "benq-t31",
12581 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12582 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12583 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12584 [ALC262_ULTRA] = "ultra",
0e31daf7 12585 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12586 [ALC262_NEC] = "nec",
ba340e82 12587 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12588 [ALC262_AUTO] = "auto",
12589};
12590
12591static struct snd_pci_quirk alc262_cfg_tbl[] = {
12592 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12593 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12594 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12595 ALC262_HP_BPC),
12596 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12597 ALC262_HP_BPC),
5734a07c
TI
12598 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12599 ALC262_HP_BPC),
53eff7e1
TI
12600 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12601 ALC262_HP_BPC),
cd7509a4 12602 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12603 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12604 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12605 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12606 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12607 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12608 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12609 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12610 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12611 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12612 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12613 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12614 ALC262_HP_TC_T5735),
8c427226 12615 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12616 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12617 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12618 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12619 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12620 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12621 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12622 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12623#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12624 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12625 ALC262_SONY_ASSAMD),
c5b5165c 12626#endif
36ca6e13 12627 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12628 ALC262_TOSHIBA_RX1),
80ffe869 12629 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12630 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12631 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12632 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12633 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12634 ALC262_ULTRA),
3e420e78 12635 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12636 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12637 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12638 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12639 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12640 {}
12641};
12642
12643static struct alc_config_preset alc262_presets[] = {
12644 [ALC262_BASIC] = {
12645 .mixers = { alc262_base_mixer },
12646 .init_verbs = { alc262_init_verbs },
12647 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12648 .dac_nids = alc262_dac_nids,
12649 .hp_nid = 0x03,
12650 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12651 .channel_mode = alc262_modes,
a3bcba38 12652 .input_mux = &alc262_capture_source,
df694daa 12653 },
ccc656ce 12654 [ALC262_HIPPO] = {
42171c17 12655 .mixers = { alc262_hippo_mixer },
6732bd0d 12656 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12657 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12658 .dac_nids = alc262_dac_nids,
12659 .hp_nid = 0x03,
12660 .dig_out_nid = ALC262_DIGOUT_NID,
12661 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12662 .channel_mode = alc262_modes,
12663 .input_mux = &alc262_capture_source,
12664 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12665 .setup = alc262_hippo_setup,
12666 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12667 },
12668 [ALC262_HIPPO_1] = {
12669 .mixers = { alc262_hippo1_mixer },
12670 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12671 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12672 .dac_nids = alc262_dac_nids,
12673 .hp_nid = 0x02,
12674 .dig_out_nid = ALC262_DIGOUT_NID,
12675 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12676 .channel_mode = alc262_modes,
12677 .input_mux = &alc262_capture_source,
42171c17 12678 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12679 .setup = alc262_hippo1_setup,
12680 .init_hook = alc262_hippo_automute,
ccc656ce 12681 },
834be88d
TI
12682 [ALC262_FUJITSU] = {
12683 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12684 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12685 alc262_fujitsu_unsol_verbs },
834be88d
TI
12686 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12687 .dac_nids = alc262_dac_nids,
12688 .hp_nid = 0x03,
12689 .dig_out_nid = ALC262_DIGOUT_NID,
12690 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12691 .channel_mode = alc262_modes,
12692 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12693 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12694 .init_hook = alc262_fujitsu_init_hook,
834be88d 12695 },
9c7f852e
TI
12696 [ALC262_HP_BPC] = {
12697 .mixers = { alc262_HP_BPC_mixer },
12698 .init_verbs = { alc262_HP_BPC_init_verbs },
12699 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12700 .dac_nids = alc262_dac_nids,
12701 .hp_nid = 0x03,
12702 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12703 .channel_mode = alc262_modes,
12704 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12705 .unsol_event = alc262_hp_bpc_unsol_event,
12706 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12707 },
cd7509a4
KY
12708 [ALC262_HP_BPC_D7000_WF] = {
12709 .mixers = { alc262_HP_BPC_WildWest_mixer },
12710 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12711 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12712 .dac_nids = alc262_dac_nids,
12713 .hp_nid = 0x03,
12714 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12715 .channel_mode = alc262_modes,
accbe498 12716 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12717 .unsol_event = alc262_hp_wildwest_unsol_event,
12718 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12719 },
cd7509a4
KY
12720 [ALC262_HP_BPC_D7000_WL] = {
12721 .mixers = { alc262_HP_BPC_WildWest_mixer,
12722 alc262_HP_BPC_WildWest_option_mixer },
12723 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12724 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12725 .dac_nids = alc262_dac_nids,
12726 .hp_nid = 0x03,
12727 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12728 .channel_mode = alc262_modes,
accbe498 12729 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12730 .unsol_event = alc262_hp_wildwest_unsol_event,
12731 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12732 },
66d2a9d6
KY
12733 [ALC262_HP_TC_T5735] = {
12734 .mixers = { alc262_hp_t5735_mixer },
12735 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12736 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12737 .dac_nids = alc262_dac_nids,
12738 .hp_nid = 0x03,
12739 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12740 .channel_mode = alc262_modes,
12741 .input_mux = &alc262_capture_source,
dc99be47 12742 .unsol_event = alc_sku_unsol_event,
4f5d1706 12743 .setup = alc262_hp_t5735_setup,
dc99be47 12744 .init_hook = alc_inithook,
8c427226
KY
12745 },
12746 [ALC262_HP_RP5700] = {
12747 .mixers = { alc262_hp_rp5700_mixer },
12748 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12749 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12750 .dac_nids = alc262_dac_nids,
12751 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12752 .channel_mode = alc262_modes,
12753 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12754 },
304dcaac
TI
12755 [ALC262_BENQ_ED8] = {
12756 .mixers = { alc262_base_mixer },
12757 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12758 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12759 .dac_nids = alc262_dac_nids,
12760 .hp_nid = 0x03,
12761 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12762 .channel_mode = alc262_modes,
12763 .input_mux = &alc262_capture_source,
f12ab1e0 12764 },
272a527c
KY
12765 [ALC262_SONY_ASSAMD] = {
12766 .mixers = { alc262_sony_mixer },
12767 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12768 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12769 .dac_nids = alc262_dac_nids,
12770 .hp_nid = 0x02,
12771 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12772 .channel_mode = alc262_modes,
12773 .input_mux = &alc262_capture_source,
12774 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12775 .setup = alc262_hippo_setup,
12776 .init_hook = alc262_hippo_automute,
83c34218
KY
12777 },
12778 [ALC262_BENQ_T31] = {
12779 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12780 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12781 alc_hp15_unsol_verbs },
83c34218
KY
12782 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12783 .dac_nids = alc262_dac_nids,
12784 .hp_nid = 0x03,
12785 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12786 .channel_mode = alc262_modes,
12787 .input_mux = &alc262_capture_source,
12788 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12789 .setup = alc262_hippo_setup,
12790 .init_hook = alc262_hippo_automute,
ea1fb29a 12791 },
f651b50b 12792 [ALC262_ULTRA] = {
f9e336f6
TI
12793 .mixers = { alc262_ultra_mixer },
12794 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12795 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12796 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12797 .dac_nids = alc262_dac_nids,
f651b50b
TD
12798 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12799 .channel_mode = alc262_modes,
12800 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12801 .adc_nids = alc262_adc_nids, /* ADC0 */
12802 .capsrc_nids = alc262_capsrc_nids,
12803 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12804 .unsol_event = alc262_ultra_unsol_event,
12805 .init_hook = alc262_ultra_automute,
12806 },
0e31daf7
J
12807 [ALC262_LENOVO_3000] = {
12808 .mixers = { alc262_lenovo_3000_mixer },
12809 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12810 alc262_lenovo_3000_unsol_verbs,
12811 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12812 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12813 .dac_nids = alc262_dac_nids,
12814 .hp_nid = 0x03,
12815 .dig_out_nid = ALC262_DIGOUT_NID,
12816 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12817 .channel_mode = alc262_modes,
12818 .input_mux = &alc262_fujitsu_capture_source,
12819 .unsol_event = alc262_lenovo_3000_unsol_event,
12820 },
e8f9ae2a
PT
12821 [ALC262_NEC] = {
12822 .mixers = { alc262_nec_mixer },
12823 .init_verbs = { alc262_nec_verbs },
12824 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12825 .dac_nids = alc262_dac_nids,
12826 .hp_nid = 0x03,
12827 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12828 .channel_mode = alc262_modes,
12829 .input_mux = &alc262_capture_source,
12830 },
4e555fe5
KY
12831 [ALC262_TOSHIBA_S06] = {
12832 .mixers = { alc262_toshiba_s06_mixer },
12833 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12834 alc262_eapd_verbs },
12835 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12836 .capsrc_nids = alc262_dmic_capsrc_nids,
12837 .dac_nids = alc262_dac_nids,
12838 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12839 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12840 .dig_out_nid = ALC262_DIGOUT_NID,
12841 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12842 .channel_mode = alc262_modes,
4f5d1706
TI
12843 .unsol_event = alc_sku_unsol_event,
12844 .setup = alc262_toshiba_s06_setup,
12845 .init_hook = alc_inithook,
4e555fe5 12846 },
9f99a638
HM
12847 [ALC262_TOSHIBA_RX1] = {
12848 .mixers = { alc262_toshiba_rx1_mixer },
12849 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12850 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12851 .dac_nids = alc262_dac_nids,
12852 .hp_nid = 0x03,
12853 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12854 .channel_mode = alc262_modes,
12855 .input_mux = &alc262_capture_source,
12856 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12857 .setup = alc262_hippo_setup,
12858 .init_hook = alc262_hippo_automute,
9f99a638 12859 },
ba340e82
TV
12860 [ALC262_TYAN] = {
12861 .mixers = { alc262_tyan_mixer },
12862 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12863 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12864 .dac_nids = alc262_dac_nids,
12865 .hp_nid = 0x02,
12866 .dig_out_nid = ALC262_DIGOUT_NID,
12867 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12868 .channel_mode = alc262_modes,
12869 .input_mux = &alc262_capture_source,
a9fd4f3f 12870 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12871 .setup = alc262_tyan_setup,
12872 .init_hook = alc_automute_amp,
ba340e82 12873 },
df694daa
KY
12874};
12875
12876static int patch_alc262(struct hda_codec *codec)
12877{
12878 struct alc_spec *spec;
12879 int board_config;
12880 int err;
12881
dc041e0b 12882 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12883 if (spec == NULL)
12884 return -ENOMEM;
12885
12886 codec->spec = spec;
12887#if 0
f12ab1e0
TI
12888 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12889 * under-run
12890 */
df694daa
KY
12891 {
12892 int tmp;
12893 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12894 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12895 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12896 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12897 }
12898#endif
da00c244 12899 alc_auto_parse_customize_define(codec);
df694daa 12900
2c3bf9ab
TI
12901 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12902
f5fcc13c
TI
12903 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12904 alc262_models,
12905 alc262_cfg_tbl);
cd7509a4 12906
f5fcc13c 12907 if (board_config < 0) {
9a11f1aa
TI
12908 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12909 codec->chip_name);
df694daa
KY
12910 board_config = ALC262_AUTO;
12911 }
12912
b5bfbc67
TI
12913 if (board_config == ALC262_AUTO) {
12914 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12915 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12916 }
18675e42 12917
df694daa
KY
12918 if (board_config == ALC262_AUTO) {
12919 /* automatic parse from the BIOS config */
12920 err = alc262_parse_auto_config(codec);
12921 if (err < 0) {
12922 alc_free(codec);
12923 return err;
f12ab1e0 12924 } else if (!err) {
9c7f852e
TI
12925 printk(KERN_INFO
12926 "hda_codec: Cannot set up configuration "
12927 "from BIOS. Using base mode...\n");
df694daa
KY
12928 board_config = ALC262_BASIC;
12929 }
12930 }
12931
dc1eae25 12932 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12933 err = snd_hda_attach_beep_device(codec, 0x1);
12934 if (err < 0) {
12935 alc_free(codec);
12936 return err;
12937 }
680cd536
KK
12938 }
12939
df694daa 12940 if (board_config != ALC262_AUTO)
e9c364c0 12941 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12942
df694daa
KY
12943 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12944 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12945
df694daa
KY
12946 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12947 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12948
f12ab1e0 12949 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12950 int i;
12951 /* check whether the digital-mic has to be supported */
12952 for (i = 0; i < spec->input_mux->num_items; i++) {
12953 if (spec->input_mux->items[i].index >= 9)
12954 break;
12955 }
12956 if (i < spec->input_mux->num_items) {
12957 /* use only ADC0 */
12958 spec->adc_nids = alc262_dmic_adc_nids;
12959 spec->num_adc_nids = 1;
12960 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12961 } else {
8c927b4a
TI
12962 /* all analog inputs */
12963 /* check whether NID 0x07 is valid */
12964 unsigned int wcap = get_wcaps(codec, 0x07);
12965
12966 /* get type */
a22d543a 12967 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12968 if (wcap != AC_WID_AUD_IN) {
12969 spec->adc_nids = alc262_adc_nids_alt;
12970 spec->num_adc_nids =
12971 ARRAY_SIZE(alc262_adc_nids_alt);
12972 spec->capsrc_nids = alc262_capsrc_nids_alt;
12973 } else {
12974 spec->adc_nids = alc262_adc_nids;
12975 spec->num_adc_nids =
12976 ARRAY_SIZE(alc262_adc_nids);
12977 spec->capsrc_nids = alc262_capsrc_nids;
12978 }
df694daa
KY
12979 }
12980 }
e64f14f4 12981 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12982 set_capture_mixer(codec);
dc1eae25 12983 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 12984 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12985
b5bfbc67 12986 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18675e42 12987
2134ea4f
TI
12988 spec->vmaster_nid = 0x0c;
12989
df694daa
KY
12990 codec->patch_ops = alc_patch_ops;
12991 if (board_config == ALC262_AUTO)
ae6b813a 12992 spec->init_hook = alc262_auto_init;
bf1b0225
KY
12993
12994 alc_init_jacks(codec);
cb53c626
TI
12995#ifdef CONFIG_SND_HDA_POWER_SAVE
12996 if (!spec->loopback.amplist)
12997 spec->loopback.amplist = alc262_loopbacks;
12998#endif
ea1fb29a 12999
df694daa
KY
13000 return 0;
13001}
13002
a361d84b
KY
13003/*
13004 * ALC268 channel source setting (2 channel)
13005 */
13006#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13007#define alc268_modes alc260_modes
ea1fb29a 13008
a361d84b
KY
13009static hda_nid_t alc268_dac_nids[2] = {
13010 /* front, hp */
13011 0x02, 0x03
13012};
13013
13014static hda_nid_t alc268_adc_nids[2] = {
13015 /* ADC0-1 */
13016 0x08, 0x07
13017};
13018
13019static hda_nid_t alc268_adc_nids_alt[1] = {
13020 /* ADC0 */
13021 0x08
13022};
13023
e1406348
TI
13024static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13025
a361d84b
KY
13026static struct snd_kcontrol_new alc268_base_mixer[] = {
13027 /* output mixer control */
13028 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13029 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13030 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13031 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13032 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13033 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13034 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
a361d84b
KY
13035 { }
13036};
13037
42171c17
TI
13038static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13039 /* output mixer control */
13040 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13041 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13042 ALC262_HIPPO_MASTER_SWITCH,
5f99f86a
DH
13043 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13044 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13045 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
42171c17
TI
13046 { }
13047};
13048
aef9d318
TI
13049/* bind Beep switches of both NID 0x0f and 0x10 */
13050static struct hda_bind_ctls alc268_bind_beep_sw = {
13051 .ops = &snd_hda_bind_sw,
13052 .values = {
13053 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13054 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13055 0
13056 },
13057};
13058
13059static struct snd_kcontrol_new alc268_beep_mixer[] = {
13060 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13061 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13062 { }
13063};
13064
d1a991a6
KY
13065static struct hda_verb alc268_eapd_verbs[] = {
13066 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13067 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13068 { }
13069};
13070
d273809e 13071/* Toshiba specific */
d273809e
TI
13072static struct hda_verb alc268_toshiba_verbs[] = {
13073 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13074 { } /* end */
13075};
13076
13077/* Acer specific */
889c4395 13078/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
13079static struct hda_bind_ctls alc268_acer_bind_master_vol = {
13080 .ops = &snd_hda_bind_vol,
13081 .values = {
13082 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13083 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13084 0
13085 },
13086};
13087
889c4395
TI
13088/* mute/unmute internal speaker according to the hp jack and mute state */
13089static void alc268_acer_automute(struct hda_codec *codec, int force)
13090{
13091 struct alc_spec *spec = codec->spec;
13092 unsigned int mute;
13093
13094 if (force || !spec->sense_updated) {
864f92be 13095 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
13096 spec->sense_updated = 1;
13097 }
13098 if (spec->jack_present)
13099 mute = HDA_AMP_MUTE; /* mute internal speaker */
13100 else /* unmute internal speaker if necessary */
13101 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13102 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13103 HDA_AMP_MUTE, mute);
13104}
13105
13106
13107/* bind hp and internal speaker mute (with plug check) */
13108static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
13109 struct snd_ctl_elem_value *ucontrol)
13110{
13111 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
13112 long *valp = ucontrol->value.integer.value;
13113 int change;
13114
8de56b7d 13115 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
13116 if (change)
13117 alc268_acer_automute(codec, 0);
13118 return change;
13119}
d273809e 13120
8ef355da
KY
13121static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13122 /* output mixer control */
13123 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13124 {
13125 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13126 .name = "Master Playback Switch",
5e26dfd0 13127 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
13128 .info = snd_hda_mixer_amp_switch_info,
13129 .get = snd_hda_mixer_amp_switch_get,
13130 .put = alc268_acer_master_sw_put,
13131 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13132 },
13133 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13134 { }
13135};
13136
d273809e
TI
13137static struct snd_kcontrol_new alc268_acer_mixer[] = {
13138 /* output mixer control */
13139 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13140 {
13141 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13142 .name = "Master Playback Switch",
5e26dfd0 13143 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
13144 .info = snd_hda_mixer_amp_switch_info,
13145 .get = snd_hda_mixer_amp_switch_get,
13146 .put = alc268_acer_master_sw_put,
13147 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13148 },
5f99f86a
DH
13149 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13150 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13151 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
d273809e
TI
13152 { }
13153};
13154
c238b4f4
TI
13155static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13156 /* output mixer control */
13157 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13158 {
13159 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13160 .name = "Master Playback Switch",
5e26dfd0 13161 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
13162 .info = snd_hda_mixer_amp_switch_info,
13163 .get = snd_hda_mixer_amp_switch_get,
13164 .put = alc268_acer_master_sw_put,
13165 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13166 },
5f99f86a
DH
13167 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13168 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
c238b4f4
TI
13169 { }
13170};
13171
8ef355da
KY
13172static struct hda_verb alc268_acer_aspire_one_verbs[] = {
13173 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13174 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13175 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13176 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13177 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13178 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13179 { }
13180};
13181
d273809e 13182static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13183 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13184 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13185 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13186 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13187 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13188 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13189 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13190 { }
13191};
13192
13193/* unsolicited event for HP jack sensing */
42171c17 13194#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
13195#define alc268_toshiba_setup alc262_hippo_setup
13196#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
13197
13198static void alc268_acer_unsol_event(struct hda_codec *codec,
13199 unsigned int res)
13200{
889c4395 13201 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
13202 return;
13203 alc268_acer_automute(codec, 1);
13204}
13205
889c4395
TI
13206static void alc268_acer_init_hook(struct hda_codec *codec)
13207{
13208 alc268_acer_automute(codec, 1);
13209}
13210
8ef355da
KY
13211/* toggle speaker-output according to the hp-jack state */
13212static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
13213{
13214 unsigned int present;
13215 unsigned char bits;
13216
864f92be 13217 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13218 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 13219 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 13220 HDA_AMP_MUTE, bits);
8ef355da 13221 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 13222 HDA_AMP_MUTE, bits);
8ef355da
KY
13223}
13224
8ef355da
KY
13225static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
13226 unsigned int res)
13227{
4f5d1706
TI
13228 switch (res >> 26) {
13229 case ALC880_HP_EVENT:
8ef355da 13230 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
13231 break;
13232 case ALC880_MIC_EVENT:
13233 alc_mic_automute(codec);
13234 break;
13235 }
13236}
13237
13238static void alc268_acer_lc_setup(struct hda_codec *codec)
13239{
13240 struct alc_spec *spec = codec->spec;
13241 spec->ext_mic.pin = 0x18;
13242 spec->ext_mic.mux_idx = 0;
13243 spec->int_mic.pin = 0x12;
13244 spec->int_mic.mux_idx = 6;
13245 spec->auto_mic = 1;
8ef355da
KY
13246}
13247
13248static void alc268_acer_lc_init_hook(struct hda_codec *codec)
13249{
13250 alc268_aspire_one_speaker_automute(codec);
4f5d1706 13251 alc_mic_automute(codec);
8ef355da
KY
13252}
13253
3866f0b0
TI
13254static struct snd_kcontrol_new alc268_dell_mixer[] = {
13255 /* output mixer control */
13256 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13257 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13258 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13259 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13260 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13261 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
3866f0b0
TI
13262 { }
13263};
13264
13265static struct hda_verb alc268_dell_verbs[] = {
13266 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13267 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13268 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 13269 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
13270 { }
13271};
13272
13273/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 13274static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 13275{
a9fd4f3f 13276 struct alc_spec *spec = codec->spec;
3866f0b0 13277
a9fd4f3f
TI
13278 spec->autocfg.hp_pins[0] = 0x15;
13279 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13280 spec->ext_mic.pin = 0x18;
13281 spec->ext_mic.mux_idx = 0;
13282 spec->int_mic.pin = 0x19;
13283 spec->int_mic.mux_idx = 1;
13284 spec->auto_mic = 1;
3866f0b0
TI
13285}
13286
eb5a6621
HRK
13287static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13288 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13289 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13290 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13291 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13292 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13293 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
5f99f86a
DH
13294 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13295 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
eb5a6621
HRK
13296 { }
13297};
13298
13299static struct hda_verb alc267_quanta_il1_verbs[] = {
13300 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13301 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13302 { }
13303};
13304
4f5d1706 13305static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 13306{
a9fd4f3f 13307 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
13308 spec->autocfg.hp_pins[0] = 0x15;
13309 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13310 spec->ext_mic.pin = 0x18;
13311 spec->ext_mic.mux_idx = 0;
13312 spec->int_mic.pin = 0x19;
13313 spec->int_mic.mux_idx = 1;
13314 spec->auto_mic = 1;
eb5a6621
HRK
13315}
13316
a361d84b
KY
13317/*
13318 * generic initialization of ADC, input mixers and output mixers
13319 */
13320static struct hda_verb alc268_base_init_verbs[] = {
13321 /* Unmute DAC0-1 and set vol = 0 */
13322 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 13323 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13324
13325 /*
13326 * Set up output mixers (0x0c - 0x0e)
13327 */
13328 /* set vol=0 to output mixers */
13329 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13330 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13331
13332 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13333 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13334
13335 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13336 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13337 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13338 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13339 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13340 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13341 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13342 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13343
13344 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13345 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13346 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13347 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13348 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13349
13350 /* set PCBEEP vol = 0, mute connections */
13351 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13352 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13353 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13354
a9b3aa8a 13355 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13356
a9b3aa8a
JZ
13357 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13358 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13359 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13360 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13361
a361d84b
KY
13362 { }
13363};
13364
13365/*
13366 * generic initialization of ADC, input mixers and output mixers
13367 */
13368static struct hda_verb alc268_volume_init_verbs[] = {
13369 /* set output DAC */
4cfb91c6
TI
13370 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13371 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13372
13373 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13374 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13375 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13376 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13377 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13378
a361d84b 13379 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13380 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13381 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13382
13383 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13384 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13385
aef9d318
TI
13386 /* set PCBEEP vol = 0, mute connections */
13387 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13388 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13389 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13390
13391 { }
13392};
13393
fdbc6626
TI
13394static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13395 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13396 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13397 { } /* end */
13398};
13399
a361d84b
KY
13400static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13401 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13402 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13403 _DEFINE_CAPSRC(1),
a361d84b
KY
13404 { } /* end */
13405};
13406
13407static struct snd_kcontrol_new alc268_capture_mixer[] = {
13408 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13409 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13410 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13411 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13412 _DEFINE_CAPSRC(2),
a361d84b
KY
13413 { } /* end */
13414};
13415
13416static struct hda_input_mux alc268_capture_source = {
13417 .num_items = 4,
13418 .items = {
13419 { "Mic", 0x0 },
13420 { "Front Mic", 0x1 },
13421 { "Line", 0x2 },
13422 { "CD", 0x3 },
13423 },
13424};
13425
0ccb541c 13426static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13427 .num_items = 3,
13428 .items = {
13429 { "Mic", 0x0 },
13430 { "Internal Mic", 0x1 },
13431 { "Line", 0x2 },
13432 },
13433};
13434
13435static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13436 .num_items = 3,
13437 .items = {
13438 { "Mic", 0x0 },
13439 { "Internal Mic", 0x6 },
13440 { "Line", 0x2 },
13441 },
13442};
13443
86c53bd2
JW
13444#ifdef CONFIG_SND_DEBUG
13445static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13446 /* Volume widgets */
13447 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13448 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13449 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13450 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13451 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13452 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13453 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13454 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13455 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13456 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13457 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13458 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13459 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13460 /* The below appears problematic on some hardwares */
13461 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13462 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13463 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13464 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13465 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13466
13467 /* Modes for retasking pin widgets */
13468 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13469 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13470 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13471 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13472
13473 /* Controls for GPIO pins, assuming they are configured as outputs */
13474 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13475 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13476 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13477 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13478
13479 /* Switches to allow the digital SPDIF output pin to be enabled.
13480 * The ALC268 does not have an SPDIF input.
13481 */
13482 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13483
13484 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13485 * this output to turn on an external amplifier.
13486 */
13487 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13488 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13489
13490 { } /* end */
13491};
13492#endif
13493
a361d84b
KY
13494/* create input playback/capture controls for the given pin */
13495static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13496 const char *ctlname, int idx)
13497{
3f3b7c1a 13498 hda_nid_t dac;
a361d84b
KY
13499 int err;
13500
3f3b7c1a
TI
13501 switch (nid) {
13502 case 0x14:
13503 case 0x16:
13504 dac = 0x02;
13505 break;
13506 case 0x15:
b08b1637
TI
13507 case 0x1a: /* ALC259/269 only */
13508 case 0x1b: /* ALC259/269 only */
531d8791 13509 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13510 dac = 0x03;
13511 break;
13512 default:
c7a9434d
TI
13513 snd_printd(KERN_WARNING "hda_codec: "
13514 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13515 return 0;
13516 }
13517 if (spec->multiout.dac_nids[0] != dac &&
13518 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13519 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13520 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13521 HDA_OUTPUT));
13522 if (err < 0)
13523 return err;
3f3b7c1a
TI
13524 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13525 }
13526
3f3b7c1a 13527 if (nid != 0x16)
0afe5f89 13528 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13529 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13530 else /* mono */
0afe5f89 13531 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13532 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13533 if (err < 0)
13534 return err;
13535 return 0;
13536}
13537
13538/* add playback controls from the parsed DAC table */
13539static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13540 const struct auto_pin_cfg *cfg)
13541{
13542 hda_nid_t nid;
13543 int err;
13544
a361d84b 13545 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13546
13547 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13548 if (nid) {
13549 const char *name;
13550 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13551 name = "Speaker";
13552 else
13553 name = "Front";
13554 err = alc268_new_analog_output(spec, nid, name, 0);
13555 if (err < 0)
13556 return err;
13557 }
a361d84b
KY
13558
13559 nid = cfg->speaker_pins[0];
13560 if (nid == 0x1d) {
0afe5f89 13561 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13562 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13563 if (err < 0)
13564 return err;
7bfb9c03 13565 } else if (nid) {
3f3b7c1a
TI
13566 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13567 if (err < 0)
13568 return err;
a361d84b
KY
13569 }
13570 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13571 if (nid) {
13572 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13573 if (err < 0)
13574 return err;
13575 }
a361d84b
KY
13576
13577 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13578 if (nid == 0x16) {
0afe5f89 13579 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13580 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13581 if (err < 0)
13582 return err;
13583 }
ea1fb29a 13584 return 0;
a361d84b
KY
13585}
13586
13587/* create playback/capture controls for input pins */
05f5f477 13588static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13589 const struct auto_pin_cfg *cfg)
13590{
05f5f477 13591 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13592}
13593
e9af4f36
TI
13594static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13595 hda_nid_t nid, int pin_type)
13596{
13597 int idx;
13598
13599 alc_set_pin_output(codec, nid, pin_type);
13600 if (nid == 0x14 || nid == 0x16)
13601 idx = 0;
13602 else
13603 idx = 1;
13604 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13605}
13606
13607static void alc268_auto_init_multi_out(struct hda_codec *codec)
13608{
13609 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13610 int i;
13611
13612 for (i = 0; i < spec->autocfg.line_outs; i++) {
13613 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13614 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13615 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13616 }
13617}
13618
13619static void alc268_auto_init_hp_out(struct hda_codec *codec)
13620{
13621 struct alc_spec *spec = codec->spec;
13622 hda_nid_t pin;
e1ca7b4e 13623 int i;
e9af4f36 13624
e1ca7b4e
TI
13625 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13626 pin = spec->autocfg.hp_pins[i];
e9af4f36 13627 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13628 }
13629 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13630 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13631 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13632 }
13633 if (spec->autocfg.mono_out_pin)
13634 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13635 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36
TI
13636}
13637
a361d84b
KY
13638static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13639{
13640 struct alc_spec *spec = codec->spec;
13641 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13642 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13643 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13644 unsigned int dac_vol1, dac_vol2;
13645
e9af4f36 13646 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13647 snd_hda_codec_write(codec, speaker_nid, 0,
13648 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13649 /* mute mixer inputs from 0x1d */
a361d84b
KY
13650 snd_hda_codec_write(codec, 0x0f, 0,
13651 AC_VERB_SET_AMP_GAIN_MUTE,
13652 AMP_IN_UNMUTE(1));
13653 snd_hda_codec_write(codec, 0x10, 0,
13654 AC_VERB_SET_AMP_GAIN_MUTE,
13655 AMP_IN_UNMUTE(1));
13656 } else {
e9af4f36 13657 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13658 snd_hda_codec_write(codec, 0x0f, 0,
13659 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13660 snd_hda_codec_write(codec, 0x10, 0,
13661 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13662 }
13663
13664 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13665 if (line_nid == 0x14)
a361d84b
KY
13666 dac_vol2 = AMP_OUT_ZERO;
13667 else if (line_nid == 0x15)
13668 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13669 if (hp_nid == 0x14)
a361d84b
KY
13670 dac_vol2 = AMP_OUT_ZERO;
13671 else if (hp_nid == 0x15)
13672 dac_vol1 = AMP_OUT_ZERO;
13673 if (line_nid != 0x16 || hp_nid != 0x16 ||
13674 spec->autocfg.line_out_pins[1] != 0x16 ||
13675 spec->autocfg.line_out_pins[2] != 0x16)
13676 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13677
13678 snd_hda_codec_write(codec, 0x02, 0,
13679 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13680 snd_hda_codec_write(codec, 0x03, 0,
13681 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13682}
13683
def319f9 13684/* pcm configuration: identical with ALC880 */
a361d84b
KY
13685#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13686#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13687#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13688#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13689
13690/*
13691 * BIOS auto configuration
13692 */
13693static int alc268_parse_auto_config(struct hda_codec *codec)
13694{
13695 struct alc_spec *spec = codec->spec;
13696 int err;
13697 static hda_nid_t alc268_ignore[] = { 0 };
13698
13699 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13700 alc268_ignore);
13701 if (err < 0)
13702 return err;
7e0e44d4
TI
13703 if (!spec->autocfg.line_outs) {
13704 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13705 spec->multiout.max_channels = 2;
13706 spec->no_analog = 1;
13707 goto dig_only;
13708 }
a361d84b 13709 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13710 }
a361d84b
KY
13711 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13712 if (err < 0)
13713 return err;
05f5f477 13714 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13715 if (err < 0)
13716 return err;
13717
13718 spec->multiout.max_channels = 2;
13719
7e0e44d4 13720 dig_only:
a361d84b 13721 /* digital only support output */
757899ac 13722 alc_auto_parse_digital(codec);
603c4019 13723 if (spec->kctls.list)
d88897ea 13724 add_mixer(spec, spec->kctls.list);
a361d84b 13725
892981ff 13726 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13727 add_mixer(spec, alc268_beep_mixer);
aef9d318 13728
d88897ea 13729 add_verb(spec, alc268_volume_init_verbs);
5908589f 13730 spec->num_mux_defs = 2;
61b9b9b1 13731 spec->input_mux = &spec->private_imux[0];
a361d84b 13732
776e184e
TI
13733 err = alc_auto_add_mic_boost(codec);
13734 if (err < 0)
13735 return err;
13736
6227cdce 13737 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13738
a361d84b
KY
13739 return 1;
13740}
13741
a361d84b
KY
13742#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13743
13744/* init callback for auto-configuration model -- overriding the default init */
13745static void alc268_auto_init(struct hda_codec *codec)
13746{
f6c7e546 13747 struct alc_spec *spec = codec->spec;
a361d84b
KY
13748 alc268_auto_init_multi_out(codec);
13749 alc268_auto_init_hp_out(codec);
13750 alc268_auto_init_mono_speaker_out(codec);
13751 alc268_auto_init_analog_input(codec);
757899ac 13752 alc_auto_init_digital(codec);
f6c7e546 13753 if (spec->unsol_event)
7fb0d78f 13754 alc_inithook(codec);
a361d84b
KY
13755}
13756
13757/*
13758 * configuration and preset
13759 */
ea734963 13760static const char * const alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13761 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13762 [ALC268_3ST] = "3stack",
983f8ae4 13763 [ALC268_TOSHIBA] = "toshiba",
d273809e 13764 [ALC268_ACER] = "acer",
c238b4f4 13765 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13766 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13767 [ALC268_DELL] = "dell",
f12462c5 13768 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13769#ifdef CONFIG_SND_DEBUG
13770 [ALC268_TEST] = "test",
13771#endif
a361d84b
KY
13772 [ALC268_AUTO] = "auto",
13773};
13774
13775static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13776 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13777 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13778 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13779 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13780 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13781 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13782 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13783 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13784 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13785 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13786 /* almost compatible with toshiba but with optional digital outs;
13787 * auto-probing seems working fine
13788 */
8871e5b9 13789 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13790 ALC268_AUTO),
a361d84b 13791 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13792 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13793 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13794 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13795 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13796 {}
13797};
13798
3abf2f36
TI
13799/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13800static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13801 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13802 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13803 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13804 ALC268_TOSHIBA),
13805 {}
13806};
13807
a361d84b 13808static struct alc_config_preset alc268_presets[] = {
eb5a6621 13809 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13810 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13811 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13812 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13813 alc267_quanta_il1_verbs },
13814 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13815 .dac_nids = alc268_dac_nids,
13816 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13817 .adc_nids = alc268_adc_nids_alt,
13818 .hp_nid = 0x03,
13819 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13820 .channel_mode = alc268_modes,
4f5d1706
TI
13821 .unsol_event = alc_sku_unsol_event,
13822 .setup = alc267_quanta_il1_setup,
13823 .init_hook = alc_inithook,
eb5a6621 13824 },
a361d84b 13825 [ALC268_3ST] = {
aef9d318
TI
13826 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13827 alc268_beep_mixer },
a361d84b
KY
13828 .init_verbs = { alc268_base_init_verbs },
13829 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13830 .dac_nids = alc268_dac_nids,
13831 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13832 .adc_nids = alc268_adc_nids_alt,
e1406348 13833 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13834 .hp_nid = 0x03,
13835 .dig_out_nid = ALC268_DIGOUT_NID,
13836 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13837 .channel_mode = alc268_modes,
13838 .input_mux = &alc268_capture_source,
13839 },
d1a991a6 13840 [ALC268_TOSHIBA] = {
42171c17 13841 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13842 alc268_beep_mixer },
d273809e
TI
13843 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13844 alc268_toshiba_verbs },
d1a991a6
KY
13845 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13846 .dac_nids = alc268_dac_nids,
13847 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13848 .adc_nids = alc268_adc_nids_alt,
e1406348 13849 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13850 .hp_nid = 0x03,
13851 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13852 .channel_mode = alc268_modes,
13853 .input_mux = &alc268_capture_source,
d273809e 13854 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13855 .setup = alc268_toshiba_setup,
13856 .init_hook = alc268_toshiba_automute,
d273809e
TI
13857 },
13858 [ALC268_ACER] = {
432fd133 13859 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13860 alc268_beep_mixer },
d273809e
TI
13861 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13862 alc268_acer_verbs },
13863 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13864 .dac_nids = alc268_dac_nids,
13865 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13866 .adc_nids = alc268_adc_nids_alt,
e1406348 13867 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13868 .hp_nid = 0x02,
13869 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13870 .channel_mode = alc268_modes,
0ccb541c 13871 .input_mux = &alc268_acer_capture_source,
d273809e 13872 .unsol_event = alc268_acer_unsol_event,
889c4395 13873 .init_hook = alc268_acer_init_hook,
d1a991a6 13874 },
c238b4f4
TI
13875 [ALC268_ACER_DMIC] = {
13876 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13877 alc268_beep_mixer },
13878 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13879 alc268_acer_verbs },
13880 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13881 .dac_nids = alc268_dac_nids,
13882 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13883 .adc_nids = alc268_adc_nids_alt,
13884 .capsrc_nids = alc268_capsrc_nids,
13885 .hp_nid = 0x02,
13886 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13887 .channel_mode = alc268_modes,
13888 .input_mux = &alc268_acer_dmic_capture_source,
13889 .unsol_event = alc268_acer_unsol_event,
13890 .init_hook = alc268_acer_init_hook,
13891 },
8ef355da
KY
13892 [ALC268_ACER_ASPIRE_ONE] = {
13893 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13894 alc268_beep_mixer,
fdbc6626 13895 alc268_capture_nosrc_mixer },
8ef355da
KY
13896 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13897 alc268_acer_aspire_one_verbs },
13898 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13899 .dac_nids = alc268_dac_nids,
13900 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13901 .adc_nids = alc268_adc_nids_alt,
13902 .capsrc_nids = alc268_capsrc_nids,
13903 .hp_nid = 0x03,
13904 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13905 .channel_mode = alc268_modes,
8ef355da 13906 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13907 .setup = alc268_acer_lc_setup,
8ef355da
KY
13908 .init_hook = alc268_acer_lc_init_hook,
13909 },
3866f0b0 13910 [ALC268_DELL] = {
fdbc6626
TI
13911 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13912 alc268_capture_nosrc_mixer },
3866f0b0
TI
13913 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13914 alc268_dell_verbs },
13915 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13916 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13917 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13918 .adc_nids = alc268_adc_nids_alt,
13919 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13920 .hp_nid = 0x02,
13921 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13922 .channel_mode = alc268_modes,
a9fd4f3f 13923 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13924 .setup = alc268_dell_setup,
13925 .init_hook = alc_inithook,
3866f0b0 13926 },
f12462c5 13927 [ALC268_ZEPTO] = {
aef9d318
TI
13928 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13929 alc268_beep_mixer },
f12462c5
MT
13930 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13931 alc268_toshiba_verbs },
13932 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13933 .dac_nids = alc268_dac_nids,
13934 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13935 .adc_nids = alc268_adc_nids_alt,
e1406348 13936 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13937 .hp_nid = 0x03,
13938 .dig_out_nid = ALC268_DIGOUT_NID,
13939 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13940 .channel_mode = alc268_modes,
13941 .input_mux = &alc268_capture_source,
4f5d1706
TI
13942 .setup = alc268_toshiba_setup,
13943 .init_hook = alc268_toshiba_automute,
f12462c5 13944 },
86c53bd2
JW
13945#ifdef CONFIG_SND_DEBUG
13946 [ALC268_TEST] = {
13947 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13948 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13949 alc268_volume_init_verbs },
13950 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13951 .dac_nids = alc268_dac_nids,
13952 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13953 .adc_nids = alc268_adc_nids_alt,
e1406348 13954 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13955 .hp_nid = 0x03,
13956 .dig_out_nid = ALC268_DIGOUT_NID,
13957 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13958 .channel_mode = alc268_modes,
13959 .input_mux = &alc268_capture_source,
13960 },
13961#endif
a361d84b
KY
13962};
13963
13964static int patch_alc268(struct hda_codec *codec)
13965{
13966 struct alc_spec *spec;
13967 int board_config;
22971e3a 13968 int i, has_beep, err;
a361d84b 13969
ef86f581 13970 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13971 if (spec == NULL)
13972 return -ENOMEM;
13973
13974 codec->spec = spec;
13975
13976 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13977 alc268_models,
13978 alc268_cfg_tbl);
13979
3abf2f36
TI
13980 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13981 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13982 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13983
a361d84b 13984 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13985 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13986 codec->chip_name);
a361d84b
KY
13987 board_config = ALC268_AUTO;
13988 }
13989
13990 if (board_config == ALC268_AUTO) {
13991 /* automatic parse from the BIOS config */
13992 err = alc268_parse_auto_config(codec);
13993 if (err < 0) {
13994 alc_free(codec);
13995 return err;
13996 } else if (!err) {
13997 printk(KERN_INFO
13998 "hda_codec: Cannot set up configuration "
13999 "from BIOS. Using base mode...\n");
14000 board_config = ALC268_3ST;
14001 }
14002 }
14003
14004 if (board_config != ALC268_AUTO)
e9c364c0 14005 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 14006
a361d84b
KY
14007 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14008 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 14009 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 14010
a361d84b
KY
14011 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14012
22971e3a
TI
14013 has_beep = 0;
14014 for (i = 0; i < spec->num_mixers; i++) {
14015 if (spec->mixers[i] == alc268_beep_mixer) {
14016 has_beep = 1;
14017 break;
14018 }
14019 }
14020
14021 if (has_beep) {
14022 err = snd_hda_attach_beep_device(codec, 0x1);
14023 if (err < 0) {
14024 alc_free(codec);
14025 return err;
14026 }
14027 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14028 /* override the amp caps for beep generator */
14029 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
14030 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14031 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14032 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14033 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 14034 }
aef9d318 14035
7e0e44d4 14036 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
14037 /* check whether NID 0x07 is valid */
14038 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 14039 int i;
3866f0b0 14040
defb5ab2 14041 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 14042 /* get type */
a22d543a 14043 wcap = get_wcaps_type(wcap);
fdbc6626
TI
14044 if (spec->auto_mic ||
14045 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
14046 spec->adc_nids = alc268_adc_nids_alt;
14047 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
14048 if (spec->auto_mic)
14049 fixup_automic_adc(codec);
fdbc6626
TI
14050 if (spec->auto_mic || spec->input_mux->num_items == 1)
14051 add_mixer(spec, alc268_capture_nosrc_mixer);
14052 else
14053 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
14054 } else {
14055 spec->adc_nids = alc268_adc_nids;
14056 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 14057 add_mixer(spec, alc268_capture_mixer);
a361d84b 14058 }
85860c06
TI
14059 /* set default input source */
14060 for (i = 0; i < spec->num_adc_nids; i++)
14061 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
14062 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
14063 i < spec->num_mux_defs ?
14064 spec->input_mux[i].items[0].index :
85860c06 14065 spec->input_mux->items[0].index);
a361d84b 14066 }
2134ea4f
TI
14067
14068 spec->vmaster_nid = 0x02;
14069
a361d84b
KY
14070 codec->patch_ops = alc_patch_ops;
14071 if (board_config == ALC268_AUTO)
14072 spec->init_hook = alc268_auto_init;
ea1fb29a 14073
bf1b0225
KY
14074 alc_init_jacks(codec);
14075
a361d84b
KY
14076 return 0;
14077}
14078
f6a92248
KY
14079/*
14080 * ALC269 channel source setting (2 channel)
14081 */
14082#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14083
14084#define alc269_dac_nids alc260_dac_nids
14085
14086static hda_nid_t alc269_adc_nids[1] = {
14087 /* ADC1 */
f53281e6
KY
14088 0x08,
14089};
14090
e01bf509
TI
14091static hda_nid_t alc269_capsrc_nids[1] = {
14092 0x23,
14093};
14094
84898e87
KY
14095static hda_nid_t alc269vb_adc_nids[1] = {
14096 /* ADC1 */
14097 0x09,
14098};
14099
14100static hda_nid_t alc269vb_capsrc_nids[1] = {
14101 0x22,
14102};
14103
6694635d
TI
14104static hda_nid_t alc269_adc_candidates[] = {
14105 0x08, 0x09, 0x07,
14106};
e01bf509 14107
f6a92248
KY
14108#define alc269_modes alc260_modes
14109#define alc269_capture_source alc880_lg_lw_capture_source
14110
14111static struct snd_kcontrol_new alc269_base_mixer[] = {
14112 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14113 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14114 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14115 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14116 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14117 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14118 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f6a92248
KY
14119 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14120 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14121 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f6a92248
KY
14122 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14123 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14124 { } /* end */
14125};
14126
60db6b53
KY
14127static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14128 /* output mixer control */
14129 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14130 {
14131 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14132 .name = "Master Playback Switch",
5e26dfd0 14133 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
14134 .info = snd_hda_mixer_amp_switch_info,
14135 .get = snd_hda_mixer_amp_switch_get,
14136 .put = alc268_acer_master_sw_put,
14137 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14138 },
14139 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14140 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14141 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
60db6b53
KY
14142 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14143 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14144 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
60db6b53
KY
14145 { }
14146};
14147
64154835
TV
14148static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14149 /* output mixer control */
14150 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14151 {
14152 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14153 .name = "Master Playback Switch",
5e26dfd0 14154 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14155 .info = snd_hda_mixer_amp_switch_info,
14156 .get = snd_hda_mixer_amp_switch_get,
14157 .put = alc268_acer_master_sw_put,
14158 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14159 },
14160 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14161 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14162 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64154835
TV
14163 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14164 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14165 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
64154835
TV
14166 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14167 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
5f99f86a 14168 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
64154835
TV
14169 { }
14170};
14171
84898e87 14172static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14173 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14174 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14175 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14176 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14177 { } /* end */
14178};
14179
84898e87
KY
14180static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14181 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14182 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14183 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14184 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14185 { } /* end */
14186};
14187
fe3eb0a7
KY
14188static struct snd_kcontrol_new alc269_asus_mixer[] = {
14189 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14190 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14191 { } /* end */
14192};
14193
f53281e6 14194/* capture mixer elements */
84898e87
KY
14195static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14196 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14197 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a
DH
14198 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14199 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14200 { } /* end */
14201};
14202
14203static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14204 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14205 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a 14206 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
26f5df26
TI
14207 { } /* end */
14208};
14209
84898e87
KY
14210static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14211 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14212 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a
DH
14213 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14214 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14215 { } /* end */
14216};
14217
14218static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14219 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14220 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a 14221 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
84898e87
KY
14222 { } /* end */
14223};
14224
26f5df26 14225/* FSC amilo */
84898e87 14226#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14227
60db6b53
KY
14228static struct hda_verb alc269_quanta_fl1_verbs[] = {
14229 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14230 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14231 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14232 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14233 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14234 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14235 { }
14236};
f6a92248 14237
64154835
TV
14238static struct hda_verb alc269_lifebook_verbs[] = {
14239 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14240 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14241 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14242 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14243 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14244 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14245 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14246 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14247 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14248 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14249 { }
14250};
14251
60db6b53
KY
14252/* toggle speaker-output according to the hp-jack state */
14253static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14254{
14255 unsigned int present;
14256 unsigned char bits;
f6a92248 14257
864f92be 14258 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 14259 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 14260 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14261 HDA_AMP_MUTE, bits);
60db6b53 14262 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14263 HDA_AMP_MUTE, bits);
f6a92248 14264
60db6b53
KY
14265 snd_hda_codec_write(codec, 0x20, 0,
14266 AC_VERB_SET_COEF_INDEX, 0x0c);
14267 snd_hda_codec_write(codec, 0x20, 0,
14268 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 14269
60db6b53
KY
14270 snd_hda_codec_write(codec, 0x20, 0,
14271 AC_VERB_SET_COEF_INDEX, 0x0c);
14272 snd_hda_codec_write(codec, 0x20, 0,
14273 AC_VERB_SET_PROC_COEF, 0x480);
14274}
f6a92248 14275
64154835
TV
14276/* toggle speaker-output according to the hp-jacks state */
14277static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
14278{
14279 unsigned int present;
14280 unsigned char bits;
14281
14282 /* Check laptop headphone socket */
864f92be 14283 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
14284
14285 /* Check port replicator headphone socket */
864f92be 14286 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 14287
5dbd5ec6 14288 bits = present ? HDA_AMP_MUTE : 0;
64154835 14289 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14290 HDA_AMP_MUTE, bits);
64154835 14291 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14292 HDA_AMP_MUTE, bits);
64154835
TV
14293
14294 snd_hda_codec_write(codec, 0x20, 0,
14295 AC_VERB_SET_COEF_INDEX, 0x0c);
14296 snd_hda_codec_write(codec, 0x20, 0,
14297 AC_VERB_SET_PROC_COEF, 0x680);
14298
14299 snd_hda_codec_write(codec, 0x20, 0,
14300 AC_VERB_SET_COEF_INDEX, 0x0c);
14301 snd_hda_codec_write(codec, 0x20, 0,
14302 AC_VERB_SET_PROC_COEF, 0x480);
14303}
14304
64154835
TV
14305static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14306{
14307 unsigned int present_laptop;
14308 unsigned int present_dock;
14309
864f92be
WF
14310 present_laptop = snd_hda_jack_detect(codec, 0x18);
14311 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14312
14313 /* Laptop mic port overrides dock mic port, design decision */
14314 if (present_dock)
14315 snd_hda_codec_write(codec, 0x23, 0,
14316 AC_VERB_SET_CONNECT_SEL, 0x3);
14317 if (present_laptop)
14318 snd_hda_codec_write(codec, 0x23, 0,
14319 AC_VERB_SET_CONNECT_SEL, 0x0);
14320 if (!present_dock && !present_laptop)
14321 snd_hda_codec_write(codec, 0x23, 0,
14322 AC_VERB_SET_CONNECT_SEL, 0x1);
14323}
14324
60db6b53
KY
14325static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14326 unsigned int res)
14327{
4f5d1706
TI
14328 switch (res >> 26) {
14329 case ALC880_HP_EVENT:
60db6b53 14330 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14331 break;
14332 case ALC880_MIC_EVENT:
14333 alc_mic_automute(codec);
14334 break;
14335 }
60db6b53 14336}
f6a92248 14337
64154835
TV
14338static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14339 unsigned int res)
14340{
14341 if ((res >> 26) == ALC880_HP_EVENT)
14342 alc269_lifebook_speaker_automute(codec);
14343 if ((res >> 26) == ALC880_MIC_EVENT)
14344 alc269_lifebook_mic_autoswitch(codec);
14345}
14346
4f5d1706
TI
14347static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14348{
14349 struct alc_spec *spec = codec->spec;
20645d70
TI
14350 spec->autocfg.hp_pins[0] = 0x15;
14351 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14352 spec->ext_mic.pin = 0x18;
14353 spec->ext_mic.mux_idx = 0;
14354 spec->int_mic.pin = 0x19;
14355 spec->int_mic.mux_idx = 1;
14356 spec->auto_mic = 1;
14357}
14358
60db6b53
KY
14359static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14360{
14361 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14362 alc_mic_automute(codec);
60db6b53 14363}
f6a92248 14364
64154835
TV
14365static void alc269_lifebook_init_hook(struct hda_codec *codec)
14366{
14367 alc269_lifebook_speaker_automute(codec);
14368 alc269_lifebook_mic_autoswitch(codec);
14369}
14370
84898e87 14371static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14372 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14373 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14374 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14375 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14376 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14377 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14378 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14379 {}
14380};
14381
84898e87 14382static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14383 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14384 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14385 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14386 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14387 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14388 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14389 {}
14390};
14391
84898e87
KY
14392static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14393 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14394 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14395 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14396 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14397 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14398 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14399 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14400 {}
14401};
14402
14403static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14404 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14405 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14406 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14407 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14408 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14409 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14410 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14411 {}
14412};
14413
fe3eb0a7
KY
14414static struct hda_verb alc271_acer_dmic_verbs[] = {
14415 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14416 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14417 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14418 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14419 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14420 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14421 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14422 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14423 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14424 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14425 { }
14426};
14427
f53281e6
KY
14428/* toggle speaker-output according to the hp-jack state */
14429static void alc269_speaker_automute(struct hda_codec *codec)
14430{
ebb83eeb
KY
14431 struct alc_spec *spec = codec->spec;
14432 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 14433 unsigned int present;
60db6b53 14434 unsigned char bits;
f53281e6 14435
ebb83eeb 14436 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 14437 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 14438 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14439 HDA_AMP_MUTE, bits);
f53281e6 14440 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14441 HDA_AMP_MUTE, bits);
cd372fb3 14442 snd_hda_input_jack_report(codec, nid);
f53281e6
KY
14443}
14444
f53281e6 14445/* unsolicited event for HP jack sensing */
84898e87 14446static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 14447 unsigned int res)
f53281e6 14448{
4f5d1706
TI
14449 switch (res >> 26) {
14450 case ALC880_HP_EVENT:
f53281e6 14451 alc269_speaker_automute(codec);
4f5d1706
TI
14452 break;
14453 case ALC880_MIC_EVENT:
14454 alc_mic_automute(codec);
14455 break;
14456 }
f53281e6
KY
14457}
14458
226b1ec8 14459static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14460{
4f5d1706 14461 struct alc_spec *spec = codec->spec;
20645d70
TI
14462 spec->autocfg.hp_pins[0] = 0x15;
14463 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14464 spec->ext_mic.pin = 0x18;
14465 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14466 spec->int_mic.pin = 0x19;
14467 spec->int_mic.mux_idx = 1;
4f5d1706 14468 spec->auto_mic = 1;
f53281e6
KY
14469}
14470
226b1ec8 14471static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14472{
14473 struct alc_spec *spec = codec->spec;
20645d70
TI
14474 spec->autocfg.hp_pins[0] = 0x15;
14475 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
14476 spec->ext_mic.pin = 0x18;
14477 spec->ext_mic.mux_idx = 0;
14478 spec->int_mic.pin = 0x12;
226b1ec8 14479 spec->int_mic.mux_idx = 5;
84898e87
KY
14480 spec->auto_mic = 1;
14481}
14482
226b1ec8 14483static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14484{
4f5d1706 14485 struct alc_spec *spec = codec->spec;
226b1ec8 14486 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14487 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14488 spec->ext_mic.pin = 0x18;
14489 spec->ext_mic.mux_idx = 0;
14490 spec->int_mic.pin = 0x19;
14491 spec->int_mic.mux_idx = 1;
14492 spec->auto_mic = 1;
f53281e6
KY
14493}
14494
226b1ec8
KY
14495static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14496{
14497 struct alc_spec *spec = codec->spec;
14498 spec->autocfg.hp_pins[0] = 0x21;
14499 spec->autocfg.speaker_pins[0] = 0x14;
14500 spec->ext_mic.pin = 0x18;
14501 spec->ext_mic.mux_idx = 0;
14502 spec->int_mic.pin = 0x12;
14503 spec->int_mic.mux_idx = 6;
14504 spec->auto_mic = 1;
14505}
14506
84898e87 14507static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
14508{
14509 alc269_speaker_automute(codec);
4f5d1706 14510 alc_mic_automute(codec);
f53281e6
KY
14511}
14512
60db6b53
KY
14513/*
14514 * generic initialization of ADC, input mixers and output mixers
14515 */
14516static struct hda_verb alc269_init_verbs[] = {
14517 /*
14518 * Unmute ADC0 and set the default input to mic-in
14519 */
84898e87 14520 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14521
14522 /*
84898e87 14523 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14524 */
14525 /* set vol=0 to output mixers */
14526 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14527 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14528
14529 /* set up input amps for analog loopback */
14530 /* Amp Indices: DAC = 0, mixer = 1 */
14531 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14532 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14533 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14534 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14535 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14536 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14537
14538 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14539 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14540 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14541 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14542 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14543 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14544 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14545
14546 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14547 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14548
84898e87
KY
14549 /* FIXME: use Mux-type input source selection */
14550 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14551 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14552 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14553
84898e87
KY
14554 /* set EAPD */
14555 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14556 { }
14557};
14558
14559static struct hda_verb alc269vb_init_verbs[] = {
14560 /*
14561 * Unmute ADC0 and set the default input to mic-in
14562 */
14563 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14564
14565 /*
14566 * Set up output mixers (0x02 - 0x03)
14567 */
14568 /* set vol=0 to output mixers */
14569 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14570 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14571
14572 /* set up input amps for analog loopback */
14573 /* Amp Indices: DAC = 0, mixer = 1 */
14574 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14575 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14576 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14577 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14578 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14579 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14580
14581 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14582 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14583 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14584 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14585 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14586 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14587 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14588
14589 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14590 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14591
14592 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14593 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14594 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14595 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14596
14597 /* set EAPD */
14598 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14599 { }
14600};
14601
9d0b71b1
TI
14602#define alc269_auto_create_multi_out_ctls \
14603 alc268_auto_create_multi_out_ctls
05f5f477
TI
14604#define alc269_auto_create_input_ctls \
14605 alc268_auto_create_input_ctls
f6a92248
KY
14606
14607#ifdef CONFIG_SND_HDA_POWER_SAVE
14608#define alc269_loopbacks alc880_loopbacks
14609#endif
14610
def319f9 14611/* pcm configuration: identical with ALC880 */
f6a92248
KY
14612#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14613#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14614#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14615#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14616
f03d3115
TI
14617static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14618 .substreams = 1,
14619 .channels_min = 2,
14620 .channels_max = 8,
14621 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14622 /* NID is set in alc_build_pcms */
14623 .ops = {
14624 .open = alc880_playback_pcm_open,
14625 .prepare = alc880_playback_pcm_prepare,
14626 .cleanup = alc880_playback_pcm_cleanup
14627 },
14628};
14629
14630static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14631 .substreams = 1,
14632 .channels_min = 2,
14633 .channels_max = 2,
14634 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14635 /* NID is set in alc_build_pcms */
14636};
14637
ad35879a
TI
14638#ifdef CONFIG_SND_HDA_POWER_SAVE
14639static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14640{
14641 switch (codec->subsystem_id) {
14642 case 0x103c1586:
14643 return 1;
14644 }
14645 return 0;
14646}
14647
14648static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14649{
14650 /* update mute-LED according to the speaker mute state */
14651 if (nid == 0x01 || nid == 0x14) {
14652 int pinval;
14653 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14654 HDA_AMP_MUTE)
14655 pinval = 0x24;
14656 else
14657 pinval = 0x20;
14658 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14659 snd_hda_codec_update_cache(codec, 0x19, 0,
14660 AC_VERB_SET_PIN_WIDGET_CONTROL,
14661 pinval);
ad35879a
TI
14662 }
14663 return alc_check_power_status(codec, nid);
14664}
14665#endif /* CONFIG_SND_HDA_POWER_SAVE */
14666
840b64c0
TI
14667static int alc275_setup_dual_adc(struct hda_codec *codec)
14668{
14669 struct alc_spec *spec = codec->spec;
14670
14671 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14672 return 0;
14673 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14674 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14675 if (spec->ext_mic.pin <= 0x12) {
14676 spec->private_adc_nids[0] = 0x08;
14677 spec->private_adc_nids[1] = 0x11;
14678 spec->private_capsrc_nids[0] = 0x23;
14679 spec->private_capsrc_nids[1] = 0x22;
14680 } else {
14681 spec->private_adc_nids[0] = 0x11;
14682 spec->private_adc_nids[1] = 0x08;
14683 spec->private_capsrc_nids[0] = 0x22;
14684 spec->private_capsrc_nids[1] = 0x23;
14685 }
14686 spec->adc_nids = spec->private_adc_nids;
14687 spec->capsrc_nids = spec->private_capsrc_nids;
14688 spec->num_adc_nids = 2;
14689 spec->dual_adc_switch = 1;
14690 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14691 spec->adc_nids[0], spec->adc_nids[1]);
14692 return 1;
14693 }
14694 return 0;
14695}
14696
d433a678
TI
14697/* different alc269-variants */
14698enum {
14699 ALC269_TYPE_NORMAL,
48c88e82 14700 ALC269_TYPE_ALC258,
d433a678 14701 ALC269_TYPE_ALC259,
48c88e82
KY
14702 ALC269_TYPE_ALC269VB,
14703 ALC269_TYPE_ALC270,
d433a678
TI
14704 ALC269_TYPE_ALC271X,
14705};
14706
f6a92248
KY
14707/*
14708 * BIOS auto configuration
14709 */
14710static int alc269_parse_auto_config(struct hda_codec *codec)
14711{
14712 struct alc_spec *spec = codec->spec;
cfb9fb55 14713 int err;
f6a92248
KY
14714 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14715
14716 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14717 alc269_ignore);
14718 if (err < 0)
14719 return err;
14720
14721 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14722 if (err < 0)
14723 return err;
f3550d1b
TI
14724 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14725 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14726 else
14727 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14728 0x22, 0);
f6a92248
KY
14729 if (err < 0)
14730 return err;
14731
14732 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14733
757899ac 14734 alc_auto_parse_digital(codec);
f6a92248 14735
603c4019 14736 if (spec->kctls.list)
d88897ea 14737 add_mixer(spec, spec->kctls.list);
f6a92248 14738
d433a678 14739 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
84898e87 14740 add_verb(spec, alc269vb_init_verbs);
6227cdce 14741 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14742 } else {
14743 add_verb(spec, alc269_init_verbs);
6227cdce 14744 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14745 }
14746
f6a92248 14747 spec->num_mux_defs = 1;
61b9b9b1 14748 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14749
14750 if (!alc275_setup_dual_adc(codec))
14751 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14752 sizeof(alc269_adc_candidates));
6694635d 14753
e01bf509 14754 /* set default input source */
840b64c0 14755 if (!spec->dual_adc_switch)
748cce43
TI
14756 select_or_unmute_capsrc(codec, spec->capsrc_nids[0],
14757 spec->input_mux->items[0].index);
f6a92248
KY
14758
14759 err = alc_auto_add_mic_boost(codec);
14760 if (err < 0)
14761 return err;
14762
7e0e44d4 14763 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14764 set_capture_mixer(codec);
f53281e6 14765
f6a92248
KY
14766 return 1;
14767}
14768
e9af4f36
TI
14769#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14770#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14771#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14772
14773
14774/* init callback for auto-configuration model -- overriding the default init */
14775static void alc269_auto_init(struct hda_codec *codec)
14776{
f6c7e546 14777 struct alc_spec *spec = codec->spec;
f6a92248
KY
14778 alc269_auto_init_multi_out(codec);
14779 alc269_auto_init_hp_out(codec);
14780 alc269_auto_init_analog_input(codec);
757899ac 14781 alc_auto_init_digital(codec);
f6c7e546 14782 if (spec->unsol_event)
7fb0d78f 14783 alc_inithook(codec);
f6a92248
KY
14784}
14785
0ec33d1f
TI
14786#ifdef SND_HDA_NEEDS_RESUME
14787static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14788{
14789 int val = alc_read_coef_idx(codec, 0x04);
14790 if (power_up)
14791 val |= 1 << 11;
14792 else
14793 val &= ~(1 << 11);
14794 alc_write_coef_idx(codec, 0x04, val);
14795}
14796
977ddd6b
KY
14797#ifdef CONFIG_SND_HDA_POWER_SAVE
14798static int alc269_suspend(struct hda_codec *codec, pm_message_t state)
14799{
14800 struct alc_spec *spec = codec->spec;
977ddd6b 14801
0ec33d1f
TI
14802 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14803 alc269_toggle_power_output(codec, 0);
977ddd6b 14804 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14805 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14806 msleep(150);
14807 }
14808
14809 alc_shutup(codec);
14810 if (spec && spec->power_hook)
14811 spec->power_hook(codec);
14812 return 0;
14813}
0ec33d1f
TI
14814#endif /* CONFIG_SND_HDA_POWER_SAVE */
14815
977ddd6b
KY
14816static int alc269_resume(struct hda_codec *codec)
14817{
977ddd6b 14818 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14819 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14820 msleep(150);
14821 }
14822
14823 codec->patch_ops.init(codec);
14824
14825 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14826 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14827 msleep(200);
14828 }
14829
0ec33d1f
TI
14830 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14831 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14832
14833 snd_hda_codec_resume_amp(codec);
14834 snd_hda_codec_resume_cache(codec);
9e5341b9 14835 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14836 return 0;
14837}
0ec33d1f 14838#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14839
1a99d4a4 14840static void alc269_fixup_hweq(struct hda_codec *codec,
b5bfbc67 14841 const struct alc_fixup *fix, int action)
1a99d4a4
KY
14842{
14843 int coef;
14844
58701120 14845 if (action != ALC_FIXUP_ACT_INIT)
9fb1ef25 14846 return;
1a99d4a4
KY
14847 coef = alc_read_coef_idx(codec, 0x1e);
14848 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14849}
14850
ff818c24
TI
14851enum {
14852 ALC269_FIXUP_SONY_VAIO,
74dc8909 14853 ALC275_FIXUP_SONY_VAIO_GPIO2,
145a902b 14854 ALC269_FIXUP_DELL_M101Z,
022c92be 14855 ALC269_FIXUP_SKU_IGNORE,
ac612407 14856 ALC269_FIXUP_ASUS_G73JW,
357f915e 14857 ALC269_FIXUP_LENOVO_EAPD,
1a99d4a4 14858 ALC275_FIXUP_SONY_HWEQ,
ff818c24
TI
14859};
14860
ff818c24
TI
14861static const struct alc_fixup alc269_fixups[] = {
14862 [ALC269_FIXUP_SONY_VAIO] = {
b5bfbc67
TI
14863 .type = ALC_FIXUP_VERBS,
14864 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
14865 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14866 {}
14867 }
ff818c24 14868 },
74dc8909 14869 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
b5bfbc67
TI
14870 .type = ALC_FIXUP_VERBS,
14871 .v.verbs = (const struct hda_verb[]) {
2785591a
KY
14872 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14873 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14874 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14875 { }
b5bfbc67
TI
14876 },
14877 .chained = true,
14878 .chain_id = ALC269_FIXUP_SONY_VAIO
2785591a 14879 },
145a902b 14880 [ALC269_FIXUP_DELL_M101Z] = {
b5bfbc67
TI
14881 .type = ALC_FIXUP_VERBS,
14882 .v.verbs = (const struct hda_verb[]) {
145a902b
DH
14883 /* Enables internal speaker */
14884 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14885 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14886 {}
14887 }
14888 },
022c92be 14889 [ALC269_FIXUP_SKU_IGNORE] = {
b5bfbc67
TI
14890 .type = ALC_FIXUP_SKU,
14891 .v.sku = ALC_FIXUP_SKU_IGNORE,
fe67b240 14892 },
ac612407 14893 [ALC269_FIXUP_ASUS_G73JW] = {
b5bfbc67
TI
14894 .type = ALC_FIXUP_PINS,
14895 .v.pins = (const struct alc_pincfg[]) {
ac612407
DH
14896 { 0x17, 0x99130111 }, /* subwoofer */
14897 { }
14898 }
14899 },
357f915e 14900 [ALC269_FIXUP_LENOVO_EAPD] = {
b5bfbc67
TI
14901 .type = ALC_FIXUP_VERBS,
14902 .v.verbs = (const struct hda_verb[]) {
357f915e
KY
14903 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14904 {}
14905 }
14906 },
1a99d4a4 14907 [ALC275_FIXUP_SONY_HWEQ] = {
b5bfbc67
TI
14908 .type = ALC_FIXUP_FUNC,
14909 .v.func = alc269_fixup_hweq,
14910 .chained = true,
14911 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
1a99d4a4 14912 }
ff818c24
TI
14913};
14914
14915static struct snd_pci_quirk alc269_fixup_tbl[] = {
74dc8909 14916 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
1a99d4a4
KY
14917 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14918 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7039c74c 14919 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14920 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
022c92be 14921 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
ded9f523
DH
14922 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14923 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14924 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14925 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
ac612407 14926 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
357f915e 14927 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
ff818c24
TI
14928 {}
14929};
14930
14931
f6a92248
KY
14932/*
14933 * configuration and preset
14934 */
ea734963 14935static const char * const alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14936 [ALC269_BASIC] = "basic",
2922c9af 14937 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14938 [ALC269_AMIC] = "laptop-amic",
14939 [ALC269_DMIC] = "laptop-dmic",
64154835 14940 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14941 [ALC269_LIFEBOOK] = "lifebook",
14942 [ALC269_AUTO] = "auto",
f6a92248
KY
14943};
14944
14945static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14946 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14947 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14948 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14949 ALC269_AMIC),
14950 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14951 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14952 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14953 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14954 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14955 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14956 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14957 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14958 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
c790ad31 14959 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
84898e87
KY
14960 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14961 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14962 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14963 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14964 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14965 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14966 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14967 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14968 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14969 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14970 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14971 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14972 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14973 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14974 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14975 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14976 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14977 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14978 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14979 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14980 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14981 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14982 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14983 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14984 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14985 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14986 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14987 ALC269_DMIC),
60db6b53 14988 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14989 ALC269_DMIC),
14990 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14991 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14992 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14993 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14994 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14995 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14996 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14997 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14998 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14999 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
15000 {}
15001};
15002
15003static struct alc_config_preset alc269_presets[] = {
15004 [ALC269_BASIC] = {
f9e336f6 15005 .mixers = { alc269_base_mixer },
f6a92248
KY
15006 .init_verbs = { alc269_init_verbs },
15007 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15008 .dac_nids = alc269_dac_nids,
15009 .hp_nid = 0x03,
15010 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15011 .channel_mode = alc269_modes,
15012 .input_mux = &alc269_capture_source,
15013 },
60db6b53
KY
15014 [ALC269_QUANTA_FL1] = {
15015 .mixers = { alc269_quanta_fl1_mixer },
15016 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15017 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15018 .dac_nids = alc269_dac_nids,
15019 .hp_nid = 0x03,
15020 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15021 .channel_mode = alc269_modes,
15022 .input_mux = &alc269_capture_source,
15023 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 15024 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
15025 .init_hook = alc269_quanta_fl1_init_hook,
15026 },
84898e87
KY
15027 [ALC269_AMIC] = {
15028 .mixers = { alc269_laptop_mixer },
15029 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 15030 .init_verbs = { alc269_init_verbs,
84898e87 15031 alc269_laptop_amic_init_verbs },
f53281e6
KY
15032 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15033 .dac_nids = alc269_dac_nids,
15034 .hp_nid = 0x03,
15035 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15036 .channel_mode = alc269_modes,
84898e87
KY
15037 .unsol_event = alc269_laptop_unsol_event,
15038 .setup = alc269_laptop_amic_setup,
15039 .init_hook = alc269_laptop_inithook,
f53281e6 15040 },
84898e87
KY
15041 [ALC269_DMIC] = {
15042 .mixers = { alc269_laptop_mixer },
15043 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 15044 .init_verbs = { alc269_init_verbs,
84898e87
KY
15045 alc269_laptop_dmic_init_verbs },
15046 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15047 .dac_nids = alc269_dac_nids,
15048 .hp_nid = 0x03,
15049 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15050 .channel_mode = alc269_modes,
15051 .unsol_event = alc269_laptop_unsol_event,
15052 .setup = alc269_laptop_dmic_setup,
15053 .init_hook = alc269_laptop_inithook,
15054 },
15055 [ALC269VB_AMIC] = {
15056 .mixers = { alc269vb_laptop_mixer },
15057 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15058 .init_verbs = { alc269vb_init_verbs,
15059 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
15060 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15061 .dac_nids = alc269_dac_nids,
15062 .hp_nid = 0x03,
15063 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15064 .channel_mode = alc269_modes,
84898e87 15065 .unsol_event = alc269_laptop_unsol_event,
226b1ec8 15066 .setup = alc269vb_laptop_amic_setup,
84898e87
KY
15067 .init_hook = alc269_laptop_inithook,
15068 },
15069 [ALC269VB_DMIC] = {
15070 .mixers = { alc269vb_laptop_mixer },
15071 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15072 .init_verbs = { alc269vb_init_verbs,
15073 alc269vb_laptop_dmic_init_verbs },
15074 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15075 .dac_nids = alc269_dac_nids,
15076 .hp_nid = 0x03,
15077 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15078 .channel_mode = alc269_modes,
15079 .unsol_event = alc269_laptop_unsol_event,
15080 .setup = alc269vb_laptop_dmic_setup,
15081 .init_hook = alc269_laptop_inithook,
f53281e6 15082 },
26f5df26 15083 [ALC269_FUJITSU] = {
45bdd1c1 15084 .mixers = { alc269_fujitsu_mixer },
84898e87 15085 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 15086 .init_verbs = { alc269_init_verbs,
84898e87 15087 alc269_laptop_dmic_init_verbs },
26f5df26
TI
15088 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15089 .dac_nids = alc269_dac_nids,
15090 .hp_nid = 0x03,
15091 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15092 .channel_mode = alc269_modes,
84898e87
KY
15093 .unsol_event = alc269_laptop_unsol_event,
15094 .setup = alc269_laptop_dmic_setup,
15095 .init_hook = alc269_laptop_inithook,
26f5df26 15096 },
64154835
TV
15097 [ALC269_LIFEBOOK] = {
15098 .mixers = { alc269_lifebook_mixer },
15099 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15100 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15101 .dac_nids = alc269_dac_nids,
15102 .hp_nid = 0x03,
15103 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15104 .channel_mode = alc269_modes,
15105 .input_mux = &alc269_capture_source,
15106 .unsol_event = alc269_lifebook_unsol_event,
15107 .init_hook = alc269_lifebook_init_hook,
15108 },
fe3eb0a7
KY
15109 [ALC271_ACER] = {
15110 .mixers = { alc269_asus_mixer },
15111 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15112 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15113 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15114 .dac_nids = alc269_dac_nids,
15115 .adc_nids = alc262_dmic_adc_nids,
15116 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15117 .capsrc_nids = alc262_dmic_capsrc_nids,
15118 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15119 .channel_mode = alc269_modes,
15120 .input_mux = &alc269_capture_source,
15121 .dig_out_nid = ALC880_DIGOUT_NID,
15122 .unsol_event = alc_sku_unsol_event,
15123 .setup = alc269vb_laptop_dmic_setup,
15124 .init_hook = alc_inithook,
15125 },
f6a92248
KY
15126};
15127
977ddd6b
KY
15128static int alc269_fill_coef(struct hda_codec *codec)
15129{
15130 int val;
15131
15132 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15133 alc_write_coef_idx(codec, 0xf, 0x960b);
15134 alc_write_coef_idx(codec, 0xe, 0x8817);
15135 }
15136
15137 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15138 alc_write_coef_idx(codec, 0xf, 0x960b);
15139 alc_write_coef_idx(codec, 0xe, 0x8814);
15140 }
15141
15142 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15143 val = alc_read_coef_idx(codec, 0x04);
15144 /* Power up output pin */
15145 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15146 }
15147
15148 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15149 val = alc_read_coef_idx(codec, 0xd);
15150 if ((val & 0x0c00) >> 10 != 0x1) {
15151 /* Capless ramp up clock control */
15152 alc_write_coef_idx(codec, 0xd, val | 1<<10);
15153 }
15154 val = alc_read_coef_idx(codec, 0x17);
15155 if ((val & 0x01c0) >> 6 != 0x4) {
15156 /* Class D power on reset */
15157 alc_write_coef_idx(codec, 0x17, val | 1<<7);
15158 }
15159 }
15160 return 0;
15161}
15162
f6a92248
KY
15163static int patch_alc269(struct hda_codec *codec)
15164{
15165 struct alc_spec *spec;
48c88e82 15166 int board_config, coef;
f6a92248
KY
15167 int err;
15168
15169 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15170 if (spec == NULL)
15171 return -ENOMEM;
15172
15173 codec->spec = spec;
15174
da00c244
KY
15175 alc_auto_parse_customize_define(codec);
15176
c793bec5
KY
15177 if (codec->vendor_id == 0x10ec0269) {
15178 coef = alc_read_coef_idx(codec, 0);
15179 if ((coef & 0x00f0) == 0x0010) {
15180 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15181 spec->cdefine.platform_type == 1) {
15182 alc_codec_rename(codec, "ALC271X");
15183 spec->codec_variant = ALC269_TYPE_ALC271X;
15184 } else if ((coef & 0xf000) == 0x1000) {
15185 spec->codec_variant = ALC269_TYPE_ALC270;
15186 } else if ((coef & 0xf000) == 0x2000) {
15187 alc_codec_rename(codec, "ALC259");
15188 spec->codec_variant = ALC269_TYPE_ALC259;
15189 } else if ((coef & 0xf000) == 0x3000) {
15190 alc_codec_rename(codec, "ALC258");
15191 spec->codec_variant = ALC269_TYPE_ALC258;
15192 } else {
15193 alc_codec_rename(codec, "ALC269VB");
15194 spec->codec_variant = ALC269_TYPE_ALC269VB;
15195 }
15196 } else
15197 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15198 alc269_fill_coef(codec);
15199 }
977ddd6b 15200
f6a92248
KY
15201 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15202 alc269_models,
15203 alc269_cfg_tbl);
15204
15205 if (board_config < 0) {
9a11f1aa
TI
15206 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15207 codec->chip_name);
f6a92248
KY
15208 board_config = ALC269_AUTO;
15209 }
15210
b5bfbc67
TI
15211 if (board_config == ALC269_AUTO) {
15212 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15213 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15214 }
ff818c24 15215
f6a92248
KY
15216 if (board_config == ALC269_AUTO) {
15217 /* automatic parse from the BIOS config */
15218 err = alc269_parse_auto_config(codec);
15219 if (err < 0) {
15220 alc_free(codec);
15221 return err;
15222 } else if (!err) {
15223 printk(KERN_INFO
15224 "hda_codec: Cannot set up configuration "
15225 "from BIOS. Using base mode...\n");
15226 board_config = ALC269_BASIC;
15227 }
15228 }
15229
dc1eae25 15230 if (has_cdefine_beep(codec)) {
8af2591d
TI
15231 err = snd_hda_attach_beep_device(codec, 0x1);
15232 if (err < 0) {
15233 alc_free(codec);
15234 return err;
15235 }
680cd536
KK
15236 }
15237
f6a92248 15238 if (board_config != ALC269_AUTO)
e9c364c0 15239 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15240
84898e87 15241 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15242 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15243 * fix the sample rate of analog I/O to 44.1kHz
15244 */
15245 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15246 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15247 } else if (spec->dual_adc_switch) {
15248 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15249 /* switch ADC dynamically */
15250 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15251 } else {
15252 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15253 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15254 }
f6a92248
KY
15255 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15256 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15257
6694635d 15258 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
1657cbd8 15259 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
6694635d
TI
15260 spec->adc_nids = alc269_adc_nids;
15261 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15262 spec->capsrc_nids = alc269_capsrc_nids;
15263 } else {
15264 spec->adc_nids = alc269vb_adc_nids;
15265 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15266 spec->capsrc_nids = alc269vb_capsrc_nids;
15267 }
84898e87
KY
15268 }
15269
f9e336f6 15270 if (!spec->cap_mixer)
b59bdf3b 15271 set_capture_mixer(codec);
dc1eae25 15272 if (has_cdefine_beep(codec))
da00c244 15273 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15274
b5bfbc67 15275 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
ff818c24 15276
100d5eb3
TI
15277 spec->vmaster_nid = 0x02;
15278
f6a92248 15279 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15280#ifdef CONFIG_SND_HDA_POWER_SAVE
15281 codec->patch_ops.suspend = alc269_suspend;
15282#endif
15283#ifdef SND_HDA_NEEDS_RESUME
15284 codec->patch_ops.resume = alc269_resume;
15285#endif
f6a92248
KY
15286 if (board_config == ALC269_AUTO)
15287 spec->init_hook = alc269_auto_init;
bf1b0225
KY
15288
15289 alc_init_jacks(codec);
f6a92248
KY
15290#ifdef CONFIG_SND_HDA_POWER_SAVE
15291 if (!spec->loopback.amplist)
15292 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15293 if (alc269_mic2_for_mute_led(codec))
15294 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15295#endif
15296
15297 return 0;
15298}
15299
df694daa
KY
15300/*
15301 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15302 */
15303
15304/*
15305 * set the path ways for 2 channel output
15306 * need to set the codec line out and mic 1 pin widgets to inputs
15307 */
15308static struct hda_verb alc861_threestack_ch2_init[] = {
15309 /* set pin widget 1Ah (line in) for input */
15310 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15311 /* set pin widget 18h (mic1/2) for input, for mic also enable
15312 * the vref
15313 */
df694daa
KY
15314 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15315
9c7f852e
TI
15316 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15317#if 0
15318 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15319 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15320#endif
df694daa
KY
15321 { } /* end */
15322};
15323/*
15324 * 6ch mode
15325 * need to set the codec line out and mic 1 pin widgets to outputs
15326 */
15327static struct hda_verb alc861_threestack_ch6_init[] = {
15328 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15329 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15330 /* set pin widget 18h (mic1) for output (CLFE)*/
15331 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15332
15333 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15334 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15335
9c7f852e
TI
15336 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15337#if 0
15338 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15339 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15340#endif
df694daa
KY
15341 { } /* end */
15342};
15343
15344static struct hda_channel_mode alc861_threestack_modes[2] = {
15345 { 2, alc861_threestack_ch2_init },
15346 { 6, alc861_threestack_ch6_init },
15347};
22309c3e
TI
15348/* Set mic1 as input and unmute the mixer */
15349static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15350 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15351 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15352 { } /* end */
15353};
15354/* Set mic1 as output and mute mixer */
15355static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15356 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15357 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15358 { } /* end */
15359};
15360
15361static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15362 { 2, alc861_uniwill_m31_ch2_init },
15363 { 4, alc861_uniwill_m31_ch4_init },
15364};
df694daa 15365
7cdbff94
MD
15366/* Set mic1 and line-in as input and unmute the mixer */
15367static struct hda_verb alc861_asus_ch2_init[] = {
15368 /* set pin widget 1Ah (line in) for input */
15369 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15370 /* set pin widget 18h (mic1/2) for input, for mic also enable
15371 * the vref
15372 */
7cdbff94
MD
15373 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15374
15375 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15376#if 0
15377 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15378 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15379#endif
15380 { } /* end */
15381};
15382/* Set mic1 nad line-in as output and mute mixer */
15383static struct hda_verb alc861_asus_ch6_init[] = {
15384 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15385 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15386 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15387 /* set pin widget 18h (mic1) for output (CLFE)*/
15388 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15389 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15390 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15391 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15392
15393 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15394#if 0
15395 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15396 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15397#endif
15398 { } /* end */
15399};
15400
15401static struct hda_channel_mode alc861_asus_modes[2] = {
15402 { 2, alc861_asus_ch2_init },
15403 { 6, alc861_asus_ch6_init },
15404};
15405
df694daa
KY
15406/* patch-ALC861 */
15407
15408static struct snd_kcontrol_new alc861_base_mixer[] = {
15409 /* output mixer control */
15410 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15411 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15412 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15413 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15414 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15415
15416 /*Input mixer control */
15417 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15418 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15419 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15420 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15421 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15422 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15423 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15424 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15425 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15426 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15427
df694daa
KY
15428 { } /* end */
15429};
15430
15431static struct snd_kcontrol_new alc861_3ST_mixer[] = {
15432 /* output mixer control */
15433 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15434 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15435 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15436 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15437 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15438
15439 /* Input mixer control */
15440 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15441 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15442 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15443 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15444 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15445 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15446 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15447 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15448 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15449 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15450
df694daa
KY
15451 {
15452 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15453 .name = "Channel Mode",
15454 .info = alc_ch_mode_info,
15455 .get = alc_ch_mode_get,
15456 .put = alc_ch_mode_put,
15457 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15458 },
15459 { } /* end */
a53d1aec
TD
15460};
15461
d1d985f0 15462static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15463 /* output mixer control */
15464 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15465 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15466 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15467
a53d1aec 15468 { } /* end */
f12ab1e0 15469};
a53d1aec 15470
22309c3e
TI
15471static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15472 /* output mixer control */
15473 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15474 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15475 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15476 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15477 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15478
15479 /* Input mixer control */
15480 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15481 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15482 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15483 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15484 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15485 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15486 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15487 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15488 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15489 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15490
22309c3e
TI
15491 {
15492 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15493 .name = "Channel Mode",
15494 .info = alc_ch_mode_info,
15495 .get = alc_ch_mode_get,
15496 .put = alc_ch_mode_put,
15497 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15498 },
15499 { } /* end */
f12ab1e0 15500};
7cdbff94
MD
15501
15502static struct snd_kcontrol_new alc861_asus_mixer[] = {
15503 /* output mixer control */
15504 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15505 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15506 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15507 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15508 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15509
15510 /* Input mixer control */
15511 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15512 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15513 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15514 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15515 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15516 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15517 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15518 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15519 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15520 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15521
7cdbff94
MD
15522 {
15523 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15524 .name = "Channel Mode",
15525 .info = alc_ch_mode_info,
15526 .get = alc_ch_mode_get,
15527 .put = alc_ch_mode_put,
15528 .private_value = ARRAY_SIZE(alc861_asus_modes),
15529 },
15530 { }
56bb0cab
TI
15531};
15532
15533/* additional mixer */
d1d985f0 15534static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15535 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15536 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15537 { }
15538};
7cdbff94 15539
df694daa
KY
15540/*
15541 * generic initialization of ADC, input mixers and output mixers
15542 */
15543static struct hda_verb alc861_base_init_verbs[] = {
15544 /*
15545 * Unmute ADC0 and set the default input to mic-in
15546 */
15547 /* port-A for surround (rear panel) */
15548 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15549 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15550 /* port-B for mic-in (rear panel) with vref */
15551 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15552 /* port-C for line-in (rear panel) */
15553 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15554 /* port-D for Front */
15555 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15556 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15557 /* port-E for HP out (front panel) */
15558 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15559 /* route front PCM to HP */
9dece1d7 15560 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15561 /* port-F for mic-in (front panel) with vref */
15562 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15563 /* port-G for CLFE (rear panel) */
15564 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15565 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15566 /* port-H for side (rear panel) */
15567 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15568 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15569 /* CD-in */
15570 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15571 /* route front mic to ADC1*/
15572 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15573 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15574
df694daa
KY
15575 /* Unmute DAC0~3 & spdif out*/
15576 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15577 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15578 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15579 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15580 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15581
df694daa
KY
15582 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15583 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15584 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15585 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15586 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15587
df694daa
KY
15588 /* Unmute Stereo Mixer 15 */
15589 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15590 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15591 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15592 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15593
15594 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15595 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15596 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15597 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15598 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15599 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15600 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15601 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15602 /* hp used DAC 3 (Front) */
15603 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15604 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15605
15606 { }
15607};
15608
15609static struct hda_verb alc861_threestack_init_verbs[] = {
15610 /*
15611 * Unmute ADC0 and set the default input to mic-in
15612 */
15613 /* port-A for surround (rear panel) */
15614 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15615 /* port-B for mic-in (rear panel) with vref */
15616 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15617 /* port-C for line-in (rear panel) */
15618 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15619 /* port-D for Front */
15620 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15621 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15622 /* port-E for HP out (front panel) */
15623 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15624 /* route front PCM to HP */
9dece1d7 15625 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15626 /* port-F for mic-in (front panel) with vref */
15627 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15628 /* port-G for CLFE (rear panel) */
15629 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15630 /* port-H for side (rear panel) */
15631 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15632 /* CD-in */
15633 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15634 /* route front mic to ADC1*/
15635 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15636 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15637 /* Unmute DAC0~3 & spdif out*/
15638 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15639 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15640 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15641 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15642 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15643
df694daa
KY
15644 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15645 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15646 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15647 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15648 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15649
df694daa
KY
15650 /* Unmute Stereo Mixer 15 */
15651 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15652 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15653 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15654 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15655
15656 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15657 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15658 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15659 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15660 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15661 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15662 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15663 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15664 /* hp used DAC 3 (Front) */
15665 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15666 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15667 { }
15668};
22309c3e
TI
15669
15670static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15671 /*
15672 * Unmute ADC0 and set the default input to mic-in
15673 */
15674 /* port-A for surround (rear panel) */
15675 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15676 /* port-B for mic-in (rear panel) with vref */
15677 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15678 /* port-C for line-in (rear panel) */
15679 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15680 /* port-D for Front */
15681 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15682 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15683 /* port-E for HP out (front panel) */
f12ab1e0
TI
15684 /* this has to be set to VREF80 */
15685 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15686 /* route front PCM to HP */
9dece1d7 15687 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15688 /* port-F for mic-in (front panel) with vref */
15689 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15690 /* port-G for CLFE (rear panel) */
15691 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15692 /* port-H for side (rear panel) */
15693 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15694 /* CD-in */
15695 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15696 /* route front mic to ADC1*/
15697 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15698 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15699 /* Unmute DAC0~3 & spdif out*/
15700 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15701 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15702 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15703 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15704 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15705
22309c3e
TI
15706 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15707 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15708 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15709 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15710 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15711
22309c3e
TI
15712 /* Unmute Stereo Mixer 15 */
15713 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15714 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15715 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15716 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15717
15718 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15719 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15720 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15721 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15722 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15723 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15724 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15725 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15726 /* hp used DAC 3 (Front) */
15727 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15728 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15729 { }
15730};
15731
7cdbff94
MD
15732static struct hda_verb alc861_asus_init_verbs[] = {
15733 /*
15734 * Unmute ADC0 and set the default input to mic-in
15735 */
f12ab1e0
TI
15736 /* port-A for surround (rear panel)
15737 * according to codec#0 this is the HP jack
15738 */
7cdbff94
MD
15739 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15740 /* route front PCM to HP */
15741 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15742 /* port-B for mic-in (rear panel) with vref */
15743 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15744 /* port-C for line-in (rear panel) */
15745 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15746 /* port-D for Front */
15747 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15748 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15749 /* port-E for HP out (front panel) */
f12ab1e0
TI
15750 /* this has to be set to VREF80 */
15751 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15752 /* route front PCM to HP */
9dece1d7 15753 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15754 /* port-F for mic-in (front panel) with vref */
15755 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15756 /* port-G for CLFE (rear panel) */
15757 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15758 /* port-H for side (rear panel) */
15759 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15760 /* CD-in */
15761 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15762 /* route front mic to ADC1*/
15763 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15764 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15765 /* Unmute DAC0~3 & spdif out*/
15766 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15767 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15768 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15769 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15770 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15771 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15772 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15773 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15774 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15775 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15776
7cdbff94
MD
15777 /* Unmute Stereo Mixer 15 */
15778 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15779 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15780 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15781 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15782
15783 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15784 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15785 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15786 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15787 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15788 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15789 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15790 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15791 /* hp used DAC 3 (Front) */
15792 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15793 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15794 { }
15795};
15796
56bb0cab
TI
15797/* additional init verbs for ASUS laptops */
15798static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15799 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15800 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15801 { }
15802};
7cdbff94 15803
df694daa
KY
15804/*
15805 * generic initialization of ADC, input mixers and output mixers
15806 */
15807static struct hda_verb alc861_auto_init_verbs[] = {
15808 /*
15809 * Unmute ADC0 and set the default input to mic-in
15810 */
f12ab1e0 15811 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15812 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15813
df694daa
KY
15814 /* Unmute DAC0~3 & spdif out*/
15815 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15816 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15817 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15818 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15819 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15820
df694daa
KY
15821 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15822 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15823 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15824 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15825 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15826
df694daa
KY
15827 /* Unmute Stereo Mixer 15 */
15828 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15829 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15830 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15831 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15832
1c20930a
TI
15833 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15834 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15835 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15836 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15837 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15838 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15839 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15840 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15841
15842 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15843 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15844 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15845 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15846 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15847 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15848 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15849 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15850
f12ab1e0 15851 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15852
15853 { }
15854};
15855
a53d1aec
TD
15856static struct hda_verb alc861_toshiba_init_verbs[] = {
15857 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15858
a53d1aec
TD
15859 { }
15860};
15861
15862/* toggle speaker-output according to the hp-jack state */
15863static void alc861_toshiba_automute(struct hda_codec *codec)
15864{
864f92be 15865 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15866
47fd830a
TI
15867 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15868 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15869 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15870 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15871}
15872
15873static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15874 unsigned int res)
15875{
a53d1aec
TD
15876 if ((res >> 26) == ALC880_HP_EVENT)
15877 alc861_toshiba_automute(codec);
15878}
15879
def319f9 15880/* pcm configuration: identical with ALC880 */
df694daa
KY
15881#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15882#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15883#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15884#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15885
15886
15887#define ALC861_DIGOUT_NID 0x07
15888
15889static struct hda_channel_mode alc861_8ch_modes[1] = {
15890 { 8, NULL }
15891};
15892
15893static hda_nid_t alc861_dac_nids[4] = {
15894 /* front, surround, clfe, side */
15895 0x03, 0x06, 0x05, 0x04
15896};
15897
9c7f852e
TI
15898static hda_nid_t alc660_dac_nids[3] = {
15899 /* front, clfe, surround */
15900 0x03, 0x05, 0x06
15901};
15902
df694daa
KY
15903static hda_nid_t alc861_adc_nids[1] = {
15904 /* ADC0-2 */
15905 0x08,
15906};
15907
15908static struct hda_input_mux alc861_capture_source = {
15909 .num_items = 5,
15910 .items = {
15911 { "Mic", 0x0 },
15912 { "Front Mic", 0x3 },
15913 { "Line", 0x1 },
15914 { "CD", 0x4 },
15915 { "Mixer", 0x5 },
15916 },
15917};
15918
1c20930a
TI
15919static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15920{
15921 struct alc_spec *spec = codec->spec;
15922 hda_nid_t mix, srcs[5];
15923 int i, j, num;
15924
15925 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15926 return 0;
15927 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15928 if (num < 0)
15929 return 0;
15930 for (i = 0; i < num; i++) {
15931 unsigned int type;
a22d543a 15932 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15933 if (type != AC_WID_AUD_OUT)
15934 continue;
15935 for (j = 0; j < spec->multiout.num_dacs; j++)
15936 if (spec->multiout.dac_nids[j] == srcs[i])
15937 break;
15938 if (j >= spec->multiout.num_dacs)
15939 return srcs[i];
15940 }
15941 return 0;
15942}
15943
df694daa 15944/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15945static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15946 const struct auto_pin_cfg *cfg)
df694daa 15947{
1c20930a 15948 struct alc_spec *spec = codec->spec;
df694daa 15949 int i;
1c20930a 15950 hda_nid_t nid, dac;
df694daa
KY
15951
15952 spec->multiout.dac_nids = spec->private_dac_nids;
15953 for (i = 0; i < cfg->line_outs; i++) {
15954 nid = cfg->line_out_pins[i];
1c20930a
TI
15955 dac = alc861_look_for_dac(codec, nid);
15956 if (!dac)
15957 continue;
15958 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15959 }
df694daa
KY
15960 return 0;
15961}
15962
bcb2f0f5
TI
15963static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15964 hda_nid_t nid, int idx, unsigned int chs)
1c20930a 15965{
bcb2f0f5 15966 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
1c20930a
TI
15967 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15968}
15969
bcb2f0f5
TI
15970#define alc861_create_out_sw(codec, pfx, nid, chs) \
15971 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15972
df694daa 15973/* add playback controls from the parsed DAC table */
1c20930a 15974static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15975 const struct auto_pin_cfg *cfg)
15976{
1c20930a 15977 struct alc_spec *spec = codec->spec;
ea734963 15978 static const char * const chname[4] = {
f12ab1e0
TI
15979 "Front", "Surround", NULL /*CLFE*/, "Side"
15980 };
bcb2f0f5 15981 const char *pfx = alc_get_line_out_pfx(cfg, true);
df694daa 15982 hda_nid_t nid;
1c20930a
TI
15983 int i, err;
15984
df694daa
KY
15985 for (i = 0; i < cfg->line_outs; i++) {
15986 nid = spec->multiout.dac_nids[i];
f12ab1e0 15987 if (!nid)
df694daa 15988 continue;
bcb2f0f5 15989 if (!pfx && i == 2) {
df694daa 15990 /* Center/LFE */
1c20930a 15991 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15992 if (err < 0)
df694daa 15993 return err;
1c20930a 15994 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15995 if (err < 0)
df694daa
KY
15996 return err;
15997 } else {
bcb2f0f5
TI
15998 const char *name = pfx;
15999 if (!name)
16000 name = chname[i];
16001 err = __alc861_create_out_sw(codec, name, nid, i, 3);
f12ab1e0 16002 if (err < 0)
df694daa
KY
16003 return err;
16004 }
16005 }
16006 return 0;
16007}
16008
1c20930a 16009static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 16010{
1c20930a 16011 struct alc_spec *spec = codec->spec;
df694daa
KY
16012 int err;
16013 hda_nid_t nid;
16014
f12ab1e0 16015 if (!pin)
df694daa
KY
16016 return 0;
16017
16018 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
16019 nid = alc861_look_for_dac(codec, pin);
16020 if (nid) {
16021 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16022 if (err < 0)
16023 return err;
16024 spec->multiout.hp_nid = nid;
16025 }
df694daa
KY
16026 }
16027 return 0;
16028}
16029
16030/* create playback/capture controls for input pins */
05f5f477 16031static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 16032 const struct auto_pin_cfg *cfg)
df694daa 16033{
05f5f477 16034 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
16035}
16036
f12ab1e0
TI
16037static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16038 hda_nid_t nid,
1c20930a 16039 int pin_type, hda_nid_t dac)
df694daa 16040{
1c20930a
TI
16041 hda_nid_t mix, srcs[5];
16042 int i, num;
16043
564c5bea
JL
16044 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16045 pin_type);
1c20930a 16046 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 16047 AMP_OUT_UNMUTE);
1c20930a
TI
16048 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16049 return;
16050 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16051 if (num < 0)
16052 return;
16053 for (i = 0; i < num; i++) {
16054 unsigned int mute;
16055 if (srcs[i] == dac || srcs[i] == 0x15)
16056 mute = AMP_IN_UNMUTE(i);
16057 else
16058 mute = AMP_IN_MUTE(i);
16059 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16060 mute);
16061 }
df694daa
KY
16062}
16063
16064static void alc861_auto_init_multi_out(struct hda_codec *codec)
16065{
16066 struct alc_spec *spec = codec->spec;
16067 int i;
16068
16069 for (i = 0; i < spec->autocfg.line_outs; i++) {
16070 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16071 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 16072 if (nid)
baba8ee9 16073 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 16074 spec->multiout.dac_nids[i]);
df694daa
KY
16075 }
16076}
16077
16078static void alc861_auto_init_hp_out(struct hda_codec *codec)
16079{
16080 struct alc_spec *spec = codec->spec;
df694daa 16081
15870f05
TI
16082 if (spec->autocfg.hp_outs)
16083 alc861_auto_set_output_and_unmute(codec,
16084 spec->autocfg.hp_pins[0],
16085 PIN_HP,
1c20930a 16086 spec->multiout.hp_nid);
15870f05
TI
16087 if (spec->autocfg.speaker_outs)
16088 alc861_auto_set_output_and_unmute(codec,
16089 spec->autocfg.speaker_pins[0],
16090 PIN_OUT,
1c20930a 16091 spec->multiout.dac_nids[0]);
df694daa
KY
16092}
16093
16094static void alc861_auto_init_analog_input(struct hda_codec *codec)
16095{
16096 struct alc_spec *spec = codec->spec;
66ceeb6b 16097 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
16098 int i;
16099
66ceeb6b
TI
16100 for (i = 0; i < cfg->num_inputs; i++) {
16101 hda_nid_t nid = cfg->inputs[i].pin;
23f0c048 16102 if (nid >= 0x0c && nid <= 0x11)
30ea098f 16103 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
df694daa
KY
16104 }
16105}
16106
16107/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
16108/* return 1 if successful, 0 if the proper config is not found,
16109 * or a negative error code
16110 */
df694daa
KY
16111static int alc861_parse_auto_config(struct hda_codec *codec)
16112{
16113 struct alc_spec *spec = codec->spec;
16114 int err;
16115 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16116
f12ab1e0
TI
16117 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16118 alc861_ignore);
16119 if (err < 0)
df694daa 16120 return err;
f12ab1e0 16121 if (!spec->autocfg.line_outs)
df694daa
KY
16122 return 0; /* can't find valid BIOS pin config */
16123
1c20930a 16124 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
16125 if (err < 0)
16126 return err;
1c20930a 16127 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
16128 if (err < 0)
16129 return err;
1c20930a 16130 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
16131 if (err < 0)
16132 return err;
05f5f477 16133 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16134 if (err < 0)
df694daa
KY
16135 return err;
16136
16137 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16138
757899ac 16139 alc_auto_parse_digital(codec);
df694daa 16140
603c4019 16141 if (spec->kctls.list)
d88897ea 16142 add_mixer(spec, spec->kctls.list);
df694daa 16143
d88897ea 16144 add_verb(spec, alc861_auto_init_verbs);
df694daa 16145
a1e8d2da 16146 spec->num_mux_defs = 1;
61b9b9b1 16147 spec->input_mux = &spec->private_imux[0];
df694daa
KY
16148
16149 spec->adc_nids = alc861_adc_nids;
16150 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 16151 set_capture_mixer(codec);
df694daa 16152
6227cdce 16153 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 16154
df694daa
KY
16155 return 1;
16156}
16157
ae6b813a
TI
16158/* additional initialization for auto-configuration model */
16159static void alc861_auto_init(struct hda_codec *codec)
df694daa 16160{
f6c7e546 16161 struct alc_spec *spec = codec->spec;
df694daa
KY
16162 alc861_auto_init_multi_out(codec);
16163 alc861_auto_init_hp_out(codec);
16164 alc861_auto_init_analog_input(codec);
757899ac 16165 alc_auto_init_digital(codec);
f6c7e546 16166 if (spec->unsol_event)
7fb0d78f 16167 alc_inithook(codec);
df694daa
KY
16168}
16169
cb53c626
TI
16170#ifdef CONFIG_SND_HDA_POWER_SAVE
16171static struct hda_amp_list alc861_loopbacks[] = {
16172 { 0x15, HDA_INPUT, 0 },
16173 { 0x15, HDA_INPUT, 1 },
16174 { 0x15, HDA_INPUT, 2 },
16175 { 0x15, HDA_INPUT, 3 },
16176 { } /* end */
16177};
16178#endif
16179
df694daa
KY
16180
16181/*
16182 * configuration and preset
16183 */
ea734963 16184static const char * const alc861_models[ALC861_MODEL_LAST] = {
f5fcc13c
TI
16185 [ALC861_3ST] = "3stack",
16186 [ALC660_3ST] = "3stack-660",
16187 [ALC861_3ST_DIG] = "3stack-dig",
16188 [ALC861_6ST_DIG] = "6stack-dig",
16189 [ALC861_UNIWILL_M31] = "uniwill-m31",
16190 [ALC861_TOSHIBA] = "toshiba",
16191 [ALC861_ASUS] = "asus",
16192 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16193 [ALC861_AUTO] = "auto",
16194};
16195
16196static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 16197 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
16198 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16199 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16200 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 16201 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 16202 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16203 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16204 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16205 * Any other models that need this preset?
16206 */
16207 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16208 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16209 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16210 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16211 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16212 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16213 /* FIXME: the below seems conflict */
16214 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16215 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16216 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16217 {}
16218};
16219
16220static struct alc_config_preset alc861_presets[] = {
16221 [ALC861_3ST] = {
16222 .mixers = { alc861_3ST_mixer },
16223 .init_verbs = { alc861_threestack_init_verbs },
16224 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16225 .dac_nids = alc861_dac_nids,
16226 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16227 .channel_mode = alc861_threestack_modes,
4e195a7b 16228 .need_dac_fix = 1,
df694daa
KY
16229 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16230 .adc_nids = alc861_adc_nids,
16231 .input_mux = &alc861_capture_source,
16232 },
16233 [ALC861_3ST_DIG] = {
16234 .mixers = { alc861_base_mixer },
16235 .init_verbs = { alc861_threestack_init_verbs },
16236 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16237 .dac_nids = alc861_dac_nids,
16238 .dig_out_nid = ALC861_DIGOUT_NID,
16239 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16240 .channel_mode = alc861_threestack_modes,
4e195a7b 16241 .need_dac_fix = 1,
df694daa
KY
16242 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16243 .adc_nids = alc861_adc_nids,
16244 .input_mux = &alc861_capture_source,
16245 },
16246 [ALC861_6ST_DIG] = {
16247 .mixers = { alc861_base_mixer },
16248 .init_verbs = { alc861_base_init_verbs },
16249 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16250 .dac_nids = alc861_dac_nids,
16251 .dig_out_nid = ALC861_DIGOUT_NID,
16252 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16253 .channel_mode = alc861_8ch_modes,
16254 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16255 .adc_nids = alc861_adc_nids,
16256 .input_mux = &alc861_capture_source,
16257 },
9c7f852e
TI
16258 [ALC660_3ST] = {
16259 .mixers = { alc861_3ST_mixer },
16260 .init_verbs = { alc861_threestack_init_verbs },
16261 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16262 .dac_nids = alc660_dac_nids,
16263 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16264 .channel_mode = alc861_threestack_modes,
4e195a7b 16265 .need_dac_fix = 1,
9c7f852e
TI
16266 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16267 .adc_nids = alc861_adc_nids,
16268 .input_mux = &alc861_capture_source,
16269 },
22309c3e
TI
16270 [ALC861_UNIWILL_M31] = {
16271 .mixers = { alc861_uniwill_m31_mixer },
16272 .init_verbs = { alc861_uniwill_m31_init_verbs },
16273 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16274 .dac_nids = alc861_dac_nids,
16275 .dig_out_nid = ALC861_DIGOUT_NID,
16276 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16277 .channel_mode = alc861_uniwill_m31_modes,
16278 .need_dac_fix = 1,
16279 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16280 .adc_nids = alc861_adc_nids,
16281 .input_mux = &alc861_capture_source,
16282 },
a53d1aec
TD
16283 [ALC861_TOSHIBA] = {
16284 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16285 .init_verbs = { alc861_base_init_verbs,
16286 alc861_toshiba_init_verbs },
a53d1aec
TD
16287 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16288 .dac_nids = alc861_dac_nids,
16289 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16290 .channel_mode = alc883_3ST_2ch_modes,
16291 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16292 .adc_nids = alc861_adc_nids,
16293 .input_mux = &alc861_capture_source,
16294 .unsol_event = alc861_toshiba_unsol_event,
16295 .init_hook = alc861_toshiba_automute,
16296 },
7cdbff94
MD
16297 [ALC861_ASUS] = {
16298 .mixers = { alc861_asus_mixer },
16299 .init_verbs = { alc861_asus_init_verbs },
16300 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16301 .dac_nids = alc861_dac_nids,
16302 .dig_out_nid = ALC861_DIGOUT_NID,
16303 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16304 .channel_mode = alc861_asus_modes,
16305 .need_dac_fix = 1,
16306 .hp_nid = 0x06,
16307 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16308 .adc_nids = alc861_adc_nids,
16309 .input_mux = &alc861_capture_source,
16310 },
56bb0cab
TI
16311 [ALC861_ASUS_LAPTOP] = {
16312 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16313 .init_verbs = { alc861_asus_init_verbs,
16314 alc861_asus_laptop_init_verbs },
16315 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16316 .dac_nids = alc861_dac_nids,
16317 .dig_out_nid = ALC861_DIGOUT_NID,
16318 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16319 .channel_mode = alc883_3ST_2ch_modes,
16320 .need_dac_fix = 1,
16321 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16322 .adc_nids = alc861_adc_nids,
16323 .input_mux = &alc861_capture_source,
16324 },
16325};
df694daa 16326
cfc9b06f
TI
16327/* Pin config fixes */
16328enum {
16329 PINFIX_FSC_AMILO_PI1505,
16330};
16331
cfc9b06f
TI
16332static const struct alc_fixup alc861_fixups[] = {
16333 [PINFIX_FSC_AMILO_PI1505] = {
b5bfbc67
TI
16334 .type = ALC_FIXUP_PINS,
16335 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
16336 { 0x0b, 0x0221101f }, /* HP */
16337 { 0x0f, 0x90170310 }, /* speaker */
16338 { }
16339 }
cfc9b06f
TI
16340 },
16341};
16342
16343static struct snd_pci_quirk alc861_fixup_tbl[] = {
16344 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16345 {}
16346};
df694daa
KY
16347
16348static int patch_alc861(struct hda_codec *codec)
16349{
16350 struct alc_spec *spec;
16351 int board_config;
16352 int err;
16353
dc041e0b 16354 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16355 if (spec == NULL)
16356 return -ENOMEM;
16357
f12ab1e0 16358 codec->spec = spec;
df694daa 16359
f5fcc13c
TI
16360 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16361 alc861_models,
16362 alc861_cfg_tbl);
9c7f852e 16363
f5fcc13c 16364 if (board_config < 0) {
9a11f1aa
TI
16365 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16366 codec->chip_name);
df694daa
KY
16367 board_config = ALC861_AUTO;
16368 }
16369
b5bfbc67
TI
16370 if (board_config == ALC861_AUTO) {
16371 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16372 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16373 }
cfc9b06f 16374
df694daa
KY
16375 if (board_config == ALC861_AUTO) {
16376 /* automatic parse from the BIOS config */
16377 err = alc861_parse_auto_config(codec);
16378 if (err < 0) {
16379 alc_free(codec);
16380 return err;
f12ab1e0 16381 } else if (!err) {
9c7f852e
TI
16382 printk(KERN_INFO
16383 "hda_codec: Cannot set up configuration "
16384 "from BIOS. Using base mode...\n");
df694daa
KY
16385 board_config = ALC861_3ST_DIG;
16386 }
16387 }
16388
680cd536
KK
16389 err = snd_hda_attach_beep_device(codec, 0x23);
16390 if (err < 0) {
16391 alc_free(codec);
16392 return err;
16393 }
16394
df694daa 16395 if (board_config != ALC861_AUTO)
e9c364c0 16396 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16397
df694daa
KY
16398 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16399 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16400
df694daa
KY
16401 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16402 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16403
c7a8eb10
TI
16404 if (!spec->cap_mixer)
16405 set_capture_mixer(codec);
45bdd1c1
TI
16406 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16407
2134ea4f
TI
16408 spec->vmaster_nid = 0x03;
16409
b5bfbc67 16410 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 16411
df694daa 16412 codec->patch_ops = alc_patch_ops;
c97259df 16413 if (board_config == ALC861_AUTO) {
ae6b813a 16414 spec->init_hook = alc861_auto_init;
c97259df
DC
16415#ifdef CONFIG_SND_HDA_POWER_SAVE
16416 spec->power_hook = alc_power_eapd;
16417#endif
16418 }
cb53c626
TI
16419#ifdef CONFIG_SND_HDA_POWER_SAVE
16420 if (!spec->loopback.amplist)
16421 spec->loopback.amplist = alc861_loopbacks;
16422#endif
ea1fb29a 16423
1da177e4
LT
16424 return 0;
16425}
16426
f32610ed
JS
16427/*
16428 * ALC861-VD support
16429 *
16430 * Based on ALC882
16431 *
16432 * In addition, an independent DAC
16433 */
16434#define ALC861VD_DIGOUT_NID 0x06
16435
16436static hda_nid_t alc861vd_dac_nids[4] = {
16437 /* front, surr, clfe, side surr */
16438 0x02, 0x03, 0x04, 0x05
16439};
16440
16441/* dac_nids for ALC660vd are in a different order - according to
16442 * Realtek's driver.
def319f9 16443 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16444 * of ALC660vd codecs, but for now there is only 3stack mixer
16445 * - and it is the same as in 861vd.
16446 * adc_nids in ALC660vd are (is) the same as in 861vd
16447 */
16448static hda_nid_t alc660vd_dac_nids[3] = {
16449 /* front, rear, clfe, rear_surr */
16450 0x02, 0x04, 0x03
16451};
16452
16453static hda_nid_t alc861vd_adc_nids[1] = {
16454 /* ADC0 */
16455 0x09,
16456};
16457
e1406348
TI
16458static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16459
f32610ed
JS
16460/* input MUX */
16461/* FIXME: should be a matrix-type input source selection */
16462static struct hda_input_mux alc861vd_capture_source = {
16463 .num_items = 4,
16464 .items = {
16465 { "Mic", 0x0 },
16466 { "Front Mic", 0x1 },
16467 { "Line", 0x2 },
16468 { "CD", 0x4 },
16469 },
16470};
16471
272a527c 16472static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16473 .num_items = 2,
272a527c 16474 .items = {
8607f7c4 16475 { "Mic", 0x0 },
28c4edb7 16476 { "Internal Mic", 0x1 },
272a527c
KY
16477 },
16478};
16479
d1a991a6
KY
16480static struct hda_input_mux alc861vd_hp_capture_source = {
16481 .num_items = 2,
16482 .items = {
16483 { "Front Mic", 0x0 },
16484 { "ATAPI Mic", 0x1 },
16485 },
16486};
16487
f32610ed
JS
16488/*
16489 * 2ch mode
16490 */
16491static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16492 { 2, NULL }
16493};
16494
16495/*
16496 * 6ch mode
16497 */
16498static struct hda_verb alc861vd_6stack_ch6_init[] = {
16499 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16500 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16501 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16502 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16503 { } /* end */
16504};
16505
16506/*
16507 * 8ch mode
16508 */
16509static struct hda_verb alc861vd_6stack_ch8_init[] = {
16510 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16511 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16512 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16513 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16514 { } /* end */
16515};
16516
16517static struct hda_channel_mode alc861vd_6stack_modes[2] = {
16518 { 6, alc861vd_6stack_ch6_init },
16519 { 8, alc861vd_6stack_ch8_init },
16520};
16521
16522static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16523 {
16524 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16525 .name = "Channel Mode",
16526 .info = alc_ch_mode_info,
16527 .get = alc_ch_mode_get,
16528 .put = alc_ch_mode_put,
16529 },
16530 { } /* end */
16531};
16532
f32610ed
JS
16533/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16534 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16535 */
16536static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16537 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16538 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16539
16540 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16541 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16542
16543 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16544 HDA_OUTPUT),
16545 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16546 HDA_OUTPUT),
16547 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16548 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16549
16550 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16551 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16552
16553 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16554
5f99f86a 16555 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16556 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16557 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16558
5f99f86a 16559 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16560 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16561 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16562
16563 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16564 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16565
16566 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16567 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16568
f32610ed
JS
16569 { } /* end */
16570};
16571
16572static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16573 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16574 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16575
16576 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16577
5f99f86a 16578 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16579 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16580 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16581
5f99f86a 16582 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16583 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16584 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16585
16586 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16587 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16588
16589 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16590 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16591
f32610ed
JS
16592 { } /* end */
16593};
16594
bdd148a3
KY
16595static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16596 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16597 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16598 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16599
16600 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16601
5f99f86a 16602 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3
KY
16603 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16604 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16605
5f99f86a 16606 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
bdd148a3
KY
16607 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16608 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16609
16610 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16611 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16612
16613 { } /* end */
16614};
16615
b419f346 16616/* Pin assignment: Speaker=0x14, HP = 0x15,
8607f7c4 16617 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
16618 */
16619static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16620 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16621 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16622 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16623 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
5f99f86a 16624 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8607f7c4
DH
16625 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16626 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 16627 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
16628 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16629 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16630 { } /* end */
16631};
16632
d1a991a6
KY
16633/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16634 * Front Mic=0x18, ATAPI Mic = 0x19,
16635 */
16636static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16637 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16638 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16639 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16640 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16641 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16642 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16643 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16644 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16645
d1a991a6
KY
16646 { } /* end */
16647};
16648
f32610ed
JS
16649/*
16650 * generic initialization of ADC, input mixers and output mixers
16651 */
16652static struct hda_verb alc861vd_volume_init_verbs[] = {
16653 /*
16654 * Unmute ADC0 and set the default input to mic-in
16655 */
16656 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16657 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16658
16659 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16660 * the analog-loopback mixer widget
16661 */
16662 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16663 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16664 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16665 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16666 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16667 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16668
16669 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16670 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16671 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16672 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16673 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16674
16675 /*
16676 * Set up output mixers (0x02 - 0x05)
16677 */
16678 /* set vol=0 to output mixers */
16679 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16680 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16681 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16682 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16683
16684 /* set up input amps for analog loopback */
16685 /* Amp Indices: DAC = 0, mixer = 1 */
16686 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16687 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16688 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16689 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16690 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16691 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16692 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16693 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16694
16695 { }
16696};
16697
16698/*
16699 * 3-stack pin configuration:
16700 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16701 */
16702static struct hda_verb alc861vd_3stack_init_verbs[] = {
16703 /*
16704 * Set pin mode and muting
16705 */
16706 /* set front pin widgets 0x14 for output */
16707 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16708 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16709 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16710
16711 /* Mic (rear) pin: input vref at 80% */
16712 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16713 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16714 /* Front Mic pin: input vref at 80% */
16715 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16716 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16717 /* Line In pin: input */
16718 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16719 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16720 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16721 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16722 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16723 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16724 /* CD pin widget for input */
16725 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16726
16727 { }
16728};
16729
16730/*
16731 * 6-stack pin configuration:
16732 */
16733static struct hda_verb alc861vd_6stack_init_verbs[] = {
16734 /*
16735 * Set pin mode and muting
16736 */
16737 /* set front pin widgets 0x14 for output */
16738 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16739 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16740 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16741
16742 /* Rear Pin: output 1 (0x0d) */
16743 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16744 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16745 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16746 /* CLFE Pin: output 2 (0x0e) */
16747 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16748 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16749 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16750 /* Side Pin: output 3 (0x0f) */
16751 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16752 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16753 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16754
16755 /* Mic (rear) pin: input vref at 80% */
16756 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16757 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16758 /* Front Mic pin: input vref at 80% */
16759 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16760 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16761 /* Line In pin: input */
16762 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16763 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16764 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16765 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16766 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16767 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16768 /* CD pin widget for input */
16769 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16770
16771 { }
16772};
16773
bdd148a3
KY
16774static struct hda_verb alc861vd_eapd_verbs[] = {
16775 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16776 { }
16777};
16778
f9423e7a
KY
16779static struct hda_verb alc660vd_eapd_verbs[] = {
16780 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16781 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16782 { }
16783};
16784
bdd148a3
KY
16785static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16786 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16787 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16788 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16789 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16790 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16791 {}
16792};
16793
4f5d1706 16794static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16795{
a9fd4f3f 16796 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16797 spec->autocfg.hp_pins[0] = 0x1b;
16798 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
16799}
16800
16801static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16802{
a9fd4f3f 16803 alc_automute_amp(codec);
eeb43387 16804 alc88x_simple_mic_automute(codec);
bdd148a3
KY
16805}
16806
16807static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16808 unsigned int res)
16809{
16810 switch (res >> 26) {
bdd148a3 16811 case ALC880_MIC_EVENT:
eeb43387 16812 alc88x_simple_mic_automute(codec);
bdd148a3 16813 break;
a9fd4f3f
TI
16814 default:
16815 alc_automute_amp_unsol_event(codec, res);
16816 break;
bdd148a3
KY
16817 }
16818}
16819
272a527c
KY
16820static struct hda_verb alc861vd_dallas_verbs[] = {
16821 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16822 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16823 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16824 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16825
16826 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16827 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16828 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16829 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16830 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16831 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16832 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16833 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16834
272a527c
KY
16835 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16836 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16837 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16838 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16839 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16840 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16841 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16842 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16843
16844 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16845 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16846 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16847 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16848 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16849 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16850 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16851 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16852
16853 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16854 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16855 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16856 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16857
16858 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16859 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16860 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16861
16862 { } /* end */
16863};
16864
16865/* toggle speaker-output according to the hp-jack state */
4f5d1706 16866static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16867{
a9fd4f3f 16868 struct alc_spec *spec = codec->spec;
272a527c 16869
a9fd4f3f
TI
16870 spec->autocfg.hp_pins[0] = 0x15;
16871 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
16872}
16873
cb53c626
TI
16874#ifdef CONFIG_SND_HDA_POWER_SAVE
16875#define alc861vd_loopbacks alc880_loopbacks
16876#endif
16877
def319f9 16878/* pcm configuration: identical with ALC880 */
f32610ed
JS
16879#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16880#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16881#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16882#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16883
16884/*
16885 * configuration and preset
16886 */
ea734963 16887static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
f32610ed 16888 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16889 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16890 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16891 [ALC861VD_3ST] = "3stack",
16892 [ALC861VD_3ST_DIG] = "3stack-digout",
16893 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16894 [ALC861VD_LENOVO] = "lenovo",
272a527c 16895 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16896 [ALC861VD_HP] = "hp",
f32610ed
JS
16897 [ALC861VD_AUTO] = "auto",
16898};
16899
16900static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16901 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16902 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16903 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16904 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16905 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16906 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16907 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16908 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16909 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16910 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16911 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16912 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16913 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16914 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16915 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16916 {}
16917};
16918
16919static struct alc_config_preset alc861vd_presets[] = {
16920 [ALC660VD_3ST] = {
16921 .mixers = { alc861vd_3st_mixer },
16922 .init_verbs = { alc861vd_volume_init_verbs,
16923 alc861vd_3stack_init_verbs },
16924 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16925 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16926 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16927 .channel_mode = alc861vd_3stack_2ch_modes,
16928 .input_mux = &alc861vd_capture_source,
16929 },
6963f84c
MC
16930 [ALC660VD_3ST_DIG] = {
16931 .mixers = { alc861vd_3st_mixer },
16932 .init_verbs = { alc861vd_volume_init_verbs,
16933 alc861vd_3stack_init_verbs },
16934 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16935 .dac_nids = alc660vd_dac_nids,
16936 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16937 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16938 .channel_mode = alc861vd_3stack_2ch_modes,
16939 .input_mux = &alc861vd_capture_source,
16940 },
f32610ed
JS
16941 [ALC861VD_3ST] = {
16942 .mixers = { alc861vd_3st_mixer },
16943 .init_verbs = { alc861vd_volume_init_verbs,
16944 alc861vd_3stack_init_verbs },
16945 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16946 .dac_nids = alc861vd_dac_nids,
16947 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16948 .channel_mode = alc861vd_3stack_2ch_modes,
16949 .input_mux = &alc861vd_capture_source,
16950 },
16951 [ALC861VD_3ST_DIG] = {
16952 .mixers = { alc861vd_3st_mixer },
16953 .init_verbs = { alc861vd_volume_init_verbs,
16954 alc861vd_3stack_init_verbs },
16955 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16956 .dac_nids = alc861vd_dac_nids,
16957 .dig_out_nid = ALC861VD_DIGOUT_NID,
16958 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16959 .channel_mode = alc861vd_3stack_2ch_modes,
16960 .input_mux = &alc861vd_capture_source,
16961 },
16962 [ALC861VD_6ST_DIG] = {
16963 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16964 .init_verbs = { alc861vd_volume_init_verbs,
16965 alc861vd_6stack_init_verbs },
16966 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16967 .dac_nids = alc861vd_dac_nids,
16968 .dig_out_nid = ALC861VD_DIGOUT_NID,
16969 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16970 .channel_mode = alc861vd_6stack_modes,
16971 .input_mux = &alc861vd_capture_source,
16972 },
bdd148a3
KY
16973 [ALC861VD_LENOVO] = {
16974 .mixers = { alc861vd_lenovo_mixer },
16975 .init_verbs = { alc861vd_volume_init_verbs,
16976 alc861vd_3stack_init_verbs,
16977 alc861vd_eapd_verbs,
16978 alc861vd_lenovo_unsol_verbs },
16979 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16980 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16981 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16982 .channel_mode = alc861vd_3stack_2ch_modes,
16983 .input_mux = &alc861vd_capture_source,
16984 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16985 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16986 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16987 },
272a527c
KY
16988 [ALC861VD_DALLAS] = {
16989 .mixers = { alc861vd_dallas_mixer },
16990 .init_verbs = { alc861vd_dallas_verbs },
16991 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16992 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16993 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16994 .channel_mode = alc861vd_3stack_2ch_modes,
16995 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 16996 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16997 .setup = alc861vd_dallas_setup,
16998 .init_hook = alc_automute_amp,
d1a991a6
KY
16999 },
17000 [ALC861VD_HP] = {
17001 .mixers = { alc861vd_hp_mixer },
17002 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17003 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17004 .dac_nids = alc861vd_dac_nids,
d1a991a6 17005 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
17006 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17007 .channel_mode = alc861vd_3stack_2ch_modes,
17008 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 17009 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
17010 .setup = alc861vd_dallas_setup,
17011 .init_hook = alc_automute_amp,
ea1fb29a 17012 },
13c94744
TI
17013 [ALC660VD_ASUS_V1S] = {
17014 .mixers = { alc861vd_lenovo_mixer },
17015 .init_verbs = { alc861vd_volume_init_verbs,
17016 alc861vd_3stack_init_verbs,
17017 alc861vd_eapd_verbs,
17018 alc861vd_lenovo_unsol_verbs },
17019 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17020 .dac_nids = alc660vd_dac_nids,
17021 .dig_out_nid = ALC861VD_DIGOUT_NID,
17022 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17023 .channel_mode = alc861vd_3stack_2ch_modes,
17024 .input_mux = &alc861vd_capture_source,
17025 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 17026 .setup = alc861vd_lenovo_setup,
a9fd4f3f 17027 .init_hook = alc861vd_lenovo_init_hook,
13c94744 17028 },
f32610ed
JS
17029};
17030
17031/*
17032 * BIOS auto configuration
17033 */
05f5f477
TI
17034static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17035 const struct auto_pin_cfg *cfg)
17036{
7167594a 17037 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
05f5f477
TI
17038}
17039
17040
f32610ed
JS
17041static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17042 hda_nid_t nid, int pin_type, int dac_idx)
17043{
f6c7e546 17044 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
17045}
17046
17047static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17048{
17049 struct alc_spec *spec = codec->spec;
17050 int i;
17051
17052 for (i = 0; i <= HDA_SIDE; i++) {
17053 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 17054 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
17055 if (nid)
17056 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 17057 pin_type, i);
f32610ed
JS
17058 }
17059}
17060
17061
17062static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17063{
17064 struct alc_spec *spec = codec->spec;
17065 hda_nid_t pin;
17066
17067 pin = spec->autocfg.hp_pins[0];
def319f9 17068 if (pin) /* connect to front and use dac 0 */
f32610ed 17069 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
17070 pin = spec->autocfg.speaker_pins[0];
17071 if (pin)
17072 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
17073}
17074
f32610ed
JS
17075#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17076
17077static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17078{
17079 struct alc_spec *spec = codec->spec;
66ceeb6b 17080 struct auto_pin_cfg *cfg = &spec->autocfg;
f32610ed
JS
17081 int i;
17082
66ceeb6b
TI
17083 for (i = 0; i < cfg->num_inputs; i++) {
17084 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 17085 if (alc_is_input_pin(codec, nid)) {
30ea098f 17086 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
17087 if (nid != ALC861VD_PIN_CD_NID &&
17088 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
17089 snd_hda_codec_write(codec, nid, 0,
17090 AC_VERB_SET_AMP_GAIN_MUTE,
17091 AMP_OUT_MUTE);
17092 }
17093 }
17094}
17095
f511b01c
TI
17096#define alc861vd_auto_init_input_src alc882_auto_init_input_src
17097
f32610ed
JS
17098#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17099#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17100
17101/* add playback controls from the parsed DAC table */
569ed348 17102/* Based on ALC880 version. But ALC861VD has separate,
f32610ed
JS
17103 * different NIDs for mute/unmute switch and volume control */
17104static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17105 const struct auto_pin_cfg *cfg)
17106{
ea734963
TI
17107 static const char * const chname[4] = {
17108 "Front", "Surround", "CLFE", "Side"
17109 };
bcb2f0f5 17110 const char *pfx = alc_get_line_out_pfx(cfg, true);
f32610ed
JS
17111 hda_nid_t nid_v, nid_s;
17112 int i, err;
17113
17114 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 17115 if (!spec->multiout.dac_nids[i])
f32610ed
JS
17116 continue;
17117 nid_v = alc861vd_idx_to_mixer_vol(
17118 alc880_dac_to_idx(
17119 spec->multiout.dac_nids[i]));
17120 nid_s = alc861vd_idx_to_mixer_switch(
17121 alc880_dac_to_idx(
17122 spec->multiout.dac_nids[i]));
17123
bcb2f0f5 17124 if (!pfx && i == 2) {
f32610ed 17125 /* Center/LFE */
0afe5f89
TI
17126 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17127 "Center",
f12ab1e0
TI
17128 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17129 HDA_OUTPUT));
17130 if (err < 0)
f32610ed 17131 return err;
0afe5f89
TI
17132 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17133 "LFE",
f12ab1e0
TI
17134 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17135 HDA_OUTPUT));
17136 if (err < 0)
f32610ed 17137 return err;
0afe5f89
TI
17138 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17139 "Center",
f12ab1e0
TI
17140 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17141 HDA_INPUT));
17142 if (err < 0)
f32610ed 17143 return err;
0afe5f89
TI
17144 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17145 "LFE",
f12ab1e0
TI
17146 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17147 HDA_INPUT));
17148 if (err < 0)
f32610ed
JS
17149 return err;
17150 } else {
bcb2f0f5
TI
17151 const char *name = pfx;
17152 if (!name)
17153 name = chname[i];
17154 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17155 name, i,
f12ab1e0
TI
17156 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17157 HDA_OUTPUT));
17158 if (err < 0)
f32610ed 17159 return err;
bcb2f0f5
TI
17160 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17161 name, i,
bdd148a3 17162 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
17163 HDA_INPUT));
17164 if (err < 0)
f32610ed
JS
17165 return err;
17166 }
17167 }
17168 return 0;
17169}
17170
17171/* add playback controls for speaker and HP outputs */
17172/* Based on ALC880 version. But ALC861VD has separate,
17173 * different NIDs for mute/unmute switch and volume control */
17174static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17175 hda_nid_t pin, const char *pfx)
17176{
17177 hda_nid_t nid_v, nid_s;
17178 int err;
f32610ed 17179
f12ab1e0 17180 if (!pin)
f32610ed
JS
17181 return 0;
17182
17183 if (alc880_is_fixed_pin(pin)) {
17184 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17185 /* specify the DAC as the extra output */
f12ab1e0 17186 if (!spec->multiout.hp_nid)
f32610ed
JS
17187 spec->multiout.hp_nid = nid_v;
17188 else
17189 spec->multiout.extra_out_nid[0] = nid_v;
17190 /* control HP volume/switch on the output mixer amp */
17191 nid_v = alc861vd_idx_to_mixer_vol(
17192 alc880_fixed_pin_idx(pin));
17193 nid_s = alc861vd_idx_to_mixer_switch(
17194 alc880_fixed_pin_idx(pin));
17195
0afe5f89 17196 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17197 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17198 if (err < 0)
f32610ed 17199 return err;
0afe5f89 17200 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17201 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17202 if (err < 0)
f32610ed
JS
17203 return err;
17204 } else if (alc880_is_multi_pin(pin)) {
17205 /* set manual connection */
17206 /* we have only a switch on HP-out PIN */
0afe5f89 17207 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17208 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17209 if (err < 0)
f32610ed
JS
17210 return err;
17211 }
17212 return 0;
17213}
17214
17215/* parse the BIOS configuration and set up the alc_spec
17216 * return 1 if successful, 0 if the proper config is not found,
17217 * or a negative error code
17218 * Based on ALC880 version - had to change it to override
17219 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17220static int alc861vd_parse_auto_config(struct hda_codec *codec)
17221{
17222 struct alc_spec *spec = codec->spec;
17223 int err;
17224 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17225
f12ab1e0
TI
17226 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17227 alc861vd_ignore);
17228 if (err < 0)
f32610ed 17229 return err;
f12ab1e0 17230 if (!spec->autocfg.line_outs)
f32610ed
JS
17231 return 0; /* can't find valid BIOS pin config */
17232
f12ab1e0
TI
17233 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17234 if (err < 0)
17235 return err;
17236 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17237 if (err < 0)
17238 return err;
17239 err = alc861vd_auto_create_extra_out(spec,
17240 spec->autocfg.speaker_pins[0],
17241 "Speaker");
17242 if (err < 0)
17243 return err;
17244 err = alc861vd_auto_create_extra_out(spec,
17245 spec->autocfg.hp_pins[0],
17246 "Headphone");
17247 if (err < 0)
17248 return err;
05f5f477 17249 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17250 if (err < 0)
f32610ed
JS
17251 return err;
17252
17253 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17254
757899ac 17255 alc_auto_parse_digital(codec);
f32610ed 17256
603c4019 17257 if (spec->kctls.list)
d88897ea 17258 add_mixer(spec, spec->kctls.list);
f32610ed 17259
d88897ea 17260 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
17261
17262 spec->num_mux_defs = 1;
61b9b9b1 17263 spec->input_mux = &spec->private_imux[0];
f32610ed 17264
776e184e
TI
17265 err = alc_auto_add_mic_boost(codec);
17266 if (err < 0)
17267 return err;
17268
6227cdce 17269 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17270
f32610ed
JS
17271 return 1;
17272}
17273
17274/* additional initialization for auto-configuration model */
17275static void alc861vd_auto_init(struct hda_codec *codec)
17276{
f6c7e546 17277 struct alc_spec *spec = codec->spec;
f32610ed
JS
17278 alc861vd_auto_init_multi_out(codec);
17279 alc861vd_auto_init_hp_out(codec);
17280 alc861vd_auto_init_analog_input(codec);
f511b01c 17281 alc861vd_auto_init_input_src(codec);
757899ac 17282 alc_auto_init_digital(codec);
f6c7e546 17283 if (spec->unsol_event)
7fb0d78f 17284 alc_inithook(codec);
f32610ed
JS
17285}
17286
f8f25ba3
TI
17287enum {
17288 ALC660VD_FIX_ASUS_GPIO1
17289};
17290
17291/* reset GPIO1 */
f8f25ba3
TI
17292static const struct alc_fixup alc861vd_fixups[] = {
17293 [ALC660VD_FIX_ASUS_GPIO1] = {
b5bfbc67
TI
17294 .type = ALC_FIXUP_VERBS,
17295 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
17296 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17297 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17298 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17299 { }
17300 }
f8f25ba3
TI
17301 },
17302};
17303
17304static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17305 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17306 {}
17307};
17308
f32610ed
JS
17309static int patch_alc861vd(struct hda_codec *codec)
17310{
17311 struct alc_spec *spec;
17312 int err, board_config;
17313
17314 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17315 if (spec == NULL)
17316 return -ENOMEM;
17317
17318 codec->spec = spec;
17319
17320 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17321 alc861vd_models,
17322 alc861vd_cfg_tbl);
17323
17324 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17325 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17326 codec->chip_name);
f32610ed
JS
17327 board_config = ALC861VD_AUTO;
17328 }
17329
b5bfbc67
TI
17330 if (board_config == ALC861VD_AUTO) {
17331 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17332 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17333 }
f8f25ba3 17334
f32610ed
JS
17335 if (board_config == ALC861VD_AUTO) {
17336 /* automatic parse from the BIOS config */
17337 err = alc861vd_parse_auto_config(codec);
17338 if (err < 0) {
17339 alc_free(codec);
17340 return err;
f12ab1e0 17341 } else if (!err) {
f32610ed
JS
17342 printk(KERN_INFO
17343 "hda_codec: Cannot set up configuration "
17344 "from BIOS. Using base mode...\n");
17345 board_config = ALC861VD_3ST;
17346 }
17347 }
17348
680cd536
KK
17349 err = snd_hda_attach_beep_device(codec, 0x23);
17350 if (err < 0) {
17351 alc_free(codec);
17352 return err;
17353 }
17354
f32610ed 17355 if (board_config != ALC861VD_AUTO)
e9c364c0 17356 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17357
2f893286 17358 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17359 /* always turn on EAPD */
d88897ea 17360 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17361 }
17362
f32610ed
JS
17363 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17364 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17365
f32610ed
JS
17366 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17367 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17368
dd704698
TI
17369 if (!spec->adc_nids) {
17370 spec->adc_nids = alc861vd_adc_nids;
17371 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17372 }
17373 if (!spec->capsrc_nids)
17374 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17375
b59bdf3b 17376 set_capture_mixer(codec);
45bdd1c1 17377 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17378
2134ea4f
TI
17379 spec->vmaster_nid = 0x02;
17380
b5bfbc67 17381 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 17382
f32610ed
JS
17383 codec->patch_ops = alc_patch_ops;
17384
17385 if (board_config == ALC861VD_AUTO)
17386 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
17387#ifdef CONFIG_SND_HDA_POWER_SAVE
17388 if (!spec->loopback.amplist)
17389 spec->loopback.amplist = alc861vd_loopbacks;
17390#endif
f32610ed
JS
17391
17392 return 0;
17393}
17394
bc9f98a9
KY
17395/*
17396 * ALC662 support
17397 *
17398 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17399 * configuration. Each pin widget can choose any input DACs and a mixer.
17400 * Each ADC is connected from a mixer of all inputs. This makes possible
17401 * 6-channel independent captures.
17402 *
17403 * In addition, an independent DAC for the multi-playback (not used in this
17404 * driver yet).
17405 */
17406#define ALC662_DIGOUT_NID 0x06
17407#define ALC662_DIGIN_NID 0x0a
17408
17409static hda_nid_t alc662_dac_nids[4] = {
17410 /* front, rear, clfe, rear_surr */
17411 0x02, 0x03, 0x04
17412};
17413
622e84cd
KY
17414static hda_nid_t alc272_dac_nids[2] = {
17415 0x02, 0x03
17416};
17417
b59bdf3b 17418static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17419 /* ADC1-2 */
b59bdf3b 17420 0x09, 0x08
bc9f98a9 17421};
e1406348 17422
622e84cd
KY
17423static hda_nid_t alc272_adc_nids[1] = {
17424 /* ADC1-2 */
17425 0x08,
17426};
17427
b59bdf3b 17428static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
17429static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17430
e1406348 17431
bc9f98a9
KY
17432/* input MUX */
17433/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
17434static struct hda_input_mux alc662_capture_source = {
17435 .num_items = 4,
17436 .items = {
17437 { "Mic", 0x0 },
17438 { "Front Mic", 0x1 },
17439 { "Line", 0x2 },
17440 { "CD", 0x4 },
17441 },
17442};
17443
17444static struct hda_input_mux alc662_lenovo_101e_capture_source = {
17445 .num_items = 2,
17446 .items = {
17447 { "Mic", 0x1 },
17448 { "Line", 0x2 },
17449 },
17450};
291702f0 17451
6dda9f4a
KY
17452static struct hda_input_mux alc663_capture_source = {
17453 .num_items = 3,
17454 .items = {
17455 { "Mic", 0x0 },
17456 { "Front Mic", 0x1 },
17457 { "Line", 0x2 },
17458 },
17459};
17460
4f5d1706 17461#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
17462static struct hda_input_mux alc272_nc10_capture_source = {
17463 .num_items = 16,
17464 .items = {
17465 { "Autoselect Mic", 0x0 },
17466 { "Internal Mic", 0x1 },
17467 { "In-0x02", 0x2 },
17468 { "In-0x03", 0x3 },
17469 { "In-0x04", 0x4 },
17470 { "In-0x05", 0x5 },
17471 { "In-0x06", 0x6 },
17472 { "In-0x07", 0x7 },
17473 { "In-0x08", 0x8 },
17474 { "In-0x09", 0x9 },
17475 { "In-0x0a", 0x0a },
17476 { "In-0x0b", 0x0b },
17477 { "In-0x0c", 0x0c },
17478 { "In-0x0d", 0x0d },
17479 { "In-0x0e", 0x0e },
17480 { "In-0x0f", 0x0f },
17481 },
17482};
17483#endif
17484
bc9f98a9
KY
17485/*
17486 * 2ch mode
17487 */
17488static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17489 { 2, NULL }
17490};
17491
17492/*
17493 * 2ch mode
17494 */
17495static struct hda_verb alc662_3ST_ch2_init[] = {
17496 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17497 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17498 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17499 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17500 { } /* end */
17501};
17502
17503/*
17504 * 6ch mode
17505 */
17506static struct hda_verb alc662_3ST_ch6_init[] = {
17507 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17508 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17509 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17510 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17511 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17512 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17513 { } /* end */
17514};
17515
17516static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17517 { 2, alc662_3ST_ch2_init },
17518 { 6, alc662_3ST_ch6_init },
17519};
17520
17521/*
17522 * 2ch mode
17523 */
17524static struct hda_verb alc662_sixstack_ch6_init[] = {
17525 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17526 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17527 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17528 { } /* end */
17529};
17530
17531/*
17532 * 6ch mode
17533 */
17534static struct hda_verb alc662_sixstack_ch8_init[] = {
17535 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17536 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17537 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17538 { } /* end */
17539};
17540
17541static struct hda_channel_mode alc662_5stack_modes[2] = {
17542 { 2, alc662_sixstack_ch6_init },
17543 { 6, alc662_sixstack_ch8_init },
17544};
17545
17546/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17547 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17548 */
17549
17550static struct snd_kcontrol_new alc662_base_mixer[] = {
17551 /* output mixer control */
17552 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17553 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17554 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17555 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17556 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17557 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17558 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17559 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17560 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17561
17562 /*Input mixer control */
17563 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17564 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17565 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17566 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17567 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17568 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17569 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17570 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17571 { } /* end */
17572};
17573
17574static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17575 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17576 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17577 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17578 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17579 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17580 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17581 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17582 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17583 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17584 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17585 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17586 { } /* end */
17587};
17588
17589static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17590 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17591 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17592 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17593 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17594 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17595 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17596 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17597 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17598 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17599 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17600 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17601 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17602 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17603 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17604 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17605 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17606 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17607 { } /* end */
17608};
17609
17610static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17611 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17612 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17613 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17614 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17615 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17616 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17617 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17618 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17619 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17620 { } /* end */
17621};
17622
291702f0 17623static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17624 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17625 ALC262_HIPPO_MASTER_SWITCH,
291702f0 17626
5f99f86a 17627 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17628 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17629 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
291702f0 17630
5f99f86a 17631 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17632 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17633 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
291702f0
KY
17634 { } /* end */
17635};
17636
8c427226 17637static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17638 ALC262_HIPPO_MASTER_SWITCH,
17639 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17640 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17641 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17642 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17643 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17644 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17645 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17646 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17647 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17648 { } /* end */
17649};
17650
f1d4e28b
KY
17651static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17652 .ops = &snd_hda_bind_vol,
17653 .values = {
17654 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17655 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17656 0
17657 },
17658};
17659
17660static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17661 .ops = &snd_hda_bind_sw,
17662 .values = {
17663 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17664 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17665 0
17666 },
17667};
17668
6dda9f4a 17669static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17670 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17671 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17672 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17673 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17674 { } /* end */
17675};
17676
17677static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17678 .ops = &snd_hda_bind_sw,
17679 .values = {
17680 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17681 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17682 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17683 0
17684 },
17685};
17686
17687static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17688 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17689 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17690 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17691 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17692 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17693 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17694
17695 { } /* end */
17696};
17697
17698static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17699 .ops = &snd_hda_bind_sw,
17700 .values = {
17701 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17702 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17703 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17704 0
17705 },
17706};
17707
17708static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17709 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17710 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17711 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17712 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17713 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17714 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17715 { } /* end */
17716};
17717
17718static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17719 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17720 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17721 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17722 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17723 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17724 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17725 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17726 { } /* end */
17727};
17728
17729static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17730 .ops = &snd_hda_bind_vol,
17731 .values = {
17732 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17733 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17734 0
17735 },
17736};
17737
17738static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17739 .ops = &snd_hda_bind_sw,
17740 .values = {
17741 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17742 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17743 0
17744 },
17745};
17746
17747static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17748 HDA_BIND_VOL("Master Playback Volume",
17749 &alc663_asus_two_bind_master_vol),
17750 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17751 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17752 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17753 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17754 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17755 { } /* end */
17756};
17757
17758static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17759 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17760 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17761 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17762 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17763 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17764 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17765 { } /* end */
17766};
17767
17768static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17769 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17770 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17771 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17772 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17773 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17774
17775 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17776 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17777 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17778 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17779 { } /* end */
17780};
17781
17782static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17783 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17784 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17785 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17786
17787 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17788 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17789 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17790 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17791 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17792 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17793 { } /* end */
17794};
17795
ebb83eeb
KY
17796static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17797 .ops = &snd_hda_bind_sw,
17798 .values = {
17799 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17800 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17801 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17802 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17803 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17804 0
17805 },
17806};
17807
17808static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17809 .ops = &snd_hda_bind_sw,
17810 .values = {
17811 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17812 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17813 0
17814 },
17815};
17816
17817static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17818 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17819 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17820 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17821 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17822 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17823 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17824 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17825 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17826 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17827 { } /* end */
17828};
17829
17830static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17831 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17832 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17833 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17834 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17835 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17836 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17837 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17838 { } /* end */
17839};
17840
17841
bc9f98a9
KY
17842static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17843 {
17844 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17845 .name = "Channel Mode",
17846 .info = alc_ch_mode_info,
17847 .get = alc_ch_mode_get,
17848 .put = alc_ch_mode_put,
17849 },
17850 { } /* end */
17851};
17852
17853static struct hda_verb alc662_init_verbs[] = {
17854 /* ADC: mute amp left and right */
17855 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17856 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17857
b60dd394
KY
17858 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17859 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17860 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17861 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17862 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17863 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17864
17865 /* Front Pin: output 0 (0x0c) */
17866 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17867 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17868
17869 /* Rear Pin: output 1 (0x0d) */
17870 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17871 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17872
17873 /* CLFE Pin: output 2 (0x0e) */
17874 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17875 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17876
17877 /* Mic (rear) pin: input vref at 80% */
17878 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17879 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17880 /* Front Mic pin: input vref at 80% */
17881 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17882 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17883 /* Line In pin: input */
17884 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17885 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17886 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17887 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17888 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17889 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17890 /* CD pin widget for input */
17891 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17892
17893 /* FIXME: use matrix-type input source selection */
17894 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17895 /* Input mixer */
17896 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17897 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
17898
17899 /* always trun on EAPD */
17900 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17901 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17902
bc9f98a9
KY
17903 { }
17904};
17905
cec27c89
KY
17906static struct hda_verb alc663_init_verbs[] = {
17907 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17908 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17909 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17910 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17911 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17912 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17913 { }
17914};
17915
17916static struct hda_verb alc272_init_verbs[] = {
17917 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17918 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17919 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17920 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17921 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17922 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17923 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17924 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17925 { }
17926};
17927
bc9f98a9
KY
17928static struct hda_verb alc662_sue_init_verbs[] = {
17929 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17930 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17931 {}
17932};
17933
17934static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17935 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17936 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17937 {}
bc9f98a9
KY
17938};
17939
8c427226
KY
17940/* Set Unsolicited Event*/
17941static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17942 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17943 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17944 {}
17945};
17946
6dda9f4a 17947static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17948 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17949 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17950 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17951 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17952 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17953 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17954 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17955 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17956 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17957 {}
17958};
17959
17960static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17961 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17962 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17963 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17964 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17965 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17966 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17967 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17968 {}
17969};
17970
17971static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17972 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17973 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17974 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17975 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17976 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17977 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17978 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17979 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17980 {}
17981};
6dda9f4a 17982
f1d4e28b
KY
17983static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17984 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17985 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17986 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17987 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17988 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17989 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17990 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17991 {}
17992};
6dda9f4a 17993
f1d4e28b
KY
17994static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17995 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17996 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17997 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17998 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17999 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18000 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18001 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18002 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18003 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
18004 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18005 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
18006 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18007 {}
18008};
18009
18010static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
18011 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18012 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18013 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18014 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18015 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18016 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18017 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18018 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18019 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18020 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18021 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18022 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
18023 {}
18024};
18025
18026static struct hda_verb alc663_g71v_init_verbs[] = {
18027 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18028 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18029 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18030
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, 0x00}, /* Headphone */
18034
18035 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18036 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18037 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18038 {}
18039};
18040
18041static struct hda_verb alc663_g50v_init_verbs[] = {
18042 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18043 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18044 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18045
18046 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18047 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18048 {}
18049};
18050
f1d4e28b
KY
18051static struct hda_verb alc662_ecs_init_verbs[] = {
18052 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18053 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18054 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18055 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18056 {}
18057};
18058
622e84cd
KY
18059static struct hda_verb alc272_dell_zm1_init_verbs[] = {
18060 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18061 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18062 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18063 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18064 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18065 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18066 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18067 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18068 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18069 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18070 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18071 {}
18072};
18073
18074static struct hda_verb alc272_dell_init_verbs[] = {
18075 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18076 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18077 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18078 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18079 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18080 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18081 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18082 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18083 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18084 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18085 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18086 {}
18087};
18088
ebb83eeb
KY
18089static struct hda_verb alc663_mode7_init_verbs[] = {
18090 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18091 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18092 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18093 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18094 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18095 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18096 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18097 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18098 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18099 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18100 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18101 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18102 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18103 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18104 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18105 {}
18106};
18107
18108static struct hda_verb alc663_mode8_init_verbs[] = {
18109 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18110 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18111 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18112 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18113 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18114 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18115 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18116 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18117 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18118 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18119 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18120 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18121 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18122 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18123 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18124 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18125 {}
18126};
18127
f1d4e28b
KY
18128static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18129 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18130 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18131 { } /* end */
18132};
18133
622e84cd
KY
18134static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18135 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18136 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18137 { } /* end */
18138};
18139
bc9f98a9
KY
18140static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
18141{
18142 unsigned int present;
f12ab1e0 18143 unsigned char bits;
bc9f98a9 18144
864f92be 18145 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 18146 bits = present ? HDA_AMP_MUTE : 0;
864f92be 18147
47fd830a
TI
18148 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18149 HDA_AMP_MUTE, bits);
bc9f98a9
KY
18150}
18151
18152static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
18153{
18154 unsigned int present;
f12ab1e0 18155 unsigned char bits;
bc9f98a9 18156
864f92be 18157 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 18158 bits = present ? HDA_AMP_MUTE : 0;
864f92be 18159
47fd830a
TI
18160 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18161 HDA_AMP_MUTE, bits);
18162 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18163 HDA_AMP_MUTE, bits);
bc9f98a9
KY
18164}
18165
18166static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
18167 unsigned int res)
18168{
18169 if ((res >> 26) == ALC880_HP_EVENT)
18170 alc662_lenovo_101e_all_automute(codec);
18171 if ((res >> 26) == ALC880_FRONT_EVENT)
18172 alc662_lenovo_101e_ispeaker_automute(codec);
18173}
18174
291702f0
KY
18175/* unsolicited event for HP jack sensing */
18176static void alc662_eeepc_unsol_event(struct hda_codec *codec,
18177 unsigned int res)
18178{
291702f0 18179 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 18180 alc_mic_automute(codec);
42171c17
TI
18181 else
18182 alc262_hippo_unsol_event(codec, res);
291702f0
KY
18183}
18184
4f5d1706
TI
18185static void alc662_eeepc_setup(struct hda_codec *codec)
18186{
18187 struct alc_spec *spec = codec->spec;
18188
18189 alc262_hippo1_setup(codec);
18190 spec->ext_mic.pin = 0x18;
18191 spec->ext_mic.mux_idx = 0;
18192 spec->int_mic.pin = 0x19;
18193 spec->int_mic.mux_idx = 1;
18194 spec->auto_mic = 1;
18195}
18196
291702f0
KY
18197static void alc662_eeepc_inithook(struct hda_codec *codec)
18198{
4f5d1706
TI
18199 alc262_hippo_automute(codec);
18200 alc_mic_automute(codec);
291702f0
KY
18201}
18202
4f5d1706 18203static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18204{
42171c17
TI
18205 struct alc_spec *spec = codec->spec;
18206
18207 spec->autocfg.hp_pins[0] = 0x14;
18208 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
18209}
18210
4f5d1706
TI
18211#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
18212
6dda9f4a
KY
18213static void alc663_m51va_speaker_automute(struct hda_codec *codec)
18214{
18215 unsigned int present;
18216 unsigned char bits;
18217
864f92be 18218 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 18219 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 18220 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18221 HDA_AMP_MUTE, bits);
f1d4e28b 18222 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18223 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18224}
18225
18226static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
18227{
18228 unsigned int present;
18229 unsigned char bits;
18230
864f92be 18231 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
18232 bits = present ? HDA_AMP_MUTE : 0;
18233 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18234 HDA_AMP_MUTE, bits);
f1d4e28b 18235 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18236 HDA_AMP_MUTE, bits);
f1d4e28b 18237 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18238 HDA_AMP_MUTE, bits);
f1d4e28b 18239 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18240 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18241}
18242
18243static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
18244{
18245 unsigned int present;
18246 unsigned char bits;
18247
864f92be 18248 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18249 bits = present ? HDA_AMP_MUTE : 0;
18250 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18251 HDA_AMP_MUTE, bits);
f1d4e28b 18252 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18253 HDA_AMP_MUTE, bits);
f1d4e28b 18254 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18255 HDA_AMP_MUTE, bits);
f1d4e28b 18256 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18257 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18258}
18259
18260static void alc662_f5z_speaker_automute(struct hda_codec *codec)
18261{
18262 unsigned int present;
18263 unsigned char bits;
18264
864f92be 18265 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
18266 bits = present ? 0 : PIN_OUT;
18267 snd_hda_codec_write(codec, 0x14, 0,
18268 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
18269}
18270
18271static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
18272{
18273 unsigned int present1, present2;
18274
864f92be
WF
18275 present1 = snd_hda_jack_detect(codec, 0x21);
18276 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18277
18278 if (present1 || present2) {
18279 snd_hda_codec_write_cache(codec, 0x14, 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 }
18285}
18286
18287static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
18288{
18289 unsigned int present1, present2;
18290
864f92be
WF
18291 present1 = snd_hda_jack_detect(codec, 0x1b);
18292 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18293
18294 if (present1 || present2) {
18295 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18296 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 18297 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18298 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
18299 } else {
18300 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18301 HDA_AMP_MUTE, 0);
f1d4e28b 18302 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18303 HDA_AMP_MUTE, 0);
f1d4e28b 18304 }
6dda9f4a
KY
18305}
18306
ebb83eeb
KY
18307static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
18308{
18309 unsigned int present1, present2;
18310
18311 present1 = snd_hda_codec_read(codec, 0x1b, 0,
18312 AC_VERB_GET_PIN_SENSE, 0)
18313 & AC_PINSENSE_PRESENCE;
18314 present2 = snd_hda_codec_read(codec, 0x21, 0,
18315 AC_VERB_GET_PIN_SENSE, 0)
18316 & AC_PINSENSE_PRESENCE;
18317
18318 if (present1 || present2) {
18319 snd_hda_codec_write_cache(codec, 0x14, 0,
18320 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18321 snd_hda_codec_write_cache(codec, 0x17, 0,
18322 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18323 } else {
18324 snd_hda_codec_write_cache(codec, 0x14, 0,
18325 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18326 snd_hda_codec_write_cache(codec, 0x17, 0,
18327 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18328 }
18329}
18330
18331static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
18332{
18333 unsigned int present1, present2;
18334
18335 present1 = snd_hda_codec_read(codec, 0x21, 0,
18336 AC_VERB_GET_PIN_SENSE, 0)
18337 & AC_PINSENSE_PRESENCE;
18338 present2 = snd_hda_codec_read(codec, 0x15, 0,
18339 AC_VERB_GET_PIN_SENSE, 0)
18340 & AC_PINSENSE_PRESENCE;
18341
18342 if (present1 || present2) {
18343 snd_hda_codec_write_cache(codec, 0x14, 0,
18344 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18345 snd_hda_codec_write_cache(codec, 0x17, 0,
18346 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18347 } else {
18348 snd_hda_codec_write_cache(codec, 0x14, 0,
18349 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18350 snd_hda_codec_write_cache(codec, 0x17, 0,
18351 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18352 }
18353}
18354
6dda9f4a
KY
18355static void alc663_m51va_unsol_event(struct hda_codec *codec,
18356 unsigned int res)
18357{
18358 switch (res >> 26) {
18359 case ALC880_HP_EVENT:
18360 alc663_m51va_speaker_automute(codec);
18361 break;
18362 case ALC880_MIC_EVENT:
4f5d1706 18363 alc_mic_automute(codec);
6dda9f4a
KY
18364 break;
18365 }
18366}
18367
4f5d1706
TI
18368static void alc663_m51va_setup(struct hda_codec *codec)
18369{
18370 struct alc_spec *spec = codec->spec;
18371 spec->ext_mic.pin = 0x18;
18372 spec->ext_mic.mux_idx = 0;
18373 spec->int_mic.pin = 0x12;
ebb83eeb 18374 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18375 spec->auto_mic = 1;
18376}
18377
6dda9f4a
KY
18378static void alc663_m51va_inithook(struct hda_codec *codec)
18379{
18380 alc663_m51va_speaker_automute(codec);
4f5d1706 18381 alc_mic_automute(codec);
6dda9f4a
KY
18382}
18383
f1d4e28b 18384/* ***************** Mode1 ******************************/
4f5d1706 18385#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
18386
18387static void alc663_mode1_setup(struct hda_codec *codec)
18388{
18389 struct alc_spec *spec = codec->spec;
18390 spec->ext_mic.pin = 0x18;
18391 spec->ext_mic.mux_idx = 0;
18392 spec->int_mic.pin = 0x19;
18393 spec->int_mic.mux_idx = 1;
18394 spec->auto_mic = 1;
18395}
18396
4f5d1706 18397#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 18398
f1d4e28b
KY
18399/* ***************** Mode2 ******************************/
18400static void alc662_mode2_unsol_event(struct hda_codec *codec,
18401 unsigned int res)
18402{
18403 switch (res >> 26) {
18404 case ALC880_HP_EVENT:
18405 alc662_f5z_speaker_automute(codec);
18406 break;
18407 case ALC880_MIC_EVENT:
4f5d1706 18408 alc_mic_automute(codec);
f1d4e28b
KY
18409 break;
18410 }
18411}
18412
ebb83eeb 18413#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 18414
f1d4e28b
KY
18415static void alc662_mode2_inithook(struct hda_codec *codec)
18416{
18417 alc662_f5z_speaker_automute(codec);
4f5d1706 18418 alc_mic_automute(codec);
f1d4e28b
KY
18419}
18420/* ***************** Mode3 ******************************/
18421static void alc663_mode3_unsol_event(struct hda_codec *codec,
18422 unsigned int res)
18423{
18424 switch (res >> 26) {
18425 case ALC880_HP_EVENT:
18426 alc663_two_hp_m1_speaker_automute(codec);
18427 break;
18428 case ALC880_MIC_EVENT:
4f5d1706 18429 alc_mic_automute(codec);
f1d4e28b
KY
18430 break;
18431 }
18432}
18433
ebb83eeb 18434#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 18435
f1d4e28b
KY
18436static void alc663_mode3_inithook(struct hda_codec *codec)
18437{
18438 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 18439 alc_mic_automute(codec);
f1d4e28b
KY
18440}
18441/* ***************** Mode4 ******************************/
18442static void alc663_mode4_unsol_event(struct hda_codec *codec,
18443 unsigned int res)
18444{
18445 switch (res >> 26) {
18446 case ALC880_HP_EVENT:
18447 alc663_21jd_two_speaker_automute(codec);
18448 break;
18449 case ALC880_MIC_EVENT:
4f5d1706 18450 alc_mic_automute(codec);
f1d4e28b
KY
18451 break;
18452 }
18453}
18454
ebb83eeb 18455#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 18456
f1d4e28b
KY
18457static void alc663_mode4_inithook(struct hda_codec *codec)
18458{
18459 alc663_21jd_two_speaker_automute(codec);
4f5d1706 18460 alc_mic_automute(codec);
f1d4e28b
KY
18461}
18462/* ***************** Mode5 ******************************/
18463static void alc663_mode5_unsol_event(struct hda_codec *codec,
18464 unsigned int res)
18465{
18466 switch (res >> 26) {
18467 case ALC880_HP_EVENT:
18468 alc663_15jd_two_speaker_automute(codec);
18469 break;
18470 case ALC880_MIC_EVENT:
4f5d1706 18471 alc_mic_automute(codec);
f1d4e28b
KY
18472 break;
18473 }
18474}
18475
ebb83eeb 18476#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 18477
f1d4e28b
KY
18478static void alc663_mode5_inithook(struct hda_codec *codec)
18479{
18480 alc663_15jd_two_speaker_automute(codec);
4f5d1706 18481 alc_mic_automute(codec);
f1d4e28b
KY
18482}
18483/* ***************** Mode6 ******************************/
18484static void alc663_mode6_unsol_event(struct hda_codec *codec,
18485 unsigned int res)
18486{
18487 switch (res >> 26) {
18488 case ALC880_HP_EVENT:
18489 alc663_two_hp_m2_speaker_automute(codec);
18490 break;
18491 case ALC880_MIC_EVENT:
4f5d1706 18492 alc_mic_automute(codec);
f1d4e28b
KY
18493 break;
18494 }
18495}
18496
ebb83eeb 18497#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 18498
f1d4e28b
KY
18499static void alc663_mode6_inithook(struct hda_codec *codec)
18500{
18501 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 18502 alc_mic_automute(codec);
f1d4e28b
KY
18503}
18504
ebb83eeb
KY
18505/* ***************** Mode7 ******************************/
18506static void alc663_mode7_unsol_event(struct hda_codec *codec,
18507 unsigned int res)
18508{
18509 switch (res >> 26) {
18510 case ALC880_HP_EVENT:
18511 alc663_two_hp_m7_speaker_automute(codec);
18512 break;
18513 case ALC880_MIC_EVENT:
18514 alc_mic_automute(codec);
18515 break;
18516 }
18517}
18518
18519#define alc663_mode7_setup alc663_mode1_setup
18520
18521static void alc663_mode7_inithook(struct hda_codec *codec)
18522{
18523 alc663_two_hp_m7_speaker_automute(codec);
18524 alc_mic_automute(codec);
18525}
18526
18527/* ***************** Mode8 ******************************/
18528static void alc663_mode8_unsol_event(struct hda_codec *codec,
18529 unsigned int res)
18530{
18531 switch (res >> 26) {
18532 case ALC880_HP_EVENT:
18533 alc663_two_hp_m8_speaker_automute(codec);
18534 break;
18535 case ALC880_MIC_EVENT:
18536 alc_mic_automute(codec);
18537 break;
18538 }
18539}
18540
18541#define alc663_mode8_setup alc663_m51va_setup
18542
18543static void alc663_mode8_inithook(struct hda_codec *codec)
18544{
18545 alc663_two_hp_m8_speaker_automute(codec);
18546 alc_mic_automute(codec);
18547}
18548
6dda9f4a
KY
18549static void alc663_g71v_hp_automute(struct hda_codec *codec)
18550{
18551 unsigned int present;
18552 unsigned char bits;
18553
864f92be 18554 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
18555 bits = present ? HDA_AMP_MUTE : 0;
18556 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18557 HDA_AMP_MUTE, bits);
18558 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18559 HDA_AMP_MUTE, bits);
18560}
18561
18562static void alc663_g71v_front_automute(struct hda_codec *codec)
18563{
18564 unsigned int present;
18565 unsigned char bits;
18566
864f92be 18567 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
18568 bits = present ? HDA_AMP_MUTE : 0;
18569 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18570 HDA_AMP_MUTE, bits);
18571}
18572
18573static void alc663_g71v_unsol_event(struct hda_codec *codec,
18574 unsigned int res)
18575{
18576 switch (res >> 26) {
18577 case ALC880_HP_EVENT:
18578 alc663_g71v_hp_automute(codec);
18579 break;
18580 case ALC880_FRONT_EVENT:
18581 alc663_g71v_front_automute(codec);
18582 break;
18583 case ALC880_MIC_EVENT:
4f5d1706 18584 alc_mic_automute(codec);
6dda9f4a
KY
18585 break;
18586 }
18587}
18588
4f5d1706
TI
18589#define alc663_g71v_setup alc663_m51va_setup
18590
6dda9f4a
KY
18591static void alc663_g71v_inithook(struct hda_codec *codec)
18592{
18593 alc663_g71v_front_automute(codec);
18594 alc663_g71v_hp_automute(codec);
4f5d1706 18595 alc_mic_automute(codec);
6dda9f4a
KY
18596}
18597
18598static void alc663_g50v_unsol_event(struct hda_codec *codec,
18599 unsigned int res)
18600{
18601 switch (res >> 26) {
18602 case ALC880_HP_EVENT:
18603 alc663_m51va_speaker_automute(codec);
18604 break;
18605 case ALC880_MIC_EVENT:
4f5d1706 18606 alc_mic_automute(codec);
6dda9f4a
KY
18607 break;
18608 }
18609}
18610
4f5d1706
TI
18611#define alc663_g50v_setup alc663_m51va_setup
18612
6dda9f4a
KY
18613static void alc663_g50v_inithook(struct hda_codec *codec)
18614{
18615 alc663_m51va_speaker_automute(codec);
4f5d1706 18616 alc_mic_automute(codec);
6dda9f4a
KY
18617}
18618
f1d4e28b
KY
18619static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18620 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18621 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b 18622
5f99f86a 18623 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
18624 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18625 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b 18626
5f99f86a 18627 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
18628 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18629 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
f1d4e28b
KY
18630 { } /* end */
18631};
18632
9541ba1d
CP
18633static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18634 /* Master Playback automatically created from Speaker and Headphone */
18635 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18636 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18637 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18638 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18639
8607f7c4
DH
18640 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18641 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 18642 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9541ba1d 18643
28c4edb7
DH
18644 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18645 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 18646 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9541ba1d
CP
18647 { } /* end */
18648};
18649
cb53c626
TI
18650#ifdef CONFIG_SND_HDA_POWER_SAVE
18651#define alc662_loopbacks alc880_loopbacks
18652#endif
18653
bc9f98a9 18654
def319f9 18655/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18656#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18657#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18658#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18659#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18660
18661/*
18662 * configuration and preset
18663 */
ea734963 18664static const char * const alc662_models[ALC662_MODEL_LAST] = {
bc9f98a9
KY
18665 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18666 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18667 [ALC662_3ST_6ch] = "3stack-6ch",
18668 [ALC662_5ST_DIG] = "6stack-dig",
18669 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18670 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18671 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18672 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18673 [ALC663_ASUS_M51VA] = "m51va",
18674 [ALC663_ASUS_G71V] = "g71v",
18675 [ALC663_ASUS_H13] = "h13",
18676 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18677 [ALC663_ASUS_MODE1] = "asus-mode1",
18678 [ALC662_ASUS_MODE2] = "asus-mode2",
18679 [ALC663_ASUS_MODE3] = "asus-mode3",
18680 [ALC663_ASUS_MODE4] = "asus-mode4",
18681 [ALC663_ASUS_MODE5] = "asus-mode5",
18682 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18683 [ALC663_ASUS_MODE7] = "asus-mode7",
18684 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18685 [ALC272_DELL] = "dell",
18686 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18687 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18688 [ALC662_AUTO] = "auto",
18689};
18690
18691static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18692 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18693 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18694 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18695 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18696 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18697 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18698 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18699 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18700 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18701 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18702 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18703 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18704 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18705 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18706 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18707 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18708 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18709 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18710 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18711 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18712 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18713 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18714 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18715 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18716 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18717 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18718 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18719 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18720 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18721 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18722 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18723 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18724 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18725 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18726 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18727 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18728 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18729 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18730 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18731 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18732 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18733 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18734 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18735 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18736 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18737 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18738 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18739 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18740 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18741 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18742 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18743 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18744 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18745 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18746 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18747 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18748 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18749 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18750 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18751 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18752 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18753 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18754 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18755 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18756 ALC662_3ST_6ch_DIG),
4dee8baa 18757 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18758 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
18759 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18760 ALC662_3ST_6ch_DIG),
6227cdce 18761 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18762 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18763 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18764 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18765 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18766 ALC662_3ST_6ch_DIG),
dea0a509
TI
18767 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18768 ALC663_ASUS_H13),
965b76d2 18769 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
bc9f98a9
KY
18770 {}
18771};
18772
18773static struct alc_config_preset alc662_presets[] = {
18774 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18775 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
18776 .init_verbs = { alc662_init_verbs },
18777 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18778 .dac_nids = alc662_dac_nids,
18779 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18780 .dig_in_nid = ALC662_DIGIN_NID,
18781 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18782 .channel_mode = alc662_3ST_2ch_modes,
18783 .input_mux = &alc662_capture_source,
18784 },
18785 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18786 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18787 .init_verbs = { alc662_init_verbs },
18788 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18789 .dac_nids = alc662_dac_nids,
18790 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18791 .dig_in_nid = ALC662_DIGIN_NID,
18792 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18793 .channel_mode = alc662_3ST_6ch_modes,
18794 .need_dac_fix = 1,
18795 .input_mux = &alc662_capture_source,
f12ab1e0 18796 },
bc9f98a9 18797 [ALC662_3ST_6ch] = {
f9e336f6 18798 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18799 .init_verbs = { alc662_init_verbs },
18800 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18801 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18802 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18803 .channel_mode = alc662_3ST_6ch_modes,
18804 .need_dac_fix = 1,
18805 .input_mux = &alc662_capture_source,
f12ab1e0 18806 },
bc9f98a9 18807 [ALC662_5ST_DIG] = {
f9e336f6 18808 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18809 .init_verbs = { alc662_init_verbs },
18810 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18811 .dac_nids = alc662_dac_nids,
18812 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18813 .dig_in_nid = ALC662_DIGIN_NID,
18814 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18815 .channel_mode = alc662_5stack_modes,
18816 .input_mux = &alc662_capture_source,
18817 },
18818 [ALC662_LENOVO_101E] = {
f9e336f6 18819 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
18820 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18821 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18822 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18823 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18824 .channel_mode = alc662_3ST_2ch_modes,
18825 .input_mux = &alc662_lenovo_101e_capture_source,
18826 .unsol_event = alc662_lenovo_101e_unsol_event,
18827 .init_hook = alc662_lenovo_101e_all_automute,
18828 },
291702f0 18829 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18830 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
18831 .init_verbs = { alc662_init_verbs,
18832 alc662_eeepc_sue_init_verbs },
18833 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18834 .dac_nids = alc662_dac_nids,
291702f0
KY
18835 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18836 .channel_mode = alc662_3ST_2ch_modes,
291702f0 18837 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18838 .setup = alc662_eeepc_setup,
291702f0
KY
18839 .init_hook = alc662_eeepc_inithook,
18840 },
8c427226 18841 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18842 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18843 alc662_chmode_mixer },
18844 .init_verbs = { alc662_init_verbs,
18845 alc662_eeepc_ep20_sue_init_verbs },
18846 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18847 .dac_nids = alc662_dac_nids,
8c427226
KY
18848 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18849 .channel_mode = alc662_3ST_6ch_modes,
18850 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 18851 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18852 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
18853 .init_hook = alc662_eeepc_ep20_inithook,
18854 },
f1d4e28b 18855 [ALC662_ECS] = {
f9e336f6 18856 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
18857 .init_verbs = { alc662_init_verbs,
18858 alc662_ecs_init_verbs },
18859 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18860 .dac_nids = alc662_dac_nids,
18861 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18862 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18863 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18864 .setup = alc662_eeepc_setup,
f1d4e28b
KY
18865 .init_hook = alc662_eeepc_inithook,
18866 },
6dda9f4a 18867 [ALC663_ASUS_M51VA] = {
f9e336f6 18868 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18869 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18870 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18871 .dac_nids = alc662_dac_nids,
18872 .dig_out_nid = ALC662_DIGOUT_NID,
18873 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18874 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18875 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18876 .setup = alc663_m51va_setup,
6dda9f4a
KY
18877 .init_hook = alc663_m51va_inithook,
18878 },
18879 [ALC663_ASUS_G71V] = {
f9e336f6 18880 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
18881 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18882 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
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,
6dda9f4a 18887 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 18888 .setup = alc663_g71v_setup,
6dda9f4a
KY
18889 .init_hook = alc663_g71v_inithook,
18890 },
18891 [ALC663_ASUS_H13] = {
f9e336f6 18892 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18893 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18894 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18895 .dac_nids = alc662_dac_nids,
18896 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18897 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
18898 .unsol_event = alc663_m51va_unsol_event,
18899 .init_hook = alc663_m51va_inithook,
18900 },
18901 [ALC663_ASUS_G50V] = {
f9e336f6 18902 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
18903 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18904 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18905 .dac_nids = alc662_dac_nids,
18906 .dig_out_nid = ALC662_DIGOUT_NID,
18907 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18908 .channel_mode = alc662_3ST_6ch_modes,
18909 .input_mux = &alc663_capture_source,
18910 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 18911 .setup = alc663_g50v_setup,
6dda9f4a
KY
18912 .init_hook = alc663_g50v_inithook,
18913 },
f1d4e28b 18914 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18915 .mixers = { alc663_m51va_mixer },
18916 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18917 .init_verbs = { alc662_init_verbs,
18918 alc663_21jd_amic_init_verbs },
18919 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18920 .hp_nid = 0x03,
18921 .dac_nids = alc662_dac_nids,
18922 .dig_out_nid = ALC662_DIGOUT_NID,
18923 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18924 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18925 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18926 .setup = alc663_mode1_setup,
f1d4e28b
KY
18927 .init_hook = alc663_mode1_inithook,
18928 },
18929 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18930 .mixers = { alc662_1bjd_mixer },
18931 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18932 .init_verbs = { alc662_init_verbs,
18933 alc662_1bjd_amic_init_verbs },
18934 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18935 .dac_nids = alc662_dac_nids,
18936 .dig_out_nid = ALC662_DIGOUT_NID,
18937 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18938 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18939 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18940 .setup = alc662_mode2_setup,
f1d4e28b
KY
18941 .init_hook = alc662_mode2_inithook,
18942 },
18943 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18944 .mixers = { alc663_two_hp_m1_mixer },
18945 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18946 .init_verbs = { alc662_init_verbs,
18947 alc663_two_hp_amic_m1_init_verbs },
18948 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18949 .hp_nid = 0x03,
18950 .dac_nids = alc662_dac_nids,
18951 .dig_out_nid = ALC662_DIGOUT_NID,
18952 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18953 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18954 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 18955 .setup = alc663_mode3_setup,
f1d4e28b
KY
18956 .init_hook = alc663_mode3_inithook,
18957 },
18958 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18959 .mixers = { alc663_asus_21jd_clfe_mixer },
18960 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18961 .init_verbs = { alc662_init_verbs,
18962 alc663_21jd_amic_init_verbs},
18963 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18964 .hp_nid = 0x03,
18965 .dac_nids = alc662_dac_nids,
18966 .dig_out_nid = ALC662_DIGOUT_NID,
18967 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18968 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18969 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18970 .setup = alc663_mode4_setup,
f1d4e28b
KY
18971 .init_hook = alc663_mode4_inithook,
18972 },
18973 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18974 .mixers = { alc663_asus_15jd_clfe_mixer },
18975 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18976 .init_verbs = { alc662_init_verbs,
18977 alc663_15jd_amic_init_verbs },
18978 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18979 .hp_nid = 0x03,
18980 .dac_nids = alc662_dac_nids,
18981 .dig_out_nid = ALC662_DIGOUT_NID,
18982 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18983 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18984 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 18985 .setup = alc663_mode5_setup,
f1d4e28b
KY
18986 .init_hook = alc663_mode5_inithook,
18987 },
18988 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18989 .mixers = { alc663_two_hp_m2_mixer },
18990 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18991 .init_verbs = { alc662_init_verbs,
18992 alc663_two_hp_amic_m2_init_verbs },
18993 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18994 .hp_nid = 0x03,
18995 .dac_nids = alc662_dac_nids,
18996 .dig_out_nid = ALC662_DIGOUT_NID,
18997 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18998 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18999 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 19000 .setup = alc663_mode6_setup,
f1d4e28b
KY
19001 .init_hook = alc663_mode6_inithook,
19002 },
ebb83eeb
KY
19003 [ALC663_ASUS_MODE7] = {
19004 .mixers = { alc663_mode7_mixer },
19005 .cap_mixer = alc662_auto_capture_mixer,
19006 .init_verbs = { alc662_init_verbs,
19007 alc663_mode7_init_verbs },
19008 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19009 .hp_nid = 0x03,
19010 .dac_nids = alc662_dac_nids,
19011 .dig_out_nid = ALC662_DIGOUT_NID,
19012 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19013 .channel_mode = alc662_3ST_2ch_modes,
19014 .unsol_event = alc663_mode7_unsol_event,
19015 .setup = alc663_mode7_setup,
19016 .init_hook = alc663_mode7_inithook,
19017 },
19018 [ALC663_ASUS_MODE8] = {
19019 .mixers = { alc663_mode8_mixer },
19020 .cap_mixer = alc662_auto_capture_mixer,
19021 .init_verbs = { alc662_init_verbs,
19022 alc663_mode8_init_verbs },
19023 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19024 .hp_nid = 0x03,
19025 .dac_nids = alc662_dac_nids,
19026 .dig_out_nid = ALC662_DIGOUT_NID,
19027 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19028 .channel_mode = alc662_3ST_2ch_modes,
19029 .unsol_event = alc663_mode8_unsol_event,
19030 .setup = alc663_mode8_setup,
19031 .init_hook = alc663_mode8_inithook,
19032 },
622e84cd
KY
19033 [ALC272_DELL] = {
19034 .mixers = { alc663_m51va_mixer },
19035 .cap_mixer = alc272_auto_capture_mixer,
19036 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
19037 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19038 .dac_nids = alc662_dac_nids,
19039 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19040 .adc_nids = alc272_adc_nids,
19041 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
19042 .capsrc_nids = alc272_capsrc_nids,
19043 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 19044 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 19045 .setup = alc663_m51va_setup,
622e84cd
KY
19046 .init_hook = alc663_m51va_inithook,
19047 },
19048 [ALC272_DELL_ZM1] = {
19049 .mixers = { alc663_m51va_mixer },
19050 .cap_mixer = alc662_auto_capture_mixer,
19051 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
19052 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19053 .dac_nids = alc662_dac_nids,
19054 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19055 .adc_nids = alc662_adc_nids,
b59bdf3b 19056 .num_adc_nids = 1,
622e84cd
KY
19057 .capsrc_nids = alc662_capsrc_nids,
19058 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 19059 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 19060 .setup = alc663_m51va_setup,
622e84cd
KY
19061 .init_hook = alc663_m51va_inithook,
19062 },
9541ba1d
CP
19063 [ALC272_SAMSUNG_NC10] = {
19064 .mixers = { alc272_nc10_mixer },
19065 .init_verbs = { alc662_init_verbs,
19066 alc663_21jd_amic_init_verbs },
19067 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19068 .dac_nids = alc272_dac_nids,
19069 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19070 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 19071 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 19072 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 19073 .setup = alc663_mode4_setup,
9541ba1d
CP
19074 .init_hook = alc663_mode4_inithook,
19075 },
bc9f98a9
KY
19076};
19077
19078
19079/*
19080 * BIOS auto configuration
19081 */
19082
7085ec12
TI
19083/* convert from MIX nid to DAC */
19084static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
19085{
19086 if (nid == 0x0f)
19087 return 0x02;
19088 else if (nid >= 0x0c && nid <= 0x0e)
19089 return nid - 0x0c + 0x02;
cc1c452e
DH
19090 else if (nid == 0x26) /* ALC887-VD has this DAC too */
19091 return 0x25;
7085ec12
TI
19092 else
19093 return 0;
19094}
19095
19096/* get MIX nid connected to the given pin targeted to DAC */
19097static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
19098 hda_nid_t dac)
19099{
cc1c452e 19100 hda_nid_t mix[5];
7085ec12
TI
19101 int i, num;
19102
19103 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
19104 for (i = 0; i < num; i++) {
19105 if (alc662_mix_to_dac(mix[i]) == dac)
19106 return mix[i];
19107 }
19108 return 0;
19109}
19110
19111/* look for an empty DAC slot */
19112static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
19113{
19114 struct alc_spec *spec = codec->spec;
19115 hda_nid_t srcs[5];
19116 int i, j, num;
19117
19118 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
19119 if (num < 0)
19120 return 0;
19121 for (i = 0; i < num; i++) {
19122 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
19123 if (!nid)
19124 continue;
19125 for (j = 0; j < spec->multiout.num_dacs; j++)
19126 if (spec->multiout.dac_nids[j] == nid)
19127 break;
19128 if (j >= spec->multiout.num_dacs)
19129 return nid;
19130 }
19131 return 0;
19132}
19133
19134/* fill in the dac_nids table from the parsed pin configuration */
19135static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19136 const struct auto_pin_cfg *cfg)
19137{
19138 struct alc_spec *spec = codec->spec;
19139 int i;
19140 hda_nid_t dac;
19141
19142 spec->multiout.dac_nids = spec->private_dac_nids;
19143 for (i = 0; i < cfg->line_outs; i++) {
19144 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
19145 if (!dac)
19146 continue;
19147 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19148 }
19149 return 0;
19150}
19151
bcb2f0f5
TI
19152static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
19153 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19154{
bcb2f0f5 19155 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
7085ec12
TI
19156 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
19157}
19158
bcb2f0f5
TI
19159static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19160 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19161{
bcb2f0f5 19162 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
7085ec12
TI
19163 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19164}
19165
bcb2f0f5
TI
19166#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19167 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19168#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19169 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
7085ec12
TI
19170#define alc662_add_stereo_vol(spec, pfx, nid) \
19171 alc662_add_vol_ctl(spec, pfx, nid, 3)
19172#define alc662_add_stereo_sw(spec, pfx, nid) \
19173 alc662_add_sw_ctl(spec, pfx, nid, 3)
19174
bc9f98a9 19175/* add playback controls from the parsed DAC table */
7085ec12 19176static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
19177 const struct auto_pin_cfg *cfg)
19178{
7085ec12 19179 struct alc_spec *spec = codec->spec;
ea734963 19180 static const char * const chname[4] = {
bc9f98a9
KY
19181 "Front", "Surround", NULL /*CLFE*/, "Side"
19182 };
bcb2f0f5 19183 const char *pfx = alc_get_line_out_pfx(cfg, true);
7085ec12 19184 hda_nid_t nid, mix;
bc9f98a9
KY
19185 int i, err;
19186
19187 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
19188 nid = spec->multiout.dac_nids[i];
19189 if (!nid)
19190 continue;
19191 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
19192 if (!mix)
bc9f98a9 19193 continue;
bcb2f0f5 19194 if (!pfx && i == 2) {
bc9f98a9 19195 /* Center/LFE */
7085ec12 19196 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
19197 if (err < 0)
19198 return err;
7085ec12 19199 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
19200 if (err < 0)
19201 return err;
7085ec12 19202 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
19203 if (err < 0)
19204 return err;
7085ec12 19205 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
19206 if (err < 0)
19207 return err;
19208 } else {
bcb2f0f5
TI
19209 const char *name = pfx;
19210 if (!name)
19211 name = chname[i];
19212 err = __alc662_add_vol_ctl(spec, name, nid, i, 3);
bc9f98a9
KY
19213 if (err < 0)
19214 return err;
bcb2f0f5 19215 err = __alc662_add_sw_ctl(spec, name, mix, i, 3);
bc9f98a9
KY
19216 if (err < 0)
19217 return err;
19218 }
19219 }
19220 return 0;
19221}
19222
19223/* add playback controls for speaker and HP outputs */
7085ec12
TI
19224/* return DAC nid if any new DAC is assigned */
19225static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
19226 const char *pfx)
19227{
7085ec12
TI
19228 struct alc_spec *spec = codec->spec;
19229 hda_nid_t nid, mix;
bc9f98a9 19230 int err;
bc9f98a9
KY
19231
19232 if (!pin)
19233 return 0;
7085ec12
TI
19234 nid = alc662_look_for_dac(codec, pin);
19235 if (!nid) {
7085ec12
TI
19236 /* the corresponding DAC is already occupied */
19237 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19238 return 0; /* no way */
19239 /* create a switch only */
0afe5f89 19240 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 19241 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
19242 }
19243
7085ec12
TI
19244 mix = alc662_dac_to_mix(codec, pin, nid);
19245 if (!mix)
19246 return 0;
19247 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19248 if (err < 0)
19249 return err;
19250 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19251 if (err < 0)
19252 return err;
19253 return nid;
bc9f98a9
KY
19254}
19255
19256/* create playback/capture controls for input pins */
05f5f477 19257#define alc662_auto_create_input_ctls \
4b7348a1 19258 alc882_auto_create_input_ctls
bc9f98a9
KY
19259
19260static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19261 hda_nid_t nid, int pin_type,
7085ec12 19262 hda_nid_t dac)
bc9f98a9 19263{
7085ec12 19264 int i, num;
ce503f38 19265 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 19266
f6c7e546 19267 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 19268 /* need the manual connection? */
7085ec12
TI
19269 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19270 if (num <= 1)
19271 return;
19272 for (i = 0; i < num; i++) {
19273 if (alc662_mix_to_dac(srcs[i]) != dac)
19274 continue;
19275 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
19276 return;
bc9f98a9
KY
19277 }
19278}
19279
19280static void alc662_auto_init_multi_out(struct hda_codec *codec)
19281{
19282 struct alc_spec *spec = codec->spec;
7085ec12 19283 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
19284 int i;
19285
19286 for (i = 0; i <= HDA_SIDE; i++) {
19287 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19288 if (nid)
baba8ee9 19289 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 19290 spec->multiout.dac_nids[i]);
bc9f98a9
KY
19291 }
19292}
19293
19294static void alc662_auto_init_hp_out(struct hda_codec *codec)
19295{
19296 struct alc_spec *spec = codec->spec;
19297 hda_nid_t pin;
19298
19299 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
19300 if (pin)
19301 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19302 spec->multiout.hp_nid);
f6c7e546
TI
19303 pin = spec->autocfg.speaker_pins[0];
19304 if (pin)
7085ec12
TI
19305 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19306 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
19307}
19308
bc9f98a9
KY
19309#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19310
19311static void alc662_auto_init_analog_input(struct hda_codec *codec)
19312{
19313 struct alc_spec *spec = codec->spec;
66ceeb6b 19314 struct auto_pin_cfg *cfg = &spec->autocfg;
bc9f98a9
KY
19315 int i;
19316
66ceeb6b
TI
19317 for (i = 0; i < cfg->num_inputs; i++) {
19318 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 19319 if (alc_is_input_pin(codec, nid)) {
30ea098f 19320 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
52ca15b7 19321 if (nid != ALC662_PIN_CD_NID &&
e82c025b 19322 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
19323 snd_hda_codec_write(codec, nid, 0,
19324 AC_VERB_SET_AMP_GAIN_MUTE,
19325 AMP_OUT_MUTE);
19326 }
19327 }
19328}
19329
f511b01c
TI
19330#define alc662_auto_init_input_src alc882_auto_init_input_src
19331
bc9f98a9
KY
19332static int alc662_parse_auto_config(struct hda_codec *codec)
19333{
19334 struct alc_spec *spec = codec->spec;
19335 int err;
19336 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19337
19338 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19339 alc662_ignore);
19340 if (err < 0)
19341 return err;
19342 if (!spec->autocfg.line_outs)
19343 return 0; /* can't find valid BIOS pin config */
19344
7085ec12 19345 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
19346 if (err < 0)
19347 return err;
7085ec12 19348 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19349 if (err < 0)
19350 return err;
7085ec12 19351 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
19352 spec->autocfg.speaker_pins[0],
19353 "Speaker");
19354 if (err < 0)
19355 return err;
7085ec12
TI
19356 if (err)
19357 spec->multiout.extra_out_nid[0] = err;
19358 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
19359 "Headphone");
19360 if (err < 0)
19361 return err;
7085ec12
TI
19362 if (err)
19363 spec->multiout.hp_nid = err;
05f5f477 19364 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19365 if (err < 0)
bc9f98a9
KY
19366 return err;
19367
19368 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19369
757899ac 19370 alc_auto_parse_digital(codec);
bc9f98a9 19371
603c4019 19372 if (spec->kctls.list)
d88897ea 19373 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19374
19375 spec->num_mux_defs = 1;
61b9b9b1 19376 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19377
cec27c89
KY
19378 add_verb(spec, alc662_init_verbs);
19379 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
d1eb57f4 19380 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
cec27c89
KY
19381 add_verb(spec, alc663_init_verbs);
19382
19383 if (codec->vendor_id == 0x10ec0272)
19384 add_verb(spec, alc272_init_verbs);
ee979a14
TI
19385
19386 err = alc_auto_add_mic_boost(codec);
19387 if (err < 0)
19388 return err;
19389
6227cdce
KY
19390 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19391 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19392 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19393 else
19394 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19395
8c87286f 19396 return 1;
bc9f98a9
KY
19397}
19398
19399/* additional initialization for auto-configuration model */
19400static void alc662_auto_init(struct hda_codec *codec)
19401{
f6c7e546 19402 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19403 alc662_auto_init_multi_out(codec);
19404 alc662_auto_init_hp_out(codec);
19405 alc662_auto_init_analog_input(codec);
f511b01c 19406 alc662_auto_init_input_src(codec);
757899ac 19407 alc_auto_init_digital(codec);
f6c7e546 19408 if (spec->unsol_event)
7fb0d78f 19409 alc_inithook(codec);
bc9f98a9
KY
19410}
19411
6be7948f 19412static void alc272_fixup_mario(struct hda_codec *codec,
b5bfbc67 19413 const struct alc_fixup *fix, int action)
6fc398cb 19414{
b5bfbc67 19415 if (action != ALC_FIXUP_ACT_PROBE)
6fc398cb 19416 return;
6be7948f
TB
19417 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19418 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19419 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19420 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19421 (0 << AC_AMPCAP_MUTE_SHIFT)))
19422 printk(KERN_WARNING
19423 "hda_codec: failed to override amp caps for NID 0x2\n");
19424}
19425
6cb3b707 19426enum {
2df03514 19427 ALC662_FIXUP_ASPIRE,
6cb3b707 19428 ALC662_FIXUP_IDEAPAD,
6be7948f 19429 ALC272_FIXUP_MARIO,
d2ebd479 19430 ALC662_FIXUP_CZC_P10T,
6cb3b707
DH
19431};
19432
19433static const struct alc_fixup alc662_fixups[] = {
2df03514 19434 [ALC662_FIXUP_ASPIRE] = {
b5bfbc67
TI
19435 .type = ALC_FIXUP_PINS,
19436 .v.pins = (const struct alc_pincfg[]) {
2df03514
DC
19437 { 0x15, 0x99130112 }, /* subwoofer */
19438 { }
19439 }
19440 },
6cb3b707 19441 [ALC662_FIXUP_IDEAPAD] = {
b5bfbc67
TI
19442 .type = ALC_FIXUP_PINS,
19443 .v.pins = (const struct alc_pincfg[]) {
6cb3b707
DH
19444 { 0x17, 0x99130112 }, /* subwoofer */
19445 { }
19446 }
19447 },
6be7948f 19448 [ALC272_FIXUP_MARIO] = {
b5bfbc67
TI
19449 .type = ALC_FIXUP_FUNC,
19450 .v.func = alc272_fixup_mario,
d2ebd479
AA
19451 },
19452 [ALC662_FIXUP_CZC_P10T] = {
19453 .type = ALC_FIXUP_VERBS,
19454 .v.verbs = (const struct hda_verb[]) {
19455 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19456 {}
19457 }
19458 },
6cb3b707
DH
19459};
19460
19461static struct snd_pci_quirk alc662_fixup_tbl[] = {
a6c47a85 19462 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
2df03514 19463 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
a0e90acc 19464 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
d4118588 19465 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707 19466 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
d2ebd479 19467 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6cb3b707
DH
19468 {}
19469};
19470
6be7948f
TB
19471static const struct alc_model_fixup alc662_fixup_models[] = {
19472 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19473 {}
19474};
6cb3b707
DH
19475
19476
bc9f98a9
KY
19477static int patch_alc662(struct hda_codec *codec)
19478{
19479 struct alc_spec *spec;
19480 int err, board_config;
693194f3 19481 int coef;
bc9f98a9
KY
19482
19483 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19484 if (!spec)
19485 return -ENOMEM;
19486
19487 codec->spec = spec;
19488
da00c244
KY
19489 alc_auto_parse_customize_define(codec);
19490
2c3bf9ab
TI
19491 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19492
693194f3
KY
19493 coef = alc_read_coef_idx(codec, 0);
19494 if (coef == 0x8020 || coef == 0x8011)
c027ddcd 19495 alc_codec_rename(codec, "ALC661");
693194f3
KY
19496 else if (coef & (1 << 14) &&
19497 codec->bus->pci->subsystem_vendor == 0x1025 &&
19498 spec->cdefine.platform_type == 1)
c027ddcd 19499 alc_codec_rename(codec, "ALC272X");
693194f3
KY
19500 else if (coef == 0x4011)
19501 alc_codec_rename(codec, "ALC656");
274693f3 19502
bc9f98a9
KY
19503 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19504 alc662_models,
19505 alc662_cfg_tbl);
19506 if (board_config < 0) {
9a11f1aa
TI
19507 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19508 codec->chip_name);
bc9f98a9
KY
19509 board_config = ALC662_AUTO;
19510 }
19511
19512 if (board_config == ALC662_AUTO) {
b5bfbc67
TI
19513 alc_pick_fixup(codec, alc662_fixup_models,
19514 alc662_fixup_tbl, alc662_fixups);
19515 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
bc9f98a9
KY
19516 /* automatic parse from the BIOS config */
19517 err = alc662_parse_auto_config(codec);
19518 if (err < 0) {
19519 alc_free(codec);
19520 return err;
8c87286f 19521 } else if (!err) {
bc9f98a9
KY
19522 printk(KERN_INFO
19523 "hda_codec: Cannot set up configuration "
19524 "from BIOS. Using base mode...\n");
19525 board_config = ALC662_3ST_2ch_DIG;
19526 }
19527 }
19528
dc1eae25 19529 if (has_cdefine_beep(codec)) {
8af2591d
TI
19530 err = snd_hda_attach_beep_device(codec, 0x1);
19531 if (err < 0) {
19532 alc_free(codec);
19533 return err;
19534 }
680cd536
KK
19535 }
19536
bc9f98a9 19537 if (board_config != ALC662_AUTO)
e9c364c0 19538 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19539
bc9f98a9
KY
19540 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19541 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19542
bc9f98a9
KY
19543 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19544 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19545
dd704698
TI
19546 if (!spec->adc_nids) {
19547 spec->adc_nids = alc662_adc_nids;
19548 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19549 }
19550 if (!spec->capsrc_nids)
19551 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19552
f9e336f6 19553 if (!spec->cap_mixer)
b59bdf3b 19554 set_capture_mixer(codec);
cec27c89 19555
dc1eae25 19556 if (has_cdefine_beep(codec)) {
da00c244
KY
19557 switch (codec->vendor_id) {
19558 case 0x10ec0662:
19559 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19560 break;
19561 case 0x10ec0272:
19562 case 0x10ec0663:
19563 case 0x10ec0665:
19564 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19565 break;
19566 case 0x10ec0273:
19567 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19568 break;
19569 }
cec27c89 19570 }
2134ea4f
TI
19571 spec->vmaster_nid = 0x02;
19572
b5bfbc67
TI
19573 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19574
bc9f98a9 19575 codec->patch_ops = alc_patch_ops;
b5bfbc67 19576 if (board_config == ALC662_AUTO)
bc9f98a9 19577 spec->init_hook = alc662_auto_init;
6cb3b707 19578
bf1b0225
KY
19579 alc_init_jacks(codec);
19580
cb53c626
TI
19581#ifdef CONFIG_SND_HDA_POWER_SAVE
19582 if (!spec->loopback.amplist)
19583 spec->loopback.amplist = alc662_loopbacks;
19584#endif
bc9f98a9
KY
19585
19586 return 0;
19587}
19588
274693f3
KY
19589static int patch_alc888(struct hda_codec *codec)
19590{
19591 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19592 kfree(codec->chip_name);
01e0f137
KY
19593 if (codec->vendor_id == 0x10ec0887)
19594 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19595 else
19596 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19597 if (!codec->chip_name) {
19598 alc_free(codec);
274693f3 19599 return -ENOMEM;
ac2c92e0
TI
19600 }
19601 return patch_alc662(codec);
274693f3 19602 }
ac2c92e0 19603 return patch_alc882(codec);
274693f3
KY
19604}
19605
d1eb57f4
KY
19606/*
19607 * ALC680 support
19608 */
c69aefab 19609#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19610#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19611#define alc680_modes alc260_modes
19612
19613static hda_nid_t alc680_dac_nids[3] = {
19614 /* Lout1, Lout2, hp */
19615 0x02, 0x03, 0x04
19616};
19617
19618static hda_nid_t alc680_adc_nids[3] = {
19619 /* ADC0-2 */
19620 /* DMIC, MIC, Line-in*/
19621 0x07, 0x08, 0x09
19622};
19623
c69aefab
KY
19624/*
19625 * Analog capture ADC cgange
19626 */
66ceeb6b
TI
19627static void alc680_rec_autoswitch(struct hda_codec *codec)
19628{
19629 struct alc_spec *spec = codec->spec;
19630 struct auto_pin_cfg *cfg = &spec->autocfg;
19631 int pin_found = 0;
19632 int type_found = AUTO_PIN_LAST;
19633 hda_nid_t nid;
19634 int i;
19635
19636 for (i = 0; i < cfg->num_inputs; i++) {
19637 nid = cfg->inputs[i].pin;
19638 if (!(snd_hda_query_pin_caps(codec, nid) &
19639 AC_PINCAP_PRES_DETECT))
19640 continue;
19641 if (snd_hda_jack_detect(codec, nid)) {
19642 if (cfg->inputs[i].type < type_found) {
19643 type_found = cfg->inputs[i].type;
19644 pin_found = nid;
19645 }
19646 }
19647 }
19648
19649 nid = 0x07;
19650 if (pin_found)
19651 snd_hda_get_connections(codec, pin_found, &nid, 1);
19652
19653 if (nid != spec->cur_adc)
19654 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19655 spec->cur_adc = nid;
19656 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19657 spec->cur_adc_format);
19658}
19659
c69aefab
KY
19660static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19661 struct hda_codec *codec,
19662 unsigned int stream_tag,
19663 unsigned int format,
19664 struct snd_pcm_substream *substream)
19665{
19666 struct alc_spec *spec = codec->spec;
c69aefab 19667
66ceeb6b 19668 spec->cur_adc = 0x07;
c69aefab
KY
19669 spec->cur_adc_stream_tag = stream_tag;
19670 spec->cur_adc_format = format;
19671
66ceeb6b 19672 alc680_rec_autoswitch(codec);
c69aefab
KY
19673 return 0;
19674}
19675
19676static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19677 struct hda_codec *codec,
19678 struct snd_pcm_substream *substream)
19679{
19680 snd_hda_codec_cleanup_stream(codec, 0x07);
19681 snd_hda_codec_cleanup_stream(codec, 0x08);
19682 snd_hda_codec_cleanup_stream(codec, 0x09);
19683 return 0;
19684}
19685
19686static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19687 .substreams = 1, /* can be overridden */
19688 .channels_min = 2,
19689 .channels_max = 2,
19690 /* NID is set in alc_build_pcms */
19691 .ops = {
19692 .prepare = alc680_capture_pcm_prepare,
19693 .cleanup = alc680_capture_pcm_cleanup
19694 },
19695};
19696
d1eb57f4
KY
19697static struct snd_kcontrol_new alc680_base_mixer[] = {
19698 /* output mixer control */
19699 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19700 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19701 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19702 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5f99f86a
DH
19703 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19704 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19705 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19706 { }
19707};
19708
c69aefab
KY
19709static struct hda_bind_ctls alc680_bind_cap_vol = {
19710 .ops = &snd_hda_bind_vol,
19711 .values = {
19712 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19713 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19714 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19715 0
19716 },
19717};
19718
19719static struct hda_bind_ctls alc680_bind_cap_switch = {
19720 .ops = &snd_hda_bind_sw,
19721 .values = {
19722 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19723 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19724 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19725 0
19726 },
19727};
19728
19729static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19730 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19731 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19732 { } /* end */
19733};
19734
19735/*
19736 * generic initialization of ADC, input mixers and output mixers
19737 */
19738static struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19739 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19740 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19741 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19742
c69aefab
KY
19743 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19744 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19745 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19746 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19747 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19748 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19749
19750 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19751 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19752 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19753 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19754 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19755
19756 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19757 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19758 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19759
d1eb57f4
KY
19760 { }
19761};
19762
c69aefab
KY
19763/* toggle speaker-output according to the hp-jack state */
19764static void alc680_base_setup(struct hda_codec *codec)
19765{
19766 struct alc_spec *spec = codec->spec;
19767
19768 spec->autocfg.hp_pins[0] = 0x16;
19769 spec->autocfg.speaker_pins[0] = 0x14;
19770 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19771 spec->autocfg.num_inputs = 2;
19772 spec->autocfg.inputs[0].pin = 0x18;
19773 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19774 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19775 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
c69aefab
KY
19776}
19777
19778static void alc680_unsol_event(struct hda_codec *codec,
19779 unsigned int res)
19780{
19781 if ((res >> 26) == ALC880_HP_EVENT)
19782 alc_automute_amp(codec);
19783 if ((res >> 26) == ALC880_MIC_EVENT)
19784 alc680_rec_autoswitch(codec);
19785}
19786
19787static void alc680_inithook(struct hda_codec *codec)
19788{
19789 alc_automute_amp(codec);
19790 alc680_rec_autoswitch(codec);
19791}
19792
d1eb57f4
KY
19793/* create input playback/capture controls for the given pin */
19794static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19795 const char *ctlname, int idx)
19796{
19797 hda_nid_t dac;
19798 int err;
19799
19800 switch (nid) {
19801 case 0x14:
19802 dac = 0x02;
19803 break;
19804 case 0x15:
19805 dac = 0x03;
19806 break;
19807 case 0x16:
19808 dac = 0x04;
19809 break;
19810 default:
19811 return 0;
19812 }
19813 if (spec->multiout.dac_nids[0] != dac &&
19814 spec->multiout.dac_nids[1] != dac) {
19815 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19816 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19817 HDA_OUTPUT));
19818 if (err < 0)
19819 return err;
19820
19821 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19822 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19823
19824 if (err < 0)
19825 return err;
19826 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19827 }
19828
19829 return 0;
19830}
19831
19832/* add playback controls from the parsed DAC table */
19833static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19834 const struct auto_pin_cfg *cfg)
19835{
19836 hda_nid_t nid;
19837 int err;
19838
19839 spec->multiout.dac_nids = spec->private_dac_nids;
19840
19841 nid = cfg->line_out_pins[0];
19842 if (nid) {
19843 const char *name;
19844 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19845 name = "Speaker";
19846 else
19847 name = "Front";
19848 err = alc680_new_analog_output(spec, nid, name, 0);
19849 if (err < 0)
19850 return err;
19851 }
19852
19853 nid = cfg->speaker_pins[0];
19854 if (nid) {
19855 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19856 if (err < 0)
19857 return err;
19858 }
19859 nid = cfg->hp_pins[0];
19860 if (nid) {
19861 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19862 if (err < 0)
19863 return err;
19864 }
19865
19866 return 0;
19867}
19868
19869static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19870 hda_nid_t nid, int pin_type)
19871{
19872 alc_set_pin_output(codec, nid, pin_type);
19873}
19874
19875static void alc680_auto_init_multi_out(struct hda_codec *codec)
19876{
19877 struct alc_spec *spec = codec->spec;
19878 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19879 if (nid) {
19880 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19881 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19882 }
19883}
19884
19885static void alc680_auto_init_hp_out(struct hda_codec *codec)
19886{
19887 struct alc_spec *spec = codec->spec;
19888 hda_nid_t pin;
19889
19890 pin = spec->autocfg.hp_pins[0];
19891 if (pin)
19892 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19893 pin = spec->autocfg.speaker_pins[0];
19894 if (pin)
19895 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19896}
19897
19898/* pcm configuration: identical with ALC880 */
19899#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19900#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19901#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19902#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19903#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19904
19905/*
19906 * BIOS auto configuration
19907 */
19908static int alc680_parse_auto_config(struct hda_codec *codec)
19909{
19910 struct alc_spec *spec = codec->spec;
19911 int err;
19912 static hda_nid_t alc680_ignore[] = { 0 };
19913
19914 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19915 alc680_ignore);
19916 if (err < 0)
19917 return err;
c69aefab 19918
d1eb57f4
KY
19919 if (!spec->autocfg.line_outs) {
19920 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19921 spec->multiout.max_channels = 2;
19922 spec->no_analog = 1;
19923 goto dig_only;
19924 }
19925 return 0; /* can't find valid BIOS pin config */
19926 }
19927 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19928 if (err < 0)
19929 return err;
19930
19931 spec->multiout.max_channels = 2;
19932
19933 dig_only:
19934 /* digital only support output */
757899ac 19935 alc_auto_parse_digital(codec);
d1eb57f4
KY
19936 if (spec->kctls.list)
19937 add_mixer(spec, spec->kctls.list);
19938
19939 add_verb(spec, alc680_init_verbs);
d1eb57f4
KY
19940
19941 err = alc_auto_add_mic_boost(codec);
19942 if (err < 0)
19943 return err;
19944
19945 return 1;
19946}
19947
19948#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19949
19950/* init callback for auto-configuration model -- overriding the default init */
19951static void alc680_auto_init(struct hda_codec *codec)
19952{
19953 struct alc_spec *spec = codec->spec;
19954 alc680_auto_init_multi_out(codec);
19955 alc680_auto_init_hp_out(codec);
19956 alc680_auto_init_analog_input(codec);
757899ac 19957 alc_auto_init_digital(codec);
d1eb57f4
KY
19958 if (spec->unsol_event)
19959 alc_inithook(codec);
19960}
19961
19962/*
19963 * configuration and preset
19964 */
ea734963 19965static const char * const alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19966 [ALC680_BASE] = "base",
19967 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19968};
19969
19970static struct snd_pci_quirk alc680_cfg_tbl[] = {
19971 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19972 {}
19973};
19974
19975static struct alc_config_preset alc680_presets[] = {
19976 [ALC680_BASE] = {
19977 .mixers = { alc680_base_mixer },
c69aefab 19978 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
19979 .init_verbs = { alc680_init_verbs },
19980 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19981 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
19982 .dig_out_nid = ALC680_DIGOUT_NID,
19983 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19984 .channel_mode = alc680_modes,
c69aefab
KY
19985 .unsol_event = alc680_unsol_event,
19986 .setup = alc680_base_setup,
19987 .init_hook = alc680_inithook,
19988
d1eb57f4
KY
19989 },
19990};
19991
19992static int patch_alc680(struct hda_codec *codec)
19993{
19994 struct alc_spec *spec;
19995 int board_config;
19996 int err;
19997
19998 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19999 if (spec == NULL)
20000 return -ENOMEM;
20001
20002 codec->spec = spec;
20003
20004 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
20005 alc680_models,
20006 alc680_cfg_tbl);
20007
20008 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
20009 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
20010 codec->chip_name);
20011 board_config = ALC680_AUTO;
20012 }
20013
20014 if (board_config == ALC680_AUTO) {
20015 /* automatic parse from the BIOS config */
20016 err = alc680_parse_auto_config(codec);
20017 if (err < 0) {
20018 alc_free(codec);
20019 return err;
20020 } else if (!err) {
20021 printk(KERN_INFO
20022 "hda_codec: Cannot set up configuration "
20023 "from BIOS. Using base mode...\n");
20024 board_config = ALC680_BASE;
20025 }
20026 }
20027
20028 if (board_config != ALC680_AUTO)
20029 setup_preset(codec, &alc680_presets[board_config]);
20030
20031 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 20032 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 20033 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 20034 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
20035
20036 if (!spec->adc_nids) {
20037 spec->adc_nids = alc680_adc_nids;
20038 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20039 }
20040
20041 if (!spec->cap_mixer)
20042 set_capture_mixer(codec);
20043
20044 spec->vmaster_nid = 0x02;
20045
20046 codec->patch_ops = alc_patch_ops;
20047 if (board_config == ALC680_AUTO)
20048 spec->init_hook = alc680_auto_init;
20049
20050 return 0;
20051}
20052
1da177e4
LT
20053/*
20054 * patch entries
20055 */
1289e9e8 20056static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 20057 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 20058 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 20059 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 20060 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 20061 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 20062 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 20063 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 20064 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 20065 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 20066 .patch = patch_alc861 },
f32610ed
JS
20067 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20068 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20069 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 20070 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 20071 .patch = patch_alc882 },
bc9f98a9
KY
20072 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20073 .patch = patch_alc662 },
6dda9f4a 20074 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 20075 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 20076 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 20077 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 20078 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 20079 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 20080 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 20081 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 20082 .patch = patch_alc882 },
cb308f97 20083 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 20084 .patch = patch_alc882 },
df694daa 20085 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
01e0f137 20086 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
4442608d 20087 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 20088 .patch = patch_alc882 },
274693f3 20089 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 20090 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 20091 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
20092 {} /* terminator */
20093};
1289e9e8
TI
20094
20095MODULE_ALIAS("snd-hda-codec-id:10ec*");
20096
20097MODULE_LICENSE("GPL");
20098MODULE_DESCRIPTION("Realtek HD-audio codec");
20099
20100static struct hda_codec_preset_list realtek_list = {
20101 .preset = snd_hda_preset_realtek,
20102 .owner = THIS_MODULE,
20103};
20104
20105static int __init patch_realtek_init(void)
20106{
20107 return snd_hda_add_codec_preset(&realtek_list);
20108}
20109
20110static void __exit patch_realtek_exit(void)
20111{
20112 snd_hda_delete_codec_preset(&realtek_list);
20113}
20114
20115module_init(patch_realtek_init)
20116module_exit(patch_realtek_exit)
This page took 2.752861 seconds and 5 git commands to generate.