Merge branch 's5p-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[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
9ad0e496
KY
285struct alc_jack {
286 hda_nid_t nid;
287 int type;
288 struct snd_jack *jack;
289};
290
6c819492
TI
291#define MUX_IDX_UNDEF ((unsigned char)-1)
292
da00c244
KY
293struct alc_customize_define {
294 unsigned int sku_cfg;
295 unsigned char port_connectivity;
296 unsigned char check_sum;
297 unsigned char customization;
298 unsigned char external_amp;
299 unsigned int enable_pcbeep:1;
300 unsigned int platform_type:1;
301 unsigned int swap:1;
302 unsigned int override:1;
90622917 303 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
da00c244
KY
304};
305
b5bfbc67
TI
306struct alc_fixup;
307
1da177e4
LT
308struct alc_spec {
309 /* codec parameterization */
df694daa 310 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 311 unsigned int num_mixers;
f9e336f6 312 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 313 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 314
2d9c6482 315 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
316 * don't forget NULL
317 * termination!
e9edcee0
TI
318 */
319 unsigned int num_init_verbs;
1da177e4 320
aa563af7 321 char stream_name_analog[32]; /* analog PCM stream */
1da177e4
LT
322 struct hda_pcm_stream *stream_analog_playback;
323 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
324 struct hda_pcm_stream *stream_analog_alt_playback;
325 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 326
aa563af7 327 char stream_name_digital[32]; /* digital PCM stream */
1da177e4
LT
328 struct hda_pcm_stream *stream_digital_playback;
329 struct hda_pcm_stream *stream_digital_capture;
330
331 /* playback */
16ded525
TI
332 struct hda_multi_out multiout; /* playback set-up
333 * max_channels, dacs must be set
334 * dig_out_nid and hp_nid are optional
335 */
6330079f 336 hda_nid_t alt_dac_nid;
6a05ac4a 337 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 338 int dig_out_type;
1da177e4
LT
339
340 /* capture */
341 unsigned int num_adc_nids;
342 hda_nid_t *adc_nids;
e1406348 343 hda_nid_t *capsrc_nids;
16ded525 344 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4 345
840b64c0
TI
346 /* capture setup for dynamic dual-adc switch */
347 unsigned int cur_adc_idx;
348 hda_nid_t cur_adc;
349 unsigned int cur_adc_stream_tag;
350 unsigned int cur_adc_format;
351
1da177e4 352 /* capture source */
a1e8d2da 353 unsigned int num_mux_defs;
1da177e4
LT
354 const struct hda_input_mux *input_mux;
355 unsigned int cur_mux[3];
6c819492
TI
356 struct alc_mic_route ext_mic;
357 struct alc_mic_route int_mic;
1da177e4
LT
358
359 /* channel model */
d2a6d7dc 360 const struct hda_channel_mode *channel_mode;
1da177e4 361 int num_channel_mode;
4e195a7b 362 int need_dac_fix;
3b315d70
HM
363 int const_channel_count;
364 int ext_channel_count;
1da177e4
LT
365
366 /* PCM information */
4c5186ed 367 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 368
9ad0e496
KY
369 /* jack detection */
370 struct snd_array jacks;
371
e9edcee0
TI
372 /* dynamic controls, init_verbs and input_mux */
373 struct auto_pin_cfg autocfg;
da00c244 374 struct alc_customize_define cdefine;
603c4019 375 struct snd_array kctls;
61b9b9b1 376 struct hda_input_mux private_imux[3];
41923e44 377 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
378 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
379 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 380
ae6b813a
TI
381 /* hooks */
382 void (*init_hook)(struct hda_codec *codec);
383 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 384#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 385 void (*power_hook)(struct hda_codec *codec);
f5de24b0 386#endif
ae6b813a 387
834be88d
TI
388 /* for pin sensing */
389 unsigned int sense_updated: 1;
390 unsigned int jack_present: 1;
bec15c3a 391 unsigned int master_sw: 1;
6c819492 392 unsigned int auto_mic:1;
cb53c626 393
e64f14f4
TI
394 /* other flags */
395 unsigned int no_analog :1; /* digital I/O only */
840b64c0 396 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
4a79ba34 397 int init_amp;
d433a678 398 int codec_variant; /* flag for other variants */
e64f14f4 399
2134ea4f
TI
400 /* for virtual master */
401 hda_nid_t vmaster_nid;
cb53c626
TI
402#ifdef CONFIG_SND_HDA_POWER_SAVE
403 struct hda_loopback_check loopback;
404#endif
2c3bf9ab
TI
405
406 /* for PLL fix */
407 hda_nid_t pll_nid;
408 unsigned int pll_coef_idx, pll_coef_bit;
b5bfbc67
TI
409
410 /* fix-up list */
411 int fixup_id;
412 const struct alc_fixup *fixup_list;
413 const char *fixup_name;
df694daa
KY
414};
415
416/*
417 * configuration template - to be copied to the spec instance
418 */
419struct alc_config_preset {
9c7f852e
TI
420 struct snd_kcontrol_new *mixers[5]; /* should be identical size
421 * with spec
422 */
f9e336f6 423 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
424 const struct hda_verb *init_verbs[5];
425 unsigned int num_dacs;
426 hda_nid_t *dac_nids;
427 hda_nid_t dig_out_nid; /* optional */
428 hda_nid_t hp_nid; /* optional */
b25c9da1 429 hda_nid_t *slave_dig_outs;
df694daa
KY
430 unsigned int num_adc_nids;
431 hda_nid_t *adc_nids;
e1406348 432 hda_nid_t *capsrc_nids;
df694daa
KY
433 hda_nid_t dig_in_nid;
434 unsigned int num_channel_mode;
435 const struct hda_channel_mode *channel_mode;
4e195a7b 436 int need_dac_fix;
3b315d70 437 int const_channel_count;
a1e8d2da 438 unsigned int num_mux_defs;
df694daa 439 const struct hda_input_mux *input_mux;
ae6b813a 440 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 441 void (*setup)(struct hda_codec *);
ae6b813a 442 void (*init_hook)(struct hda_codec *);
cb53c626
TI
443#ifdef CONFIG_SND_HDA_POWER_SAVE
444 struct hda_amp_list *loopbacks;
c97259df 445 void (*power_hook)(struct hda_codec *codec);
cb53c626 446#endif
1da177e4
LT
447};
448
1da177e4
LT
449
450/*
451 * input MUX handling
452 */
9c7f852e
TI
453static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
454 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
455{
456 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
457 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
458 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
459 if (mux_idx >= spec->num_mux_defs)
460 mux_idx = 0;
5311114d
TI
461 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
462 mux_idx = 0;
a1e8d2da 463 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
464}
465
9c7f852e
TI
466static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
467 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
468{
469 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
470 struct alc_spec *spec = codec->spec;
471 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
472
473 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
474 return 0;
475}
476
9c7f852e
TI
477static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
478 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
479{
480 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
481 struct alc_spec *spec = codec->spec;
cd896c33 482 const struct hda_input_mux *imux;
1da177e4 483 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 484 unsigned int mux_idx;
e1406348
TI
485 hda_nid_t nid = spec->capsrc_nids ?
486 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 487 unsigned int type;
1da177e4 488
cd896c33
TI
489 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
490 imux = &spec->input_mux[mux_idx];
5311114d
TI
491 if (!imux->num_items && mux_idx > 0)
492 imux = &spec->input_mux[0];
cd896c33 493
a22d543a 494 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 495 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
496 /* Matrix-mixer style (e.g. ALC882) */
497 unsigned int *cur_val = &spec->cur_mux[adc_idx];
498 unsigned int i, idx;
499
500 idx = ucontrol->value.enumerated.item[0];
501 if (idx >= imux->num_items)
502 idx = imux->num_items - 1;
503 if (*cur_val == idx)
504 return 0;
505 for (i = 0; i < imux->num_items; i++) {
506 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
507 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
508 imux->items[i].index,
509 HDA_AMP_MUTE, v);
510 }
511 *cur_val = idx;
512 return 1;
513 } else {
514 /* MUX style (e.g. ALC880) */
cd896c33 515 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
516 &spec->cur_mux[adc_idx]);
517 }
518}
e9edcee0 519
1da177e4
LT
520/*
521 * channel mode setting
522 */
9c7f852e
TI
523static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
524 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
525{
526 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
527 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
528 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
529 spec->num_channel_mode);
1da177e4
LT
530}
531
9c7f852e
TI
532static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
533 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
534{
535 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
536 struct alc_spec *spec = codec->spec;
d2a6d7dc 537 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 538 spec->num_channel_mode,
3b315d70 539 spec->ext_channel_count);
1da177e4
LT
540}
541
9c7f852e
TI
542static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
543 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
544{
545 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
546 struct alc_spec *spec = codec->spec;
4e195a7b
TI
547 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
548 spec->num_channel_mode,
3b315d70
HM
549 &spec->ext_channel_count);
550 if (err >= 0 && !spec->const_channel_count) {
551 spec->multiout.max_channels = spec->ext_channel_count;
552 if (spec->need_dac_fix)
553 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
554 }
4e195a7b 555 return err;
1da177e4
LT
556}
557
a9430dd8 558/*
4c5186ed 559 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 560 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
561 * being part of a format specifier. Maximum allowed length of a value is
562 * 63 characters plus NULL terminator.
7cf51e48
JW
563 *
564 * Note: some retasking pin complexes seem to ignore requests for input
565 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
566 * are requested. Therefore order this list so that this behaviour will not
567 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
568 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
569 * March 2006.
4c5186ed
JW
570 */
571static char *alc_pin_mode_names[] = {
7cf51e48
JW
572 "Mic 50pc bias", "Mic 80pc bias",
573 "Line in", "Line out", "Headphone out",
4c5186ed
JW
574};
575static unsigned char alc_pin_mode_values[] = {
7cf51e48 576 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
577};
578/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
579 * in the pin being assumed to be exclusively an input or an output pin. In
580 * addition, "input" pins may or may not process the mic bias option
581 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
582 * accept requests for bias as of chip versions up to March 2006) and/or
583 * wiring in the computer.
a9430dd8 584 */
a1e8d2da
JW
585#define ALC_PIN_DIR_IN 0x00
586#define ALC_PIN_DIR_OUT 0x01
587#define ALC_PIN_DIR_INOUT 0x02
588#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
589#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 590
ea1fb29a 591/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
592 * For each direction the minimum and maximum values are given.
593 */
a1e8d2da 594static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
595 { 0, 2 }, /* ALC_PIN_DIR_IN */
596 { 3, 4 }, /* ALC_PIN_DIR_OUT */
597 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
598 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
599 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
600};
601#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
602#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
603#define alc_pin_mode_n_items(_dir) \
604 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
605
9c7f852e
TI
606static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
607 struct snd_ctl_elem_info *uinfo)
a9430dd8 608{
4c5186ed
JW
609 unsigned int item_num = uinfo->value.enumerated.item;
610 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
611
612 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 613 uinfo->count = 1;
4c5186ed
JW
614 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
615
616 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
617 item_num = alc_pin_mode_min(dir);
618 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
619 return 0;
620}
621
9c7f852e
TI
622static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
623 struct snd_ctl_elem_value *ucontrol)
a9430dd8 624{
4c5186ed 625 unsigned int i;
a9430dd8
JW
626 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
627 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 628 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 629 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
630 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
631 AC_VERB_GET_PIN_WIDGET_CONTROL,
632 0x00);
a9430dd8 633
4c5186ed
JW
634 /* Find enumerated value for current pinctl setting */
635 i = alc_pin_mode_min(dir);
4b35d2ca 636 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 637 i++;
9c7f852e 638 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
639 return 0;
640}
641
9c7f852e
TI
642static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
643 struct snd_ctl_elem_value *ucontrol)
a9430dd8 644{
4c5186ed 645 signed int change;
a9430dd8
JW
646 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
647 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
648 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
649 long val = *ucontrol->value.integer.value;
9c7f852e
TI
650 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
651 AC_VERB_GET_PIN_WIDGET_CONTROL,
652 0x00);
a9430dd8 653
f12ab1e0 654 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
655 val = alc_pin_mode_min(dir);
656
657 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
658 if (change) {
659 /* Set pin mode to that requested */
82beb8fd
TI
660 snd_hda_codec_write_cache(codec, nid, 0,
661 AC_VERB_SET_PIN_WIDGET_CONTROL,
662 alc_pin_mode_values[val]);
cdcd9268 663
ea1fb29a 664 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
665 * for the requested pin mode. Enum values of 2 or less are
666 * input modes.
667 *
668 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
669 * reduces noise slightly (particularly on input) so we'll
670 * do it. However, having both input and output buffers
671 * enabled simultaneously doesn't seem to be problematic if
672 * this turns out to be necessary in the future.
cdcd9268
JW
673 */
674 if (val <= 2) {
47fd830a
TI
675 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
676 HDA_AMP_MUTE, HDA_AMP_MUTE);
677 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
678 HDA_AMP_MUTE, 0);
cdcd9268 679 } else {
47fd830a
TI
680 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
681 HDA_AMP_MUTE, HDA_AMP_MUTE);
682 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
683 HDA_AMP_MUTE, 0);
cdcd9268
JW
684 }
685 }
a9430dd8
JW
686 return change;
687}
688
4c5186ed 689#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 690 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 691 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
692 .info = alc_pin_mode_info, \
693 .get = alc_pin_mode_get, \
694 .put = alc_pin_mode_put, \
695 .private_value = nid | (dir<<16) }
df694daa 696
5c8f858d
JW
697/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
698 * together using a mask with more than one bit set. This control is
699 * currently used only by the ALC260 test model. At this stage they are not
700 * needed for any "production" models.
701 */
702#ifdef CONFIG_SND_DEBUG
a5ce8890 703#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 704
9c7f852e
TI
705static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
706 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
707{
708 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
709 hda_nid_t nid = kcontrol->private_value & 0xffff;
710 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
711 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
712 unsigned int val = snd_hda_codec_read(codec, nid, 0,
713 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
714
715 *valp = (val & mask) != 0;
716 return 0;
717}
9c7f852e
TI
718static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
719 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
720{
721 signed int change;
722 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
723 hda_nid_t nid = kcontrol->private_value & 0xffff;
724 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
725 long val = *ucontrol->value.integer.value;
9c7f852e
TI
726 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
727 AC_VERB_GET_GPIO_DATA,
728 0x00);
5c8f858d
JW
729
730 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
731 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
732 if (val == 0)
5c8f858d
JW
733 gpio_data &= ~mask;
734 else
735 gpio_data |= mask;
82beb8fd
TI
736 snd_hda_codec_write_cache(codec, nid, 0,
737 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
738
739 return change;
740}
741#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
742 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 743 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
744 .info = alc_gpio_data_info, \
745 .get = alc_gpio_data_get, \
746 .put = alc_gpio_data_put, \
747 .private_value = nid | (mask<<16) }
748#endif /* CONFIG_SND_DEBUG */
749
92621f13
JW
750/* A switch control to allow the enabling of the digital IO pins on the
751 * ALC260. This is incredibly simplistic; the intention of this control is
752 * to provide something in the test model allowing digital outputs to be
753 * identified if present. If models are found which can utilise these
754 * outputs a more complete mixer control can be devised for those models if
755 * necessary.
756 */
757#ifdef CONFIG_SND_DEBUG
a5ce8890 758#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 759
9c7f852e
TI
760static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
761 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
762{
763 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
764 hda_nid_t nid = kcontrol->private_value & 0xffff;
765 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
766 long *valp = ucontrol->value.integer.value;
9c7f852e 767 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 768 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
769
770 *valp = (val & mask) != 0;
771 return 0;
772}
9c7f852e
TI
773static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
774 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
775{
776 signed int change;
777 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
778 hda_nid_t nid = kcontrol->private_value & 0xffff;
779 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
780 long val = *ucontrol->value.integer.value;
9c7f852e 781 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 782 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 783 0x00);
92621f13
JW
784
785 /* Set/unset the masked control bit(s) as needed */
9c7f852e 786 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
787 if (val==0)
788 ctrl_data &= ~mask;
789 else
790 ctrl_data |= mask;
82beb8fd
TI
791 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
792 ctrl_data);
92621f13
JW
793
794 return change;
795}
796#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
797 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 798 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
799 .info = alc_spdif_ctrl_info, \
800 .get = alc_spdif_ctrl_get, \
801 .put = alc_spdif_ctrl_put, \
802 .private_value = nid | (mask<<16) }
803#endif /* CONFIG_SND_DEBUG */
804
f8225f6d
JW
805/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
806 * Again, this is only used in the ALC26x test models to help identify when
807 * the EAPD line must be asserted for features to work.
808 */
809#ifdef CONFIG_SND_DEBUG
810#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
811
812static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
813 struct snd_ctl_elem_value *ucontrol)
814{
815 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
816 hda_nid_t nid = kcontrol->private_value & 0xffff;
817 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
818 long *valp = ucontrol->value.integer.value;
819 unsigned int val = snd_hda_codec_read(codec, nid, 0,
820 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
821
822 *valp = (val & mask) != 0;
823 return 0;
824}
825
826static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
827 struct snd_ctl_elem_value *ucontrol)
828{
829 int change;
830 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
831 hda_nid_t nid = kcontrol->private_value & 0xffff;
832 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
833 long val = *ucontrol->value.integer.value;
834 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
835 AC_VERB_GET_EAPD_BTLENABLE,
836 0x00);
837
838 /* Set/unset the masked control bit(s) as needed */
839 change = (!val ? 0 : mask) != (ctrl_data & mask);
840 if (!val)
841 ctrl_data &= ~mask;
842 else
843 ctrl_data |= mask;
844 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
845 ctrl_data);
846
847 return change;
848}
849
850#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
851 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 852 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
853 .info = alc_eapd_ctrl_info, \
854 .get = alc_eapd_ctrl_get, \
855 .put = alc_eapd_ctrl_put, \
856 .private_value = nid | (mask<<16) }
857#endif /* CONFIG_SND_DEBUG */
858
23f0c048
TI
859/*
860 * set up the input pin config (depending on the given auto-pin type)
861 */
862static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
863 int auto_pin_type)
864{
865 unsigned int val = PIN_IN;
866
86e2959a 867 if (auto_pin_type == AUTO_PIN_MIC) {
23f0c048 868 unsigned int pincap;
954a29c8
TI
869 unsigned int oldval;
870 oldval = snd_hda_codec_read(codec, nid, 0,
871 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1327a32b 872 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048 873 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
954a29c8
TI
874 /* if the default pin setup is vref50, we give it priority */
875 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
23f0c048 876 val = PIN_VREF80;
461c6c3a
TI
877 else if (pincap & AC_PINCAP_VREF_50)
878 val = PIN_VREF50;
879 else if (pincap & AC_PINCAP_VREF_100)
880 val = PIN_VREF100;
881 else if (pincap & AC_PINCAP_VREF_GRD)
882 val = PIN_VREFGRD;
23f0c048
TI
883 }
884 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
885}
886
f6837bbd
TI
887static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
888{
889 struct alc_spec *spec = codec->spec;
890 struct auto_pin_cfg *cfg = &spec->autocfg;
891
892 if (!cfg->line_outs) {
893 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
894 cfg->line_out_pins[cfg->line_outs])
895 cfg->line_outs++;
896 }
897 if (!cfg->speaker_outs) {
898 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
899 cfg->speaker_pins[cfg->speaker_outs])
900 cfg->speaker_outs++;
901 }
902 if (!cfg->hp_outs) {
903 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
904 cfg->hp_pins[cfg->hp_outs])
905 cfg->hp_outs++;
906 }
907}
908
d88897ea
TI
909/*
910 */
911static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
912{
913 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
914 return;
915 spec->mixers[spec->num_mixers++] = mix;
916}
917
918static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
919{
920 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
921 return;
922 spec->init_verbs[spec->num_init_verbs++] = verb;
923}
924
df694daa
KY
925/*
926 * set up from the preset table
927 */
e9c364c0 928static void setup_preset(struct hda_codec *codec,
9c7f852e 929 const struct alc_config_preset *preset)
df694daa 930{
e9c364c0 931 struct alc_spec *spec = codec->spec;
df694daa
KY
932 int i;
933
934 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 935 add_mixer(spec, preset->mixers[i]);
f9e336f6 936 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
937 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
938 i++)
d88897ea 939 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 940
df694daa
KY
941 spec->channel_mode = preset->channel_mode;
942 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 943 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 944 spec->const_channel_count = preset->const_channel_count;
df694daa 945
3b315d70
HM
946 if (preset->const_channel_count)
947 spec->multiout.max_channels = preset->const_channel_count;
948 else
949 spec->multiout.max_channels = spec->channel_mode[0].channels;
950 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
951
952 spec->multiout.num_dacs = preset->num_dacs;
953 spec->multiout.dac_nids = preset->dac_nids;
954 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 955 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 956 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 957
a1e8d2da 958 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 959 if (!spec->num_mux_defs)
a1e8d2da 960 spec->num_mux_defs = 1;
df694daa
KY
961 spec->input_mux = preset->input_mux;
962
963 spec->num_adc_nids = preset->num_adc_nids;
964 spec->adc_nids = preset->adc_nids;
e1406348 965 spec->capsrc_nids = preset->capsrc_nids;
df694daa 966 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
967
968 spec->unsol_event = preset->unsol_event;
969 spec->init_hook = preset->init_hook;
cb53c626 970#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 971 spec->power_hook = preset->power_hook;
cb53c626
TI
972 spec->loopback.amplist = preset->loopbacks;
973#endif
e9c364c0
TI
974
975 if (preset->setup)
976 preset->setup(codec);
f6837bbd
TI
977
978 alc_fixup_autocfg_pin_nums(codec);
df694daa
KY
979}
980
bc9f98a9
KY
981/* Enable GPIO mask and set output */
982static struct hda_verb alc_gpio1_init_verbs[] = {
983 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
984 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
985 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
986 { }
987};
988
989static struct hda_verb alc_gpio2_init_verbs[] = {
990 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
991 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
992 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
993 { }
994};
995
bdd148a3
KY
996static struct hda_verb alc_gpio3_init_verbs[] = {
997 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
998 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
999 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1000 { }
1001};
1002
2c3bf9ab
TI
1003/*
1004 * Fix hardware PLL issue
1005 * On some codecs, the analog PLL gating control must be off while
1006 * the default value is 1.
1007 */
1008static void alc_fix_pll(struct hda_codec *codec)
1009{
1010 struct alc_spec *spec = codec->spec;
1011 unsigned int val;
1012
1013 if (!spec->pll_nid)
1014 return;
1015 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1016 spec->pll_coef_idx);
1017 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1018 AC_VERB_GET_PROC_COEF, 0);
1019 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1020 spec->pll_coef_idx);
1021 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1022 val & ~(1 << spec->pll_coef_bit));
1023}
1024
1025static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1026 unsigned int coef_idx, unsigned int coef_bit)
1027{
1028 struct alc_spec *spec = codec->spec;
1029 spec->pll_nid = nid;
1030 spec->pll_coef_idx = coef_idx;
1031 spec->pll_coef_bit = coef_bit;
1032 alc_fix_pll(codec);
1033}
1034
9ad0e496
KY
1035#ifdef CONFIG_SND_HDA_INPUT_JACK
1036static void alc_free_jack_priv(struct snd_jack *jack)
1037{
1038 struct alc_jack *jacks = jack->private_data;
1039 jacks->nid = 0;
1040 jacks->jack = NULL;
1041}
1042
1043static int alc_add_jack(struct hda_codec *codec,
1044 hda_nid_t nid, int type)
1045{
1046 struct alc_spec *spec;
1047 struct alc_jack *jack;
1048 const char *name;
1049 int err;
1050
1051 spec = codec->spec;
1052 snd_array_init(&spec->jacks, sizeof(*jack), 32);
1053 jack = snd_array_new(&spec->jacks);
1054 if (!jack)
1055 return -ENOMEM;
1056
1057 jack->nid = nid;
1058 jack->type = type;
1059 name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
1060
1061 err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
1062 if (err < 0)
1063 return err;
1064 jack->jack->private_data = jack;
1065 jack->jack->private_free = alc_free_jack_priv;
1066 return 0;
1067}
1068
1069static void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1070{
1071 struct alc_spec *spec = codec->spec;
1072 struct alc_jack *jacks = spec->jacks.list;
1073
1074 if (jacks) {
1075 int i;
1076 for (i = 0; i < spec->jacks.used; i++) {
1077 if (jacks->nid == nid) {
1078 unsigned int present;
1079 present = snd_hda_jack_detect(codec, nid);
1080
1081 present = (present) ? jacks->type : 0;
1082
1083 snd_jack_report(jacks->jack, present);
1084 }
1085 jacks++;
1086 }
1087 }
1088}
1089
1090static int alc_init_jacks(struct hda_codec *codec)
1091{
1092 struct alc_spec *spec = codec->spec;
1093 int err;
1094 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1095 unsigned int mic_nid = spec->ext_mic.pin;
1096
265a0247
TI
1097 if (hp_nid) {
1098 err = alc_add_jack(codec, hp_nid, SND_JACK_HEADPHONE);
1099 if (err < 0)
1100 return err;
1101 alc_report_jack(codec, hp_nid);
1102 }
9ad0e496 1103
265a0247
TI
1104 if (mic_nid) {
1105 err = alc_add_jack(codec, mic_nid, SND_JACK_MICROPHONE);
1106 if (err < 0)
1107 return err;
1108 alc_report_jack(codec, mic_nid);
1109 }
9ad0e496
KY
1110
1111 return 0;
1112}
1113#else
1114static inline void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1115{
1116}
1117
1118static inline int alc_init_jacks(struct hda_codec *codec)
1119{
1120 return 0;
1121}
1122#endif
1123
bb35febd 1124static void alc_automute_speaker(struct hda_codec *codec, int pinctl)
c9b58006
KY
1125{
1126 struct alc_spec *spec = codec->spec;
bb35febd
TI
1127 unsigned int mute;
1128 hda_nid_t nid;
a9fd4f3f 1129 int i;
c9b58006 1130
bb35febd
TI
1131 spec->jack_present = 0;
1132 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1133 nid = spec->autocfg.hp_pins[i];
1134 if (!nid)
1135 break;
f0ce2799
DH
1136 alc_report_jack(codec, nid);
1137 spec->jack_present |= snd_hda_jack_detect(codec, nid);
bb35febd
TI
1138 }
1139
1140 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1141 /* Toggle internal speakers muting */
a9fd4f3f
TI
1142 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1143 nid = spec->autocfg.speaker_pins[i];
1144 if (!nid)
1145 break;
bb35febd
TI
1146 if (pinctl) {
1147 snd_hda_codec_write(codec, nid, 0,
a9fd4f3f
TI
1148 AC_VERB_SET_PIN_WIDGET_CONTROL,
1149 spec->jack_present ? 0 : PIN_OUT);
bb35febd
TI
1150 } else {
1151 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1152 HDA_AMP_MUTE, mute);
1153 }
a9fd4f3f 1154 }
c9b58006
KY
1155}
1156
bb35febd
TI
1157static void alc_automute_pin(struct hda_codec *codec)
1158{
1159 alc_automute_speaker(codec, 1);
1160}
1161
6c819492
TI
1162static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1163 hda_nid_t nid)
1164{
1165 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1166 int i, nums;
1167
1168 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1169 for (i = 0; i < nums; i++)
1170 if (conn[i] == nid)
1171 return i;
1172 return -1;
1173}
1174
840b64c0
TI
1175/* switch the current ADC according to the jack state */
1176static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1177{
1178 struct alc_spec *spec = codec->spec;
1179 unsigned int present;
1180 hda_nid_t new_adc;
1181
1182 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1183 if (present)
1184 spec->cur_adc_idx = 1;
1185 else
1186 spec->cur_adc_idx = 0;
1187 new_adc = spec->adc_nids[spec->cur_adc_idx];
1188 if (spec->cur_adc && spec->cur_adc != new_adc) {
1189 /* stream is running, let's swap the current ADC */
f0cea797 1190 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
840b64c0
TI
1191 spec->cur_adc = new_adc;
1192 snd_hda_codec_setup_stream(codec, new_adc,
1193 spec->cur_adc_stream_tag, 0,
1194 spec->cur_adc_format);
1195 }
1196}
1197
7fb0d78f
KY
1198static void alc_mic_automute(struct hda_codec *codec)
1199{
1200 struct alc_spec *spec = codec->spec;
6c819492
TI
1201 struct alc_mic_route *dead, *alive;
1202 unsigned int present, type;
1203 hda_nid_t cap_nid;
1204
b59bdf3b
TI
1205 if (!spec->auto_mic)
1206 return;
6c819492
TI
1207 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1208 return;
1209 if (snd_BUG_ON(!spec->adc_nids))
1210 return;
1211
840b64c0
TI
1212 if (spec->dual_adc_switch) {
1213 alc_dual_mic_adc_auto_switch(codec);
1214 return;
1215 }
1216
6c819492
TI
1217 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1218
864f92be 1219 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1220 if (present) {
1221 alive = &spec->ext_mic;
1222 dead = &spec->int_mic;
1223 } else {
1224 alive = &spec->int_mic;
1225 dead = &spec->ext_mic;
1226 }
1227
6c819492
TI
1228 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1229 if (type == AC_WID_AUD_MIX) {
1230 /* Matrix-mixer style (e.g. ALC882) */
1231 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1232 alive->mux_idx,
1233 HDA_AMP_MUTE, 0);
1234 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1235 dead->mux_idx,
1236 HDA_AMP_MUTE, HDA_AMP_MUTE);
1237 } else {
1238 /* MUX style (e.g. ALC880) */
1239 snd_hda_codec_write_cache(codec, cap_nid, 0,
1240 AC_VERB_SET_CONNECT_SEL,
1241 alive->mux_idx);
1242 }
9ad0e496 1243 alc_report_jack(codec, spec->ext_mic.pin);
6c819492
TI
1244
1245 /* FIXME: analog mixer */
7fb0d78f
KY
1246}
1247
c9b58006
KY
1248/* unsolicited event for HP jack sensing */
1249static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1250{
1251 if (codec->vendor_id == 0x10ec0880)
1252 res >>= 28;
1253 else
1254 res >>= 26;
a9fd4f3f
TI
1255 switch (res) {
1256 case ALC880_HP_EVENT:
1257 alc_automute_pin(codec);
1258 break;
1259 case ALC880_MIC_EVENT:
7fb0d78f 1260 alc_mic_automute(codec);
a9fd4f3f
TI
1261 break;
1262 }
7fb0d78f
KY
1263}
1264
1265static void alc_inithook(struct hda_codec *codec)
1266{
a9fd4f3f 1267 alc_automute_pin(codec);
7fb0d78f 1268 alc_mic_automute(codec);
c9b58006
KY
1269}
1270
f9423e7a
KY
1271/* additional initialization for ALC888 variants */
1272static void alc888_coef_init(struct hda_codec *codec)
1273{
1274 unsigned int tmp;
1275
1276 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1277 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1278 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1279 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1280 /* alc888S-VC */
1281 snd_hda_codec_read(codec, 0x20, 0,
1282 AC_VERB_SET_PROC_COEF, 0x830);
1283 else
1284 /* alc888-VB */
1285 snd_hda_codec_read(codec, 0x20, 0,
1286 AC_VERB_SET_PROC_COEF, 0x3030);
1287}
1288
87a8c370
JK
1289static void alc889_coef_init(struct hda_codec *codec)
1290{
1291 unsigned int tmp;
1292
1293 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1294 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1295 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1296 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1297}
1298
3fb4a508
TI
1299/* turn on/off EAPD control (only if available) */
1300static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1301{
1302 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1303 return;
1304 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1305 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1306 on ? 2 : 0);
1307}
1308
4a79ba34 1309static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1310{
4a79ba34 1311 unsigned int tmp;
bc9f98a9 1312
4a79ba34
TI
1313 switch (type) {
1314 case ALC_INIT_GPIO1:
bc9f98a9
KY
1315 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1316 break;
4a79ba34 1317 case ALC_INIT_GPIO2:
bc9f98a9
KY
1318 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1319 break;
4a79ba34 1320 case ALC_INIT_GPIO3:
bdd148a3
KY
1321 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1322 break;
4a79ba34 1323 case ALC_INIT_DEFAULT:
bdd148a3 1324 switch (codec->vendor_id) {
c9b58006 1325 case 0x10ec0260:
3fb4a508
TI
1326 set_eapd(codec, 0x0f, 1);
1327 set_eapd(codec, 0x10, 1);
c9b58006
KY
1328 break;
1329 case 0x10ec0262:
bdd148a3
KY
1330 case 0x10ec0267:
1331 case 0x10ec0268:
c9b58006 1332 case 0x10ec0269:
3fb4a508 1333 case 0x10ec0270:
c6e8f2da 1334 case 0x10ec0272:
f9423e7a
KY
1335 case 0x10ec0660:
1336 case 0x10ec0662:
1337 case 0x10ec0663:
c9b58006 1338 case 0x10ec0862:
20a3a05d 1339 case 0x10ec0889:
3fb4a508
TI
1340 set_eapd(codec, 0x14, 1);
1341 set_eapd(codec, 0x15, 1);
c9b58006 1342 break;
bdd148a3 1343 }
c9b58006
KY
1344 switch (codec->vendor_id) {
1345 case 0x10ec0260:
1346 snd_hda_codec_write(codec, 0x1a, 0,
1347 AC_VERB_SET_COEF_INDEX, 7);
1348 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1349 AC_VERB_GET_PROC_COEF, 0);
1350 snd_hda_codec_write(codec, 0x1a, 0,
1351 AC_VERB_SET_COEF_INDEX, 7);
1352 snd_hda_codec_write(codec, 0x1a, 0,
1353 AC_VERB_SET_PROC_COEF,
1354 tmp | 0x2010);
1355 break;
1356 case 0x10ec0262:
1357 case 0x10ec0880:
1358 case 0x10ec0882:
1359 case 0x10ec0883:
1360 case 0x10ec0885:
4a5a4c56 1361 case 0x10ec0887:
20a3a05d 1362 case 0x10ec0889:
87a8c370 1363 alc889_coef_init(codec);
c9b58006 1364 break;
f9423e7a 1365 case 0x10ec0888:
4a79ba34 1366 alc888_coef_init(codec);
f9423e7a 1367 break;
0aea778e 1368#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1369 case 0x10ec0267:
1370 case 0x10ec0268:
1371 snd_hda_codec_write(codec, 0x20, 0,
1372 AC_VERB_SET_COEF_INDEX, 7);
1373 tmp = snd_hda_codec_read(codec, 0x20, 0,
1374 AC_VERB_GET_PROC_COEF, 0);
1375 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1376 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1377 snd_hda_codec_write(codec, 0x20, 0,
1378 AC_VERB_SET_PROC_COEF,
1379 tmp | 0x3000);
1380 break;
0aea778e 1381#endif /* XXX */
bc9f98a9 1382 }
4a79ba34
TI
1383 break;
1384 }
1385}
1386
1387static void alc_init_auto_hp(struct hda_codec *codec)
1388{
1389 struct alc_spec *spec = codec->spec;
bb35febd
TI
1390 struct auto_pin_cfg *cfg = &spec->autocfg;
1391 int i;
4a79ba34 1392
bb35febd
TI
1393 if (!cfg->hp_pins[0]) {
1394 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
1395 return;
1396 }
4a79ba34 1397
bb35febd
TI
1398 if (!cfg->speaker_pins[0]) {
1399 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
4a79ba34 1400 return;
bb35febd
TI
1401 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1402 sizeof(cfg->speaker_pins));
1403 cfg->speaker_outs = cfg->line_outs;
1404 }
1405
1406 if (!cfg->hp_pins[0]) {
1407 memcpy(cfg->hp_pins, cfg->line_out_pins,
1408 sizeof(cfg->hp_pins));
1409 cfg->hp_outs = cfg->line_outs;
4a79ba34
TI
1410 }
1411
bb35febd
TI
1412 for (i = 0; i < cfg->hp_outs; i++) {
1413 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1414 cfg->hp_pins[i]);
1415 snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0,
4a79ba34
TI
1416 AC_VERB_SET_UNSOLICITED_ENABLE,
1417 AC_USRSP_EN | ALC880_HP_EVENT);
bb35febd 1418 }
4a79ba34
TI
1419 spec->unsol_event = alc_sku_unsol_event;
1420}
1421
6c819492
TI
1422static void alc_init_auto_mic(struct hda_codec *codec)
1423{
1424 struct alc_spec *spec = codec->spec;
1425 struct auto_pin_cfg *cfg = &spec->autocfg;
1426 hda_nid_t fixed, ext;
1427 int i;
1428
1429 /* there must be only two mic inputs exclusively */
66ceeb6b 1430 for (i = 0; i < cfg->num_inputs; i++)
86e2959a 1431 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN)
6c819492
TI
1432 return;
1433
1434 fixed = ext = 0;
66ceeb6b
TI
1435 for (i = 0; i < cfg->num_inputs; i++) {
1436 hda_nid_t nid = cfg->inputs[i].pin;
6c819492 1437 unsigned int defcfg;
6c819492 1438 defcfg = snd_hda_codec_get_pincfg(codec, nid);
99ae28be
TI
1439 switch (snd_hda_get_input_pin_attr(defcfg)) {
1440 case INPUT_PIN_ATTR_INT:
6c819492
TI
1441 if (fixed)
1442 return; /* already occupied */
1443 fixed = nid;
1444 break;
99ae28be
TI
1445 case INPUT_PIN_ATTR_UNUSED:
1446 return; /* invalid entry */
1447 default:
6c819492
TI
1448 if (ext)
1449 return; /* already occupied */
1450 ext = nid;
1451 break;
6c819492
TI
1452 }
1453 }
eaa9b3a7
TI
1454 if (!ext || !fixed)
1455 return;
6c819492
TI
1456 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1457 return; /* no unsol support */
1458 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1459 ext, fixed);
1460 spec->ext_mic.pin = ext;
1461 spec->int_mic.pin = fixed;
1462 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1463 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1464 spec->auto_mic = 1;
1465 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1466 AC_VERB_SET_UNSOLICITED_ENABLE,
1467 AC_USRSP_EN | ALC880_MIC_EVENT);
1468 spec->unsol_event = alc_sku_unsol_event;
1469}
1470
90622917
DH
1471/* Could be any non-zero and even value. When used as fixup, tells
1472 * the driver to ignore any present sku defines.
1473 */
1474#define ALC_FIXUP_SKU_IGNORE (2)
1475
da00c244
KY
1476static int alc_auto_parse_customize_define(struct hda_codec *codec)
1477{
1478 unsigned int ass, tmp, i;
7fb56223 1479 unsigned nid = 0;
da00c244
KY
1480 struct alc_spec *spec = codec->spec;
1481
b6cbe517
TI
1482 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1483
90622917
DH
1484 if (spec->cdefine.fixup) {
1485 ass = spec->cdefine.sku_cfg;
1486 if (ass == ALC_FIXUP_SKU_IGNORE)
1487 return -1;
1488 goto do_sku;
1489 }
1490
da00c244 1491 ass = codec->subsystem_id & 0xffff;
b6cbe517 1492 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1493 goto do_sku;
1494
1495 nid = 0x1d;
1496 if (codec->vendor_id == 0x10ec0260)
1497 nid = 0x17;
1498 ass = snd_hda_codec_get_pincfg(codec, nid);
1499
1500 if (!(ass & 1)) {
1501 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1502 codec->chip_name, ass);
1503 return -1;
1504 }
1505
1506 /* check sum */
1507 tmp = 0;
1508 for (i = 1; i < 16; i++) {
1509 if ((ass >> i) & 1)
1510 tmp++;
1511 }
1512 if (((ass >> 16) & 0xf) != tmp)
1513 return -1;
1514
1515 spec->cdefine.port_connectivity = ass >> 30;
1516 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1517 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1518 spec->cdefine.customization = ass >> 8;
1519do_sku:
1520 spec->cdefine.sku_cfg = ass;
1521 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1522 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1523 spec->cdefine.swap = (ass & 0x2) >> 1;
1524 spec->cdefine.override = ass & 0x1;
1525
1526 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1527 nid, spec->cdefine.sku_cfg);
1528 snd_printd("SKU: port_connectivity=0x%x\n",
1529 spec->cdefine.port_connectivity);
1530 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1531 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1532 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1533 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1534 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1535 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1536 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1537
1538 return 0;
1539}
1540
4a79ba34
TI
1541/* check subsystem ID and set up device-specific initialization;
1542 * return 1 if initialized, 0 if invalid SSID
1543 */
1544/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1545 * 31 ~ 16 : Manufacture ID
1546 * 15 ~ 8 : SKU ID
1547 * 7 ~ 0 : Assembly ID
1548 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1549 */
1550static int alc_subsystem_id(struct hda_codec *codec,
1551 hda_nid_t porta, hda_nid_t porte,
6227cdce 1552 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1553{
1554 unsigned int ass, tmp, i;
1555 unsigned nid;
1556 struct alc_spec *spec = codec->spec;
1557
90622917
DH
1558 if (spec->cdefine.fixup) {
1559 ass = spec->cdefine.sku_cfg;
1560 if (ass == ALC_FIXUP_SKU_IGNORE)
1561 return 0;
1562 goto do_sku;
1563 }
1564
4a79ba34
TI
1565 ass = codec->subsystem_id & 0xffff;
1566 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1567 goto do_sku;
1568
1569 /* invalid SSID, check the special NID pin defcfg instead */
1570 /*
def319f9 1571 * 31~30 : port connectivity
4a79ba34
TI
1572 * 29~21 : reserve
1573 * 20 : PCBEEP input
1574 * 19~16 : Check sum (15:1)
1575 * 15~1 : Custom
1576 * 0 : override
1577 */
1578 nid = 0x1d;
1579 if (codec->vendor_id == 0x10ec0260)
1580 nid = 0x17;
1581 ass = snd_hda_codec_get_pincfg(codec, nid);
1582 snd_printd("realtek: No valid SSID, "
1583 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1584 ass, nid);
6227cdce 1585 if (!(ass & 1))
4a79ba34
TI
1586 return 0;
1587 if ((ass >> 30) != 1) /* no physical connection */
1588 return 0;
1589
1590 /* check sum */
1591 tmp = 0;
1592 for (i = 1; i < 16; i++) {
1593 if ((ass >> i) & 1)
1594 tmp++;
1595 }
1596 if (((ass >> 16) & 0xf) != tmp)
1597 return 0;
1598do_sku:
1599 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1600 ass & 0xffff, codec->vendor_id);
1601 /*
1602 * 0 : override
1603 * 1 : Swap Jack
1604 * 2 : 0 --> Desktop, 1 --> Laptop
1605 * 3~5 : External Amplifier control
1606 * 7~6 : Reserved
1607 */
1608 tmp = (ass & 0x38) >> 3; /* external Amp control */
1609 switch (tmp) {
1610 case 1:
1611 spec->init_amp = ALC_INIT_GPIO1;
1612 break;
1613 case 3:
1614 spec->init_amp = ALC_INIT_GPIO2;
1615 break;
1616 case 7:
1617 spec->init_amp = ALC_INIT_GPIO3;
1618 break;
1619 case 5:
5a8cfb4e 1620 default:
4a79ba34 1621 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1622 break;
1623 }
ea1fb29a 1624
8c427226 1625 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1626 * when the external headphone out jack is plugged"
1627 */
8c427226 1628 if (!(ass & 0x8000))
4a79ba34 1629 return 1;
c9b58006
KY
1630 /*
1631 * 10~8 : Jack location
1632 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1633 * 14~13: Resvered
1634 * 15 : 1 --> enable the function "Mute internal speaker
1635 * when the external headphone out jack is plugged"
1636 */
c9b58006 1637 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1638 hda_nid_t nid;
c9b58006
KY
1639 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1640 if (tmp == 0)
01d4825d 1641 nid = porta;
c9b58006 1642 else if (tmp == 1)
01d4825d 1643 nid = porte;
c9b58006 1644 else if (tmp == 2)
01d4825d 1645 nid = portd;
6227cdce
KY
1646 else if (tmp == 3)
1647 nid = porti;
c9b58006 1648 else
4a79ba34 1649 return 1;
01d4825d
TI
1650 for (i = 0; i < spec->autocfg.line_outs; i++)
1651 if (spec->autocfg.line_out_pins[i] == nid)
1652 return 1;
1653 spec->autocfg.hp_pins[0] = nid;
c9b58006
KY
1654 }
1655
4a79ba34 1656 alc_init_auto_hp(codec);
6c819492 1657 alc_init_auto_mic(codec);
4a79ba34
TI
1658 return 1;
1659}
ea1fb29a 1660
4a79ba34 1661static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1662 hda_nid_t porta, hda_nid_t porte,
1663 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1664{
6227cdce 1665 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1666 struct alc_spec *spec = codec->spec;
1667 snd_printd("realtek: "
1668 "Enable default setup for auto mode as fallback\n");
1669 spec->init_amp = ALC_INIT_DEFAULT;
1670 alc_init_auto_hp(codec);
6c819492 1671 alc_init_auto_mic(codec);
4a79ba34 1672 }
bc9f98a9
KY
1673}
1674
f95474ec 1675/*
f8f25ba3 1676 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1677 */
1678
1679struct alc_pincfg {
1680 hda_nid_t nid;
1681 u32 val;
1682};
1683
e1eb5f10
TB
1684struct alc_model_fixup {
1685 const int id;
1686 const char *name;
1687};
1688
f8f25ba3 1689struct alc_fixup {
b5bfbc67 1690 int type;
361fe6e9
TI
1691 bool chained;
1692 int chain_id;
b5bfbc67
TI
1693 union {
1694 unsigned int sku;
1695 const struct alc_pincfg *pins;
1696 const struct hda_verb *verbs;
1697 void (*func)(struct hda_codec *codec,
1698 const struct alc_fixup *fix,
1699 int action);
1700 } v;
f8f25ba3
TI
1701};
1702
b5bfbc67
TI
1703enum {
1704 ALC_FIXUP_INVALID,
1705 ALC_FIXUP_SKU,
1706 ALC_FIXUP_PINS,
1707 ALC_FIXUP_VERBS,
1708 ALC_FIXUP_FUNC,
1709};
1710
1711enum {
1712 ALC_FIXUP_ACT_PRE_PROBE,
1713 ALC_FIXUP_ACT_PROBE,
58701120 1714 ALC_FIXUP_ACT_INIT,
b5bfbc67
TI
1715};
1716
1717static void alc_apply_fixup(struct hda_codec *codec, int action)
f95474ec 1718{
b5bfbc67
TI
1719 struct alc_spec *spec = codec->spec;
1720 int id = spec->fixup_id;
aa1d0c52 1721#ifdef CONFIG_SND_DEBUG_VERBOSE
b5bfbc67 1722 const char *modelname = spec->fixup_name;
aa1d0c52 1723#endif
b5bfbc67 1724 int depth = 0;
f95474ec 1725
b5bfbc67
TI
1726 if (!spec->fixup_list)
1727 return;
1728
1729 while (id >= 0) {
1730 const struct alc_fixup *fix = spec->fixup_list + id;
1731 const struct alc_pincfg *cfg;
1732
1733 switch (fix->type) {
1734 case ALC_FIXUP_SKU:
1735 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1736 break;;
1737 snd_printdd(KERN_INFO "hda_codec: %s: "
1738 "Apply sku override for %s\n",
1739 codec->chip_name, modelname);
1740 spec->cdefine.sku_cfg = fix->v.sku;
1741 spec->cdefine.fixup = 1;
1742 break;
1743 case ALC_FIXUP_PINS:
1744 cfg = fix->v.pins;
1745 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1746 break;
1747 snd_printdd(KERN_INFO "hda_codec: %s: "
1748 "Apply pincfg for %s\n",
1749 codec->chip_name, modelname);
1750 for (; cfg->nid; cfg++)
1751 snd_hda_codec_set_pincfg(codec, cfg->nid,
1752 cfg->val);
1753 break;
1754 case ALC_FIXUP_VERBS:
1755 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1756 break;
1757 snd_printdd(KERN_INFO "hda_codec: %s: "
1758 "Apply fix-verbs for %s\n",
1759 codec->chip_name, modelname);
1760 add_verb(codec->spec, fix->v.verbs);
1761 break;
1762 case ALC_FIXUP_FUNC:
1763 if (!fix->v.func)
1764 break;
1765 snd_printdd(KERN_INFO "hda_codec: %s: "
1766 "Apply fix-func for %s\n",
1767 codec->chip_name, modelname);
1768 fix->v.func(codec, fix, action);
1769 break;
1770 default:
1771 snd_printk(KERN_ERR "hda_codec: %s: "
1772 "Invalid fixup type %d\n",
1773 codec->chip_name, fix->type);
1774 break;
1775 }
1776 if (!fix[id].chained)
1777 break;
1778 if (++depth > 10)
1779 break;
1780 id = fix[id].chain_id;
9d57883f 1781 }
f95474ec
TI
1782}
1783
e1eb5f10 1784static void alc_pick_fixup(struct hda_codec *codec,
b5bfbc67
TI
1785 const struct alc_model_fixup *models,
1786 const struct snd_pci_quirk *quirk,
1787 const struct alc_fixup *fixlist)
e1eb5f10 1788{
b5bfbc67
TI
1789 struct alc_spec *spec = codec->spec;
1790 int id = -1;
1791 const char *name = NULL;
e1eb5f10 1792
e1eb5f10
TB
1793 if (codec->modelname && models) {
1794 while (models->name) {
1795 if (!strcmp(codec->modelname, models->name)) {
b5bfbc67
TI
1796 id = models->id;
1797 name = models->name;
e1eb5f10
TB
1798 break;
1799 }
1800 models++;
1801 }
b5bfbc67
TI
1802 }
1803 if (id < 0) {
1804 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1805 if (quirk) {
1806 id = quirk->value;
1807#ifdef CONFIG_SND_DEBUG_VERBOSE
1808 name = quirk->name;
1809#endif
1810 }
1811 }
1812
1813 spec->fixup_id = id;
1814 if (id >= 0) {
1815 spec->fixup_list = fixlist;
1816 spec->fixup_name = name;
e1eb5f10 1817 }
f95474ec
TI
1818}
1819
274693f3
KY
1820static int alc_read_coef_idx(struct hda_codec *codec,
1821 unsigned int coef_idx)
1822{
1823 unsigned int val;
1824 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1825 coef_idx);
1826 val = snd_hda_codec_read(codec, 0x20, 0,
1827 AC_VERB_GET_PROC_COEF, 0);
1828 return val;
1829}
1830
977ddd6b
KY
1831static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
1832 unsigned int coef_val)
1833{
1834 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1835 coef_idx);
1836 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
1837 coef_val);
1838}
1839
757899ac
TI
1840/* set right pin controls for digital I/O */
1841static void alc_auto_init_digital(struct hda_codec *codec)
1842{
1843 struct alc_spec *spec = codec->spec;
1844 int i;
1845 hda_nid_t pin;
1846
1847 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1848 pin = spec->autocfg.dig_out_pins[i];
1849 if (pin) {
1850 snd_hda_codec_write(codec, pin, 0,
1851 AC_VERB_SET_PIN_WIDGET_CONTROL,
1852 PIN_OUT);
1853 }
1854 }
1855 pin = spec->autocfg.dig_in_pin;
1856 if (pin)
1857 snd_hda_codec_write(codec, pin, 0,
1858 AC_VERB_SET_PIN_WIDGET_CONTROL,
1859 PIN_IN);
1860}
1861
1862/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1863static void alc_auto_parse_digital(struct hda_codec *codec)
1864{
1865 struct alc_spec *spec = codec->spec;
1866 int i, err;
1867 hda_nid_t dig_nid;
1868
1869 /* support multiple SPDIFs; the secondary is set up as a slave */
1870 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1871 err = snd_hda_get_connections(codec,
1872 spec->autocfg.dig_out_pins[i],
1873 &dig_nid, 1);
1874 if (err < 0)
1875 continue;
1876 if (!i) {
1877 spec->multiout.dig_out_nid = dig_nid;
1878 spec->dig_out_type = spec->autocfg.dig_out_type[0];
1879 } else {
1880 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1881 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1882 break;
1883 spec->slave_dig_outs[i - 1] = dig_nid;
1884 }
1885 }
1886
1887 if (spec->autocfg.dig_in_pin) {
01fdf180
TI
1888 dig_nid = codec->start_nid;
1889 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
1890 unsigned int wcaps = get_wcaps(codec, dig_nid);
1891 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
1892 continue;
1893 if (!(wcaps & AC_WCAP_DIGITAL))
1894 continue;
1895 if (!(wcaps & AC_WCAP_CONN_LIST))
1896 continue;
1897 err = get_connection_index(codec, dig_nid,
1898 spec->autocfg.dig_in_pin);
1899 if (err >= 0) {
1900 spec->dig_in_nid = dig_nid;
1901 break;
1902 }
1903 }
757899ac
TI
1904 }
1905}
1906
ef8ef5fb
VP
1907/*
1908 * ALC888
1909 */
1910
1911/*
1912 * 2ch mode
1913 */
1914static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1915/* Mic-in jack as mic in */
1916 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1917 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1918/* Line-in jack as Line in */
1919 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1920 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1921/* Line-Out as Front */
1922 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1923 { } /* end */
1924};
1925
1926/*
1927 * 4ch mode
1928 */
1929static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1930/* Mic-in jack as mic in */
1931 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1932 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1933/* Line-in jack as Surround */
1934 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1935 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1936/* Line-Out as Front */
1937 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1938 { } /* end */
1939};
1940
1941/*
1942 * 6ch mode
1943 */
1944static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1945/* Mic-in jack as CLFE */
1946 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1947 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1948/* Line-in jack as Surround */
1949 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1950 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1951/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1952 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1953 { } /* end */
1954};
1955
1956/*
1957 * 8ch mode
1958 */
1959static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1960/* Mic-in jack as CLFE */
1961 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1962 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1963/* Line-in jack as Surround */
1964 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1965 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1966/* Line-Out as Side */
1967 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1968 { } /* end */
1969};
1970
1971static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1972 { 2, alc888_4ST_ch2_intel_init },
1973 { 4, alc888_4ST_ch4_intel_init },
1974 { 6, alc888_4ST_ch6_intel_init },
1975 { 8, alc888_4ST_ch8_intel_init },
1976};
1977
1978/*
1979 * ALC888 Fujitsu Siemens Amillo xa3530
1980 */
1981
1982static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1983/* Front Mic: set to PIN_IN (empty by default) */
1984 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1985/* Connect Internal HP to Front */
1986 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1987 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1988 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1989/* Connect Bass HP to Front */
1990 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1991 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1992 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1993/* Connect Line-Out side jack (SPDIF) to Side */
1994 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1995 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1996 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1997/* Connect Mic jack to CLFE */
1998 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1999 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2000 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2001/* Connect Line-in jack to Surround */
2002 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2003 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2004 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2005/* Connect HP out jack to Front */
2006 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2007 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2008 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2009/* Enable unsolicited event for HP jack and Line-out jack */
2010 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2011 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2012 {}
2013};
2014
a9fd4f3f 2015static void alc_automute_amp(struct hda_codec *codec)
ef8ef5fb 2016{
bb35febd 2017 alc_automute_speaker(codec, 0);
ef8ef5fb
VP
2018}
2019
a9fd4f3f
TI
2020static void alc_automute_amp_unsol_event(struct hda_codec *codec,
2021 unsigned int res)
ef8ef5fb 2022{
a9fd4f3f
TI
2023 if (codec->vendor_id == 0x10ec0880)
2024 res >>= 28;
2025 else
2026 res >>= 26;
2027 if (res == ALC880_HP_EVENT)
2028 alc_automute_amp(codec);
ef8ef5fb
VP
2029}
2030
4f5d1706 2031static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
2032{
2033 struct alc_spec *spec = codec->spec;
2034
2035 spec->autocfg.hp_pins[0] = 0x15;
2036 spec->autocfg.speaker_pins[0] = 0x14;
2037 spec->autocfg.speaker_pins[1] = 0x16;
2038 spec->autocfg.speaker_pins[2] = 0x17;
2039 spec->autocfg.speaker_pins[3] = 0x19;
2040 spec->autocfg.speaker_pins[4] = 0x1a;
6732bd0d
WF
2041}
2042
2043static void alc889_intel_init_hook(struct hda_codec *codec)
2044{
2045 alc889_coef_init(codec);
4f5d1706 2046 alc_automute_amp(codec);
6732bd0d
WF
2047}
2048
4f5d1706 2049static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
2050{
2051 struct alc_spec *spec = codec->spec;
2052
2053 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2054 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2055 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2056 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
a9fd4f3f 2057}
ef8ef5fb 2058
5b2d1eca
VP
2059/*
2060 * ALC888 Acer Aspire 4930G model
2061 */
2062
2063static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2064/* Front Mic: set to PIN_IN (empty by default) */
2065 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2066/* Unselect Front Mic by default in input mixer 3 */
2067 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 2068/* Enable unsolicited event for HP jack */
5b2d1eca
VP
2069 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2070/* Connect Internal HP to front */
2071 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2072 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2073 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2074/* Connect HP out to front */
2075 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2076 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2077 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
e2e93296 2078 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
5b2d1eca
VP
2079 { }
2080};
2081
d2fd4b09
TV
2082/*
2083 * ALC888 Acer Aspire 6530G model
2084 */
2085
2086static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
2087/* Route to built-in subwoofer as well as speakers */
2088 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2089 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2090 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2091 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
2092/* Bias voltage on for external mic port */
2093 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
2094/* Front Mic: set to PIN_IN (empty by default) */
2095 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2096/* Unselect Front Mic by default in input mixer 3 */
2097 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
2098/* Enable unsolicited event for HP jack */
2099 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2100/* Enable speaker output */
2101 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2102 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 2103 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2104/* Enable headphone output */
2105 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2106 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2107 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 2108 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2109 { }
2110};
2111
d9477207
DK
2112/*
2113 *ALC888 Acer Aspire 7730G model
2114 */
2115
2116static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2117/* Bias voltage on for external mic port */
2118 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2119/* Front Mic: set to PIN_IN (empty by default) */
2120 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2121/* Unselect Front Mic by default in input mixer 3 */
2122 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2123/* Enable unsolicited event for HP jack */
2124 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2125/* Enable speaker output */
2126 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2127 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2128 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2129/* Enable headphone output */
2130 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2131 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2132 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2133 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2134/*Enable internal subwoofer */
2135 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2136 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2137 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2138 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2139 { }
2140};
2141
3b315d70 2142/*
018df418 2143 * ALC889 Acer Aspire 8930G model
3b315d70
HM
2144 */
2145
018df418 2146static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
2147/* Front Mic: set to PIN_IN (empty by default) */
2148 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2149/* Unselect Front Mic by default in input mixer 3 */
2150 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2151/* Enable unsolicited event for HP jack */
2152 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2153/* Connect Internal Front to Front */
2154 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2155 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2156 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2157/* Connect Internal Rear to Rear */
2158 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2159 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2160 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2161/* Connect Internal CLFE to CLFE */
2162 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2163 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2164 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2165/* Connect HP out to Front */
018df418 2166 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
2167 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2168 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2169/* Enable all DACs */
2170/* DAC DISABLE/MUTE 1? */
2171/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2172 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2173 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2174/* DAC DISABLE/MUTE 2? */
2175/* some bit here disables the other DACs. Init=0x4900 */
2176 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2177 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
2178/* DMIC fix
2179 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2180 * which makes the stereo useless. However, either the mic or the ALC889
2181 * makes the signal become a difference/sum signal instead of standard
2182 * stereo, which is annoying. So instead we flip this bit which makes the
2183 * codec replicate the sum signal to both channels, turning it into a
2184 * normal mono mic.
2185 */
2186/* DMIC_CONTROL? Init value = 0x0001 */
2187 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2188 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
2189 { }
2190};
2191
ef8ef5fb 2192static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
2193 /* Front mic only available on one ADC */
2194 {
2195 .num_items = 4,
2196 .items = {
2197 { "Mic", 0x0 },
2198 { "Line", 0x2 },
2199 { "CD", 0x4 },
2200 { "Front Mic", 0xb },
2201 },
2202 },
2203 {
2204 .num_items = 3,
2205 .items = {
2206 { "Mic", 0x0 },
2207 { "Line", 0x2 },
2208 { "CD", 0x4 },
2209 },
2210 }
2211};
2212
d2fd4b09
TV
2213static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2214 /* Interal mic only available on one ADC */
2215 {
684a8842 2216 .num_items = 5,
d2fd4b09 2217 .items = {
8607f7c4 2218 { "Mic", 0x0 },
684a8842 2219 { "Line In", 0x2 },
d2fd4b09 2220 { "CD", 0x4 },
684a8842 2221 { "Input Mix", 0xa },
28c4edb7 2222 { "Internal Mic", 0xb },
d2fd4b09
TV
2223 },
2224 },
2225 {
684a8842 2226 .num_items = 4,
d2fd4b09 2227 .items = {
8607f7c4 2228 { "Mic", 0x0 },
684a8842 2229 { "Line In", 0x2 },
d2fd4b09 2230 { "CD", 0x4 },
684a8842 2231 { "Input Mix", 0xa },
d2fd4b09
TV
2232 },
2233 }
2234};
2235
018df418
HM
2236static struct hda_input_mux alc889_capture_sources[3] = {
2237 /* Digital mic only available on first "ADC" */
2238 {
2239 .num_items = 5,
2240 .items = {
2241 { "Mic", 0x0 },
2242 { "Line", 0x2 },
2243 { "CD", 0x4 },
2244 { "Front Mic", 0xb },
2245 { "Input Mix", 0xa },
2246 },
2247 },
2248 {
2249 .num_items = 4,
2250 .items = {
2251 { "Mic", 0x0 },
2252 { "Line", 0x2 },
2253 { "CD", 0x4 },
2254 { "Input Mix", 0xa },
2255 },
2256 },
2257 {
2258 .num_items = 4,
2259 .items = {
2260 { "Mic", 0x0 },
2261 { "Line", 0x2 },
2262 { "CD", 0x4 },
2263 { "Input Mix", 0xa },
2264 },
2265 }
2266};
2267
ef8ef5fb 2268static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
2269 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2270 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2271 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2272 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2273 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2274 HDA_OUTPUT),
2275 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2276 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2277 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2278 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2279 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2280 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2281 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2282 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2283 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2284 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2285 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
5b2d1eca 2286 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
2287 { } /* end */
2288};
2289
460c92fa
ŁW
2290static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2291 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2292 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2293 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2294 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2295 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0f, 2, 0x0,
2296 HDA_OUTPUT),
2297 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0f, 2, 2, HDA_INPUT),
2298 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2299 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
2300 HDA_CODEC_VOLUME("Side Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2301 HDA_BIND_MUTE("Side Playback Switch", 0x0e, 2, HDA_INPUT),
2302 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2303 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2304 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2305 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2306 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2307 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2308 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2309 { } /* end */
2310};
2311
2312
556eea9a
HM
2313static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2314 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2315 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2316 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2317 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2318 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2319 HDA_OUTPUT),
2320 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2321 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2322 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2323 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2324 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2325 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2326 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
556eea9a
HM
2327 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2328 { } /* end */
2329};
2330
2331
4f5d1706 2332static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2333{
a9fd4f3f 2334 struct alc_spec *spec = codec->spec;
5b2d1eca 2335
a9fd4f3f
TI
2336 spec->autocfg.hp_pins[0] = 0x15;
2337 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2338 spec->autocfg.speaker_pins[1] = 0x16;
2339 spec->autocfg.speaker_pins[2] = 0x17;
5b2d1eca
VP
2340}
2341
4f5d1706 2342static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2343{
2344 struct alc_spec *spec = codec->spec;
2345
2346 spec->autocfg.hp_pins[0] = 0x15;
2347 spec->autocfg.speaker_pins[0] = 0x14;
2348 spec->autocfg.speaker_pins[1] = 0x16;
2349 spec->autocfg.speaker_pins[2] = 0x17;
320d5920
EL
2350}
2351
d9477207
DK
2352static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2353{
2354 struct alc_spec *spec = codec->spec;
2355
2356 spec->autocfg.hp_pins[0] = 0x15;
2357 spec->autocfg.speaker_pins[0] = 0x14;
2358 spec->autocfg.speaker_pins[1] = 0x16;
2359 spec->autocfg.speaker_pins[2] = 0x17;
2360}
2361
4f5d1706 2362static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2363{
2364 struct alc_spec *spec = codec->spec;
2365
2366 spec->autocfg.hp_pins[0] = 0x15;
2367 spec->autocfg.speaker_pins[0] = 0x14;
2368 spec->autocfg.speaker_pins[1] = 0x16;
2369 spec->autocfg.speaker_pins[2] = 0x1b;
3b315d70
HM
2370}
2371
1da177e4 2372/*
e9edcee0
TI
2373 * ALC880 3-stack model
2374 *
2375 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2376 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2377 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2378 */
2379
e9edcee0
TI
2380static hda_nid_t alc880_dac_nids[4] = {
2381 /* front, rear, clfe, rear_surr */
2382 0x02, 0x05, 0x04, 0x03
2383};
2384
2385static hda_nid_t alc880_adc_nids[3] = {
2386 /* ADC0-2 */
2387 0x07, 0x08, 0x09,
2388};
2389
2390/* The datasheet says the node 0x07 is connected from inputs,
2391 * but it shows zero connection in the real implementation on some devices.
df694daa 2392 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2393 */
e9edcee0
TI
2394static hda_nid_t alc880_adc_nids_alt[2] = {
2395 /* ADC1-2 */
2396 0x08, 0x09,
2397};
2398
2399#define ALC880_DIGOUT_NID 0x06
2400#define ALC880_DIGIN_NID 0x0a
2401
2402static struct hda_input_mux alc880_capture_source = {
2403 .num_items = 4,
2404 .items = {
2405 { "Mic", 0x0 },
2406 { "Front Mic", 0x3 },
2407 { "Line", 0x2 },
2408 { "CD", 0x4 },
2409 },
2410};
2411
2412/* channel source setting (2/6 channel selection for 3-stack) */
2413/* 2ch mode */
2414static struct hda_verb alc880_threestack_ch2_init[] = {
2415 /* set line-in to input, mute it */
2416 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2417 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2418 /* set mic-in to input vref 80%, mute it */
2419 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2420 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2421 { } /* end */
2422};
2423
2424/* 6ch mode */
2425static struct hda_verb alc880_threestack_ch6_init[] = {
2426 /* set line-in to output, unmute it */
2427 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2428 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2429 /* set mic-in to output, unmute it */
2430 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2431 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2432 { } /* end */
2433};
2434
d2a6d7dc 2435static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2436 { 2, alc880_threestack_ch2_init },
2437 { 6, alc880_threestack_ch6_init },
2438};
2439
c8b6bf9b 2440static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2441 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2442 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2443 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2444 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2445 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2446 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2447 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2448 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2449 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2450 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2451 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2452 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2453 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2454 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2455 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2456 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2457 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2458 {
2459 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2460 .name = "Channel Mode",
df694daa
KY
2461 .info = alc_ch_mode_info,
2462 .get = alc_ch_mode_get,
2463 .put = alc_ch_mode_put,
e9edcee0
TI
2464 },
2465 { } /* end */
2466};
2467
2468/* capture mixer elements */
f9e336f6
TI
2469static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2470 struct snd_ctl_elem_info *uinfo)
2471{
2472 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2473 struct alc_spec *spec = codec->spec;
2474 int err;
1da177e4 2475
5a9e02e9 2476 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2477 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2478 HDA_INPUT);
2479 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2480 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2481 return err;
2482}
2483
2484static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2485 unsigned int size, unsigned int __user *tlv)
2486{
2487 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2488 struct alc_spec *spec = codec->spec;
2489 int err;
1da177e4 2490
5a9e02e9 2491 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2492 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2493 HDA_INPUT);
2494 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2495 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2496 return err;
2497}
2498
2499typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2500 struct snd_ctl_elem_value *ucontrol);
2501
2502static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2503 struct snd_ctl_elem_value *ucontrol,
2504 getput_call_t func)
2505{
2506 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2507 struct alc_spec *spec = codec->spec;
2508 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2509 int err;
2510
5a9e02e9 2511 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2512 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2513 3, 0, HDA_INPUT);
2514 err = func(kcontrol, ucontrol);
5a9e02e9 2515 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2516 return err;
2517}
2518
2519static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2520 struct snd_ctl_elem_value *ucontrol)
2521{
2522 return alc_cap_getput_caller(kcontrol, ucontrol,
2523 snd_hda_mixer_amp_volume_get);
2524}
2525
2526static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2527 struct snd_ctl_elem_value *ucontrol)
2528{
2529 return alc_cap_getput_caller(kcontrol, ucontrol,
2530 snd_hda_mixer_amp_volume_put);
2531}
2532
2533/* capture mixer elements */
2534#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2535
2536static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2537 struct snd_ctl_elem_value *ucontrol)
2538{
2539 return alc_cap_getput_caller(kcontrol, ucontrol,
2540 snd_hda_mixer_amp_switch_get);
2541}
2542
2543static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2544 struct snd_ctl_elem_value *ucontrol)
2545{
2546 return alc_cap_getput_caller(kcontrol, ucontrol,
2547 snd_hda_mixer_amp_switch_put);
2548}
2549
a23b688f 2550#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2551 { \
2552 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2553 .name = "Capture Switch", \
2554 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2555 .count = num, \
2556 .info = alc_cap_sw_info, \
2557 .get = alc_cap_sw_get, \
2558 .put = alc_cap_sw_put, \
2559 }, \
2560 { \
2561 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2562 .name = "Capture Volume", \
2563 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2564 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2565 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2566 .count = num, \
2567 .info = alc_cap_vol_info, \
2568 .get = alc_cap_vol_get, \
2569 .put = alc_cap_vol_put, \
2570 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2571 }
2572
2573#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2574 { \
2575 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2576 /* .name = "Capture Source", */ \
2577 .name = "Input Source", \
2578 .count = num, \
2579 .info = alc_mux_enum_info, \
2580 .get = alc_mux_enum_get, \
2581 .put = alc_mux_enum_put, \
a23b688f
TI
2582 }
2583
2584#define DEFINE_CAPMIX(num) \
2585static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2586 _DEFINE_CAPMIX(num), \
2587 _DEFINE_CAPSRC(num), \
2588 { } /* end */ \
2589}
2590
2591#define DEFINE_CAPMIX_NOSRC(num) \
2592static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2593 _DEFINE_CAPMIX(num), \
2594 { } /* end */ \
f9e336f6
TI
2595}
2596
2597/* up to three ADCs */
2598DEFINE_CAPMIX(1);
2599DEFINE_CAPMIX(2);
2600DEFINE_CAPMIX(3);
a23b688f
TI
2601DEFINE_CAPMIX_NOSRC(1);
2602DEFINE_CAPMIX_NOSRC(2);
2603DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2604
2605/*
2606 * ALC880 5-stack model
2607 *
9c7f852e
TI
2608 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2609 * Side = 0x02 (0xd)
e9edcee0
TI
2610 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2611 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2612 */
2613
2614/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 2615static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2616 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2617 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2618 { } /* end */
2619};
2620
e9edcee0
TI
2621/* channel source setting (6/8 channel selection for 5-stack) */
2622/* 6ch mode */
2623static struct hda_verb alc880_fivestack_ch6_init[] = {
2624 /* set line-in to input, mute it */
2625 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2626 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2627 { } /* end */
2628};
2629
e9edcee0
TI
2630/* 8ch mode */
2631static struct hda_verb alc880_fivestack_ch8_init[] = {
2632 /* set line-in to output, unmute it */
2633 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2634 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2635 { } /* end */
2636};
2637
d2a6d7dc 2638static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2639 { 6, alc880_fivestack_ch6_init },
2640 { 8, alc880_fivestack_ch8_init },
2641};
2642
2643
2644/*
2645 * ALC880 6-stack model
2646 *
9c7f852e
TI
2647 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2648 * Side = 0x05 (0x0f)
e9edcee0
TI
2649 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2650 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2651 */
2652
2653static hda_nid_t alc880_6st_dac_nids[4] = {
2654 /* front, rear, clfe, rear_surr */
2655 0x02, 0x03, 0x04, 0x05
f12ab1e0 2656};
e9edcee0
TI
2657
2658static struct hda_input_mux alc880_6stack_capture_source = {
2659 .num_items = 4,
2660 .items = {
2661 { "Mic", 0x0 },
2662 { "Front Mic", 0x1 },
2663 { "Line", 0x2 },
2664 { "CD", 0x4 },
2665 },
2666};
2667
2668/* fixed 8-channels */
d2a6d7dc 2669static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2670 { 8, NULL },
2671};
2672
c8b6bf9b 2673static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2674 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2675 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2676 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2677 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2678 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2679 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2680 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2681 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2682 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2683 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2684 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2685 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2686 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2687 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2688 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2689 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2690 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2691 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2692 {
2693 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2694 .name = "Channel Mode",
df694daa
KY
2695 .info = alc_ch_mode_info,
2696 .get = alc_ch_mode_get,
2697 .put = alc_ch_mode_put,
16ded525
TI
2698 },
2699 { } /* end */
2700};
2701
e9edcee0
TI
2702
2703/*
2704 * ALC880 W810 model
2705 *
2706 * W810 has rear IO for:
2707 * Front (DAC 02)
2708 * Surround (DAC 03)
2709 * Center/LFE (DAC 04)
2710 * Digital out (06)
2711 *
2712 * The system also has a pair of internal speakers, and a headphone jack.
2713 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2714 *
e9edcee0
TI
2715 * There is a variable resistor to control the speaker or headphone
2716 * volume. This is a hardware-only device without a software API.
2717 *
2718 * Plugging headphones in will disable the internal speakers. This is
2719 * implemented in hardware, not via the driver using jack sense. In
2720 * a similar fashion, plugging into the rear socket marked "front" will
2721 * disable both the speakers and headphones.
2722 *
2723 * For input, there's a microphone jack, and an "audio in" jack.
2724 * These may not do anything useful with this driver yet, because I
2725 * haven't setup any initialization verbs for these yet...
2726 */
2727
2728static hda_nid_t alc880_w810_dac_nids[3] = {
2729 /* front, rear/surround, clfe */
2730 0x02, 0x03, 0x04
16ded525
TI
2731};
2732
e9edcee0 2733/* fixed 6 channels */
d2a6d7dc 2734static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2735 { 6, NULL }
2736};
2737
2738/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 2739static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2740 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2741 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2742 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2743 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2744 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2745 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2746 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2747 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2748 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2749 { } /* end */
2750};
2751
2752
2753/*
2754 * Z710V model
2755 *
2756 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2757 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2758 * Line = 0x1a
e9edcee0
TI
2759 */
2760
2761static hda_nid_t alc880_z71v_dac_nids[1] = {
2762 0x02
2763};
2764#define ALC880_Z71V_HP_DAC 0x03
2765
2766/* fixed 2 channels */
d2a6d7dc 2767static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2768 { 2, NULL }
2769};
2770
c8b6bf9b 2771static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2772 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2773 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2774 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2775 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2776 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2777 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2778 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2779 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2780 { } /* end */
2781};
2782
e9edcee0 2783
e9edcee0
TI
2784/*
2785 * ALC880 F1734 model
2786 *
2787 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2788 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2789 */
2790
2791static hda_nid_t alc880_f1734_dac_nids[1] = {
2792 0x03
2793};
2794#define ALC880_F1734_HP_DAC 0x02
2795
c8b6bf9b 2796static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2797 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2798 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2799 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2800 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2801 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2802 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2803 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2804 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2805 { } /* end */
2806};
2807
937b4160
TI
2808static struct hda_input_mux alc880_f1734_capture_source = {
2809 .num_items = 2,
2810 .items = {
2811 { "Mic", 0x1 },
2812 { "CD", 0x4 },
2813 },
2814};
2815
e9edcee0 2816
e9edcee0
TI
2817/*
2818 * ALC880 ASUS model
2819 *
2820 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2821 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2822 * Mic = 0x18, Line = 0x1a
2823 */
2824
2825#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2826#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2827
c8b6bf9b 2828static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2829 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2830 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2831 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2832 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2833 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2834 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2835 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2836 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2837 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2838 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2839 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2840 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2841 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2842 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2843 {
2844 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2845 .name = "Channel Mode",
df694daa
KY
2846 .info = alc_ch_mode_info,
2847 .get = alc_ch_mode_get,
2848 .put = alc_ch_mode_put,
16ded525
TI
2849 },
2850 { } /* end */
2851};
e9edcee0 2852
e9edcee0
TI
2853/*
2854 * ALC880 ASUS W1V model
2855 *
2856 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2857 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2858 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2859 */
2860
2861/* additional mixers to alc880_asus_mixer */
c8b6bf9b 2862static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
2863 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2864 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2865 { } /* end */
2866};
2867
df694daa
KY
2868/* TCL S700 */
2869static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2870 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2871 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2872 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2873 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2874 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2875 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2876 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2877 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2878 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2879 { } /* end */
2880};
2881
ccc656ce
KY
2882/* Uniwill */
2883static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2884 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2885 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2886 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2887 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2888 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2889 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2890 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2891 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2892 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2893 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2894 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2895 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2896 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2897 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2898 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2899 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2900 {
2901 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2902 .name = "Channel Mode",
2903 .info = alc_ch_mode_info,
2904 .get = alc_ch_mode_get,
2905 .put = alc_ch_mode_put,
2906 },
2907 { } /* end */
2908};
2909
2cf9f0fc
TD
2910static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2911 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2912 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2913 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2914 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2915 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2916 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8607f7c4
DH
2917 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2918 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
2919 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2920 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2cf9f0fc
TD
2921 { } /* end */
2922};
2923
ccc656ce 2924static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2925 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2926 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2927 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2928 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2929 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2930 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2931 { } /* end */
2932};
2933
2134ea4f
TI
2934/*
2935 * virtual master controls
2936 */
2937
2938/*
2939 * slave controls for virtual master
2940 */
ea734963 2941static const char * const alc_slave_vols[] = {
2134ea4f
TI
2942 "Front Playback Volume",
2943 "Surround Playback Volume",
2944 "Center Playback Volume",
2945 "LFE Playback Volume",
2946 "Side Playback Volume",
2947 "Headphone Playback Volume",
2948 "Speaker Playback Volume",
2949 "Mono Playback Volume",
2134ea4f 2950 "Line-Out Playback Volume",
26f5df26 2951 "PCM Playback Volume",
2134ea4f
TI
2952 NULL,
2953};
2954
ea734963 2955static const char * const alc_slave_sws[] = {
2134ea4f
TI
2956 "Front Playback Switch",
2957 "Surround Playback Switch",
2958 "Center Playback Switch",
2959 "LFE Playback Switch",
2960 "Side Playback Switch",
2961 "Headphone Playback Switch",
2962 "Speaker Playback Switch",
2963 "Mono Playback Switch",
edb54a55 2964 "IEC958 Playback Switch",
23033b2b
TI
2965 "Line-Out Playback Switch",
2966 "PCM Playback Switch",
2134ea4f
TI
2967 NULL,
2968};
2969
1da177e4 2970/*
e9edcee0 2971 * build control elements
1da177e4 2972 */
603c4019 2973
5b0cb1d8
JK
2974#define NID_MAPPING (-1)
2975
2976#define SUBDEV_SPEAKER_ (0 << 6)
2977#define SUBDEV_HP_ (1 << 6)
2978#define SUBDEV_LINE_ (2 << 6)
2979#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2980#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2981#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2982
603c4019
TI
2983static void alc_free_kctls(struct hda_codec *codec);
2984
67d634c0 2985#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2986/* additional beep mixers; the actual parameters are overwritten at build */
2987static struct snd_kcontrol_new alc_beep_mixer[] = {
2988 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 2989 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
2990 { } /* end */
2991};
67d634c0 2992#endif
45bdd1c1 2993
1da177e4
LT
2994static int alc_build_controls(struct hda_codec *codec)
2995{
2996 struct alc_spec *spec = codec->spec;
2f44f847 2997 struct snd_kcontrol *kctl = NULL;
5b0cb1d8
JK
2998 struct snd_kcontrol_new *knew;
2999 int i, j, err;
3000 unsigned int u;
3001 hda_nid_t nid;
1da177e4
LT
3002
3003 for (i = 0; i < spec->num_mixers; i++) {
3004 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
3005 if (err < 0)
3006 return err;
3007 }
f9e336f6
TI
3008 if (spec->cap_mixer) {
3009 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
3010 if (err < 0)
3011 return err;
3012 }
1da177e4 3013 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
3014 err = snd_hda_create_spdif_out_ctls(codec,
3015 spec->multiout.dig_out_nid);
1da177e4
LT
3016 if (err < 0)
3017 return err;
e64f14f4
TI
3018 if (!spec->no_analog) {
3019 err = snd_hda_create_spdif_share_sw(codec,
3020 &spec->multiout);
3021 if (err < 0)
3022 return err;
3023 spec->multiout.share_spdif = 1;
3024 }
1da177e4
LT
3025 }
3026 if (spec->dig_in_nid) {
3027 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3028 if (err < 0)
3029 return err;
3030 }
2134ea4f 3031
67d634c0 3032#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
3033 /* create beep controls if needed */
3034 if (spec->beep_amp) {
3035 struct snd_kcontrol_new *knew;
3036 for (knew = alc_beep_mixer; knew->name; knew++) {
3037 struct snd_kcontrol *kctl;
3038 kctl = snd_ctl_new1(knew, codec);
3039 if (!kctl)
3040 return -ENOMEM;
3041 kctl->private_value = spec->beep_amp;
5e26dfd0 3042 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
3043 if (err < 0)
3044 return err;
3045 }
3046 }
67d634c0 3047#endif
45bdd1c1 3048
2134ea4f 3049 /* if we have no master control, let's create it */
e64f14f4
TI
3050 if (!spec->no_analog &&
3051 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 3052 unsigned int vmaster_tlv[4];
2134ea4f 3053 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 3054 HDA_OUTPUT, vmaster_tlv);
2134ea4f 3055 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 3056 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
3057 if (err < 0)
3058 return err;
3059 }
e64f14f4
TI
3060 if (!spec->no_analog &&
3061 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
3062 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3063 NULL, alc_slave_sws);
3064 if (err < 0)
3065 return err;
3066 }
3067
5b0cb1d8 3068 /* assign Capture Source enums to NID */
fbe618f2
TI
3069 if (spec->capsrc_nids || spec->adc_nids) {
3070 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3071 if (!kctl)
3072 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3073 for (i = 0; kctl && i < kctl->count; i++) {
3074 hda_nid_t *nids = spec->capsrc_nids;
3075 if (!nids)
3076 nids = spec->adc_nids;
3077 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3078 if (err < 0)
3079 return err;
3080 }
5b0cb1d8
JK
3081 }
3082 if (spec->cap_mixer) {
3083 const char *kname = kctl ? kctl->id.name : NULL;
3084 for (knew = spec->cap_mixer; knew->name; knew++) {
3085 if (kname && strcmp(knew->name, kname) == 0)
3086 continue;
3087 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3088 for (i = 0; kctl && i < kctl->count; i++) {
3089 err = snd_hda_add_nid(codec, kctl, i,
3090 spec->adc_nids[i]);
3091 if (err < 0)
3092 return err;
3093 }
3094 }
3095 }
3096
3097 /* other nid->control mapping */
3098 for (i = 0; i < spec->num_mixers; i++) {
3099 for (knew = spec->mixers[i]; knew->name; knew++) {
3100 if (knew->iface != NID_MAPPING)
3101 continue;
3102 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3103 if (kctl == NULL)
3104 continue;
3105 u = knew->subdevice;
3106 for (j = 0; j < 4; j++, u >>= 8) {
3107 nid = u & 0x3f;
3108 if (nid == 0)
3109 continue;
3110 switch (u & 0xc0) {
3111 case SUBDEV_SPEAKER_:
3112 nid = spec->autocfg.speaker_pins[nid];
3113 break;
3114 case SUBDEV_LINE_:
3115 nid = spec->autocfg.line_out_pins[nid];
3116 break;
3117 case SUBDEV_HP_:
3118 nid = spec->autocfg.hp_pins[nid];
3119 break;
3120 default:
3121 continue;
3122 }
3123 err = snd_hda_add_nid(codec, kctl, 0, nid);
3124 if (err < 0)
3125 return err;
3126 }
3127 u = knew->private_value;
3128 for (j = 0; j < 4; j++, u >>= 8) {
3129 nid = u & 0xff;
3130 if (nid == 0)
3131 continue;
3132 err = snd_hda_add_nid(codec, kctl, 0, nid);
3133 if (err < 0)
3134 return err;
3135 }
3136 }
3137 }
bae84e70
TI
3138
3139 alc_free_kctls(codec); /* no longer needed */
3140
1da177e4
LT
3141 return 0;
3142}
3143
e9edcee0 3144
1da177e4
LT
3145/*
3146 * initialize the codec volumes, etc
3147 */
3148
e9edcee0
TI
3149/*
3150 * generic initialization of ADC, input mixers and output mixers
3151 */
3152static struct hda_verb alc880_volume_init_verbs[] = {
3153 /*
3154 * Unmute ADC0-2 and set the default input to mic-in
3155 */
71fe7b82 3156 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3157 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3158 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3159 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3160 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3161 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 3162
e9edcee0
TI
3163 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3164 * mixer widget
9c7f852e
TI
3165 * Note: PASD motherboards uses the Line In 2 as the input for front
3166 * panel mic (mic 2)
1da177e4 3167 */
e9edcee0 3168 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
3169 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3170 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3171 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3172 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3173 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3174 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3175 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 3176
e9edcee0
TI
3177 /*
3178 * Set up output mixers (0x0c - 0x0f)
1da177e4 3179 */
e9edcee0
TI
3180 /* set vol=0 to output mixers */
3181 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3182 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3183 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3184 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3185 /* set up input amps for analog loopback */
3186 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
3187 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3188 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3189 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3190 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3191 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3192 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3193 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3194 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
3195
3196 { }
3197};
3198
e9edcee0
TI
3199/*
3200 * 3-stack pin configuration:
3201 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3202 */
3203static struct hda_verb alc880_pin_3stack_init_verbs[] = {
3204 /*
3205 * preset connection lists of input pins
3206 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3207 */
3208 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3209 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3210 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3211
3212 /*
3213 * Set pin mode and muting
3214 */
3215 /* set front pin widgets 0x14 for output */
05acb863 3216 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3217 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3218 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3219 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3220 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3221 /* Mic2 (as headphone out) for HP output */
3222 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3223 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3224 /* Line In pin widget for input */
05acb863 3225 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3226 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3227 /* Line2 (as front mic) pin widget for input and vref at 80% */
3228 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3229 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3230 /* CD pin widget for input */
05acb863 3231 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3232
e9edcee0
TI
3233 { }
3234};
1da177e4 3235
e9edcee0
TI
3236/*
3237 * 5-stack pin configuration:
3238 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3239 * line-in/side = 0x1a, f-mic = 0x1b
3240 */
3241static struct hda_verb alc880_pin_5stack_init_verbs[] = {
3242 /*
3243 * preset connection lists of input pins
3244 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 3245 */
e9edcee0
TI
3246 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3247 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 3248
e9edcee0
TI
3249 /*
3250 * Set pin mode and muting
1da177e4 3251 */
e9edcee0
TI
3252 /* set pin widgets 0x14-0x17 for output */
3253 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3254 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3255 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3256 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3257 /* unmute pins for output (no gain on this amp) */
3258 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3259 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3260 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3261 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3262
3263 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3264 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3265 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3266 /* Mic2 (as headphone out) for HP output */
3267 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3268 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3269 /* Line In pin widget for input */
3270 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3271 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3272 /* Line2 (as front mic) pin widget for input and vref at 80% */
3273 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3274 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3275 /* CD pin widget for input */
3276 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3277
3278 { }
3279};
3280
e9edcee0
TI
3281/*
3282 * W810 pin configuration:
3283 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3284 */
3285static struct hda_verb alc880_pin_w810_init_verbs[] = {
3286 /* hphone/speaker input selector: front DAC */
3287 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 3288
05acb863 3289 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3290 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3291 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3292 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3293 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3294 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3295
e9edcee0 3296 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 3297 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3298
1da177e4
LT
3299 { }
3300};
3301
e9edcee0
TI
3302/*
3303 * Z71V pin configuration:
3304 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3305 */
3306static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 3307 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3308 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3309 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3310 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 3311
16ded525 3312 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3313 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 3314 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3315 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
3316
3317 { }
3318};
3319
e9edcee0
TI
3320/*
3321 * 6-stack pin configuration:
9c7f852e
TI
3322 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3323 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
3324 */
3325static struct hda_verb alc880_pin_6stack_init_verbs[] = {
3326 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3327
16ded525 3328 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3329 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3330 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3331 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3332 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3333 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3334 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3335 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3336
16ded525 3337 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3338 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3339 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3340 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3341 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3342 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3343 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3344 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3345 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3346
e9edcee0
TI
3347 { }
3348};
3349
ccc656ce
KY
3350/*
3351 * Uniwill pin configuration:
3352 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3353 * line = 0x1a
3354 */
3355static struct hda_verb alc880_uniwill_init_verbs[] = {
3356 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3357
3358 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3359 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3360 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3361 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3362 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3363 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3364 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3365 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3366 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3368 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3369 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3370 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3371 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3372
3373 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3374 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3375 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3376 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3377 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3378 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3379 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3380 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3381 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3382
3383 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3384 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3385
3386 { }
3387};
3388
3389/*
3390* Uniwill P53
ea1fb29a 3391* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
3392 */
3393static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3394 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3395
3396 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3397 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3398 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3399 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3400 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3401 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3402 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3403 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3404 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3405 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3406 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3407 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3408
3409 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3410 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3411 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3412 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3413 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3414 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3415
3416 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3417 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3418
3419 { }
3420};
3421
2cf9f0fc
TD
3422static struct hda_verb alc880_beep_init_verbs[] = {
3423 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3424 { }
3425};
3426
458a4fab 3427/* auto-toggle front mic */
eeb43387 3428static void alc88x_simple_mic_automute(struct hda_codec *codec)
458a4fab
TI
3429{
3430 unsigned int present;
3431 unsigned char bits;
ccc656ce 3432
864f92be 3433 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3434 bits = present ? HDA_AMP_MUTE : 0;
3435 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3436}
3437
4f5d1706 3438static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3439{
a9fd4f3f
TI
3440 struct alc_spec *spec = codec->spec;
3441
3442 spec->autocfg.hp_pins[0] = 0x14;
3443 spec->autocfg.speaker_pins[0] = 0x15;
3444 spec->autocfg.speaker_pins[0] = 0x16;
4f5d1706
TI
3445}
3446
3447static void alc880_uniwill_init_hook(struct hda_codec *codec)
3448{
a9fd4f3f 3449 alc_automute_amp(codec);
eeb43387 3450 alc88x_simple_mic_automute(codec);
ccc656ce
KY
3451}
3452
3453static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3454 unsigned int res)
3455{
3456 /* Looks like the unsol event is incompatible with the standard
3457 * definition. 4bit tag is placed at 28 bit!
3458 */
458a4fab 3459 switch (res >> 28) {
458a4fab 3460 case ALC880_MIC_EVENT:
eeb43387 3461 alc88x_simple_mic_automute(codec);
458a4fab 3462 break;
a9fd4f3f
TI
3463 default:
3464 alc_automute_amp_unsol_event(codec, res);
3465 break;
458a4fab 3466 }
ccc656ce
KY
3467}
3468
4f5d1706 3469static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3470{
a9fd4f3f 3471 struct alc_spec *spec = codec->spec;
ccc656ce 3472
a9fd4f3f
TI
3473 spec->autocfg.hp_pins[0] = 0x14;
3474 spec->autocfg.speaker_pins[0] = 0x15;
ccc656ce
KY
3475}
3476
3477static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3478{
3479 unsigned int present;
ea1fb29a 3480
ccc656ce 3481 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3482 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3483 present &= HDA_AMP_VOLMASK;
3484 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3485 HDA_AMP_VOLMASK, present);
3486 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3487 HDA_AMP_VOLMASK, present);
ccc656ce 3488}
47fd830a 3489
ccc656ce
KY
3490static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3491 unsigned int res)
3492{
3493 /* Looks like the unsol event is incompatible with the standard
3494 * definition. 4bit tag is placed at 28 bit!
3495 */
f12ab1e0 3496 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3497 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
3498 else
3499 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
3500}
3501
e9edcee0
TI
3502/*
3503 * F1734 pin configuration:
3504 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3505 */
3506static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3507 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3508 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3509 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3510 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3511 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3512
e9edcee0 3513 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3514 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3515 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3516 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3517
e9edcee0
TI
3518 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3519 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3520 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3521 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3522 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3523 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3524 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3525 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3526 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3527
937b4160
TI
3528 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3529 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3530
dfc0ff62
TI
3531 { }
3532};
3533
e9edcee0
TI
3534/*
3535 * ASUS pin configuration:
3536 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3537 */
3538static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3539 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3540 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3541 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3542 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3543
3544 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3545 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3546 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3547 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3548 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3549 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3550 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3551 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3552
3553 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3554 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3555 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3556 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3557 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3558 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3559 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3560 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3561 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3562
e9edcee0
TI
3563 { }
3564};
16ded525 3565
e9edcee0 3566/* Enable GPIO mask and set output */
bc9f98a9
KY
3567#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3568#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3569#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3570
3571/* Clevo m520g init */
3572static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3573 /* headphone output */
3574 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3575 /* line-out */
3576 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3577 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3578 /* Line-in */
3579 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3580 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3581 /* CD */
3582 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3583 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3584 /* Mic1 (rear panel) */
3585 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3586 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3587 /* Mic2 (front panel) */
3588 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3589 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3590 /* headphone */
3591 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3592 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3593 /* change to EAPD mode */
3594 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3595 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3596
3597 { }
16ded525
TI
3598};
3599
df694daa 3600static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3601 /* change to EAPD mode */
3602 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3603 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3604
df694daa
KY
3605 /* Headphone output */
3606 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3607 /* Front output*/
3608 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3609 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3610
3611 /* Line In pin widget for input */
3612 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3613 /* CD pin widget for input */
3614 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3615 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3616 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3617
3618 /* change to EAPD mode */
3619 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3620 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3621
3622 { }
3623};
16ded525 3624
e9edcee0 3625/*
ae6b813a
TI
3626 * LG m1 express dual
3627 *
3628 * Pin assignment:
3629 * Rear Line-In/Out (blue): 0x14
3630 * Build-in Mic-In: 0x15
3631 * Speaker-out: 0x17
3632 * HP-Out (green): 0x1b
3633 * Mic-In/Out (red): 0x19
3634 * SPDIF-Out: 0x1e
3635 */
3636
3637/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3638static hda_nid_t alc880_lg_dac_nids[3] = {
3639 0x05, 0x02, 0x03
3640};
3641
3642/* seems analog CD is not working */
3643static struct hda_input_mux alc880_lg_capture_source = {
3644 .num_items = 3,
3645 .items = {
3646 { "Mic", 0x1 },
3647 { "Line", 0x5 },
3648 { "Internal Mic", 0x6 },
3649 },
3650};
3651
3652/* 2,4,6 channel modes */
3653static struct hda_verb alc880_lg_ch2_init[] = {
3654 /* set line-in and mic-in to input */
3655 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3656 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3657 { }
3658};
3659
3660static struct hda_verb alc880_lg_ch4_init[] = {
3661 /* set line-in to out and mic-in to input */
3662 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3663 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3664 { }
3665};
3666
3667static struct hda_verb alc880_lg_ch6_init[] = {
3668 /* set line-in and mic-in to output */
3669 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3670 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3671 { }
3672};
3673
3674static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3675 { 2, alc880_lg_ch2_init },
3676 { 4, alc880_lg_ch4_init },
3677 { 6, alc880_lg_ch6_init },
3678};
3679
3680static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3681 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3682 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3683 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3684 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3685 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3686 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3687 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3688 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3689 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3690 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3691 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3692 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3693 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3694 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3695 {
3696 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3697 .name = "Channel Mode",
3698 .info = alc_ch_mode_info,
3699 .get = alc_ch_mode_get,
3700 .put = alc_ch_mode_put,
3701 },
3702 { } /* end */
3703};
3704
3705static struct hda_verb alc880_lg_init_verbs[] = {
3706 /* set capture source to mic-in */
3707 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3708 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3709 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3710 /* mute all amp mixer inputs */
3711 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3712 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3713 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3714 /* line-in to input */
3715 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3716 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3717 /* built-in mic */
3718 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3719 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3720 /* speaker-out */
3721 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3722 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3723 /* mic-in to input */
3724 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3725 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3726 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3727 /* HP-out */
3728 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3729 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3730 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3731 /* jack sense */
a9fd4f3f 3732 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3733 { }
3734};
3735
3736/* toggle speaker-output according to the hp-jack state */
4f5d1706 3737static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3738{
a9fd4f3f 3739 struct alc_spec *spec = codec->spec;
ae6b813a 3740
a9fd4f3f
TI
3741 spec->autocfg.hp_pins[0] = 0x1b;
3742 spec->autocfg.speaker_pins[0] = 0x17;
ae6b813a
TI
3743}
3744
d681518a
TI
3745/*
3746 * LG LW20
3747 *
3748 * Pin assignment:
3749 * Speaker-out: 0x14
3750 * Mic-In: 0x18
e4f41da9
CM
3751 * Built-in Mic-In: 0x19
3752 * Line-In: 0x1b
3753 * HP-Out: 0x1a
d681518a
TI
3754 * SPDIF-Out: 0x1e
3755 */
3756
d681518a 3757static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3758 .num_items = 3,
d681518a
TI
3759 .items = {
3760 { "Mic", 0x0 },
3761 { "Internal Mic", 0x1 },
e4f41da9 3762 { "Line In", 0x2 },
d681518a
TI
3763 },
3764};
3765
0a8c5da3
CM
3766#define alc880_lg_lw_modes alc880_threestack_modes
3767
d681518a 3768static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3769 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3770 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3771 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3772 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3773 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3774 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3775 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3776 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3777 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3778 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3779 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3780 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3781 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3782 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3783 {
3784 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3785 .name = "Channel Mode",
3786 .info = alc_ch_mode_info,
3787 .get = alc_ch_mode_get,
3788 .put = alc_ch_mode_put,
3789 },
d681518a
TI
3790 { } /* end */
3791};
3792
3793static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3794 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3795 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3796 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3797
d681518a
TI
3798 /* set capture source to mic-in */
3799 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3800 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3801 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3802 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3803 /* speaker-out */
3804 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3805 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3806 /* HP-out */
d681518a
TI
3807 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3808 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3809 /* mic-in to input */
3810 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3811 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3812 /* built-in mic */
3813 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3814 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3815 /* jack sense */
a9fd4f3f 3816 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3817 { }
3818};
3819
3820/* toggle speaker-output according to the hp-jack state */
4f5d1706 3821static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3822{
a9fd4f3f 3823 struct alc_spec *spec = codec->spec;
d681518a 3824
a9fd4f3f
TI
3825 spec->autocfg.hp_pins[0] = 0x1b;
3826 spec->autocfg.speaker_pins[0] = 0x14;
d681518a
TI
3827}
3828
df99cd33
TI
3829static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3830 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3831 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3832 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3833 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3834 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3835 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3836 { } /* end */
3837};
3838
3839static struct hda_input_mux alc880_medion_rim_capture_source = {
3840 .num_items = 2,
3841 .items = {
3842 { "Mic", 0x0 },
3843 { "Internal Mic", 0x1 },
3844 },
3845};
3846
3847static struct hda_verb alc880_medion_rim_init_verbs[] = {
3848 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3849
3850 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3851 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3852
3853 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3854 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3855 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3856 /* Mic2 (as headphone out) for HP output */
3857 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3858 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3859 /* Internal Speaker */
3860 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3861 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3862
3863 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3864 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3865
3866 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3867 { }
3868};
3869
3870/* toggle speaker-output according to the hp-jack state */
3871static void alc880_medion_rim_automute(struct hda_codec *codec)
3872{
a9fd4f3f
TI
3873 struct alc_spec *spec = codec->spec;
3874 alc_automute_amp(codec);
3875 /* toggle EAPD */
3876 if (spec->jack_present)
df99cd33
TI
3877 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3878 else
3879 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3880}
3881
3882static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3883 unsigned int res)
3884{
3885 /* Looks like the unsol event is incompatible with the standard
3886 * definition. 4bit tag is placed at 28 bit!
3887 */
3888 if ((res >> 28) == ALC880_HP_EVENT)
3889 alc880_medion_rim_automute(codec);
3890}
3891
4f5d1706 3892static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
3893{
3894 struct alc_spec *spec = codec->spec;
3895
3896 spec->autocfg.hp_pins[0] = 0x14;
3897 spec->autocfg.speaker_pins[0] = 0x1b;
a9fd4f3f
TI
3898}
3899
cb53c626
TI
3900#ifdef CONFIG_SND_HDA_POWER_SAVE
3901static struct hda_amp_list alc880_loopbacks[] = {
3902 { 0x0b, HDA_INPUT, 0 },
3903 { 0x0b, HDA_INPUT, 1 },
3904 { 0x0b, HDA_INPUT, 2 },
3905 { 0x0b, HDA_INPUT, 3 },
3906 { 0x0b, HDA_INPUT, 4 },
3907 { } /* end */
3908};
3909
3910static struct hda_amp_list alc880_lg_loopbacks[] = {
3911 { 0x0b, HDA_INPUT, 1 },
3912 { 0x0b, HDA_INPUT, 6 },
3913 { 0x0b, HDA_INPUT, 7 },
3914 { } /* end */
3915};
3916#endif
3917
ae6b813a
TI
3918/*
3919 * Common callbacks
e9edcee0
TI
3920 */
3921
1da177e4
LT
3922static int alc_init(struct hda_codec *codec)
3923{
3924 struct alc_spec *spec = codec->spec;
e9edcee0
TI
3925 unsigned int i;
3926
2c3bf9ab 3927 alc_fix_pll(codec);
4a79ba34 3928 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 3929
e9edcee0
TI
3930 for (i = 0; i < spec->num_init_verbs; i++)
3931 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
3932
3933 if (spec->init_hook)
3934 spec->init_hook(codec);
3935
58701120
TI
3936 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
3937
9e5341b9 3938 hda_call_check_power_status(codec, 0x01);
1da177e4
LT
3939 return 0;
3940}
3941
ae6b813a
TI
3942static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3943{
3944 struct alc_spec *spec = codec->spec;
3945
3946 if (spec->unsol_event)
3947 spec->unsol_event(codec, res);
3948}
3949
cb53c626
TI
3950#ifdef CONFIG_SND_HDA_POWER_SAVE
3951static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3952{
3953 struct alc_spec *spec = codec->spec;
3954 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3955}
3956#endif
3957
1da177e4
LT
3958/*
3959 * Analog playback callbacks
3960 */
3961static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3962 struct hda_codec *codec,
c8b6bf9b 3963 struct snd_pcm_substream *substream)
1da177e4
LT
3964{
3965 struct alc_spec *spec = codec->spec;
9a08160b
TI
3966 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3967 hinfo);
1da177e4
LT
3968}
3969
3970static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3971 struct hda_codec *codec,
3972 unsigned int stream_tag,
3973 unsigned int format,
c8b6bf9b 3974 struct snd_pcm_substream *substream)
1da177e4
LT
3975{
3976 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3977 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3978 stream_tag, format, substream);
1da177e4
LT
3979}
3980
3981static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3982 struct hda_codec *codec,
c8b6bf9b 3983 struct snd_pcm_substream *substream)
1da177e4
LT
3984{
3985 struct alc_spec *spec = codec->spec;
3986 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3987}
3988
3989/*
3990 * Digital out
3991 */
3992static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3993 struct hda_codec *codec,
c8b6bf9b 3994 struct snd_pcm_substream *substream)
1da177e4
LT
3995{
3996 struct alc_spec *spec = codec->spec;
3997 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3998}
3999
6b97eb45
TI
4000static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4001 struct hda_codec *codec,
4002 unsigned int stream_tag,
4003 unsigned int format,
4004 struct snd_pcm_substream *substream)
4005{
4006 struct alc_spec *spec = codec->spec;
4007 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4008 stream_tag, format, substream);
4009}
4010
9b5f12e5
TI
4011static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4012 struct hda_codec *codec,
4013 struct snd_pcm_substream *substream)
4014{
4015 struct alc_spec *spec = codec->spec;
4016 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4017}
4018
1da177e4
LT
4019static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4020 struct hda_codec *codec,
c8b6bf9b 4021 struct snd_pcm_substream *substream)
1da177e4
LT
4022{
4023 struct alc_spec *spec = codec->spec;
4024 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4025}
4026
4027/*
4028 * Analog capture
4029 */
6330079f 4030static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
4031 struct hda_codec *codec,
4032 unsigned int stream_tag,
4033 unsigned int format,
c8b6bf9b 4034 struct snd_pcm_substream *substream)
1da177e4
LT
4035{
4036 struct alc_spec *spec = codec->spec;
4037
6330079f 4038 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
4039 stream_tag, 0, format);
4040 return 0;
4041}
4042
6330079f 4043static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 4044 struct hda_codec *codec,
c8b6bf9b 4045 struct snd_pcm_substream *substream)
1da177e4
LT
4046{
4047 struct alc_spec *spec = codec->spec;
4048
888afa15
TI
4049 snd_hda_codec_cleanup_stream(codec,
4050 spec->adc_nids[substream->number + 1]);
1da177e4
LT
4051 return 0;
4052}
4053
840b64c0
TI
4054/* analog capture with dynamic dual-adc changes */
4055static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4056 struct hda_codec *codec,
4057 unsigned int stream_tag,
4058 unsigned int format,
4059 struct snd_pcm_substream *substream)
4060{
4061 struct alc_spec *spec = codec->spec;
4062 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4063 spec->cur_adc_stream_tag = stream_tag;
4064 spec->cur_adc_format = format;
4065 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4066 return 0;
4067}
4068
4069static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4070 struct hda_codec *codec,
4071 struct snd_pcm_substream *substream)
4072{
4073 struct alc_spec *spec = codec->spec;
4074 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4075 spec->cur_adc = 0;
4076 return 0;
4077}
4078
4079static struct hda_pcm_stream dualmic_pcm_analog_capture = {
4080 .substreams = 1,
4081 .channels_min = 2,
4082 .channels_max = 2,
4083 .nid = 0, /* fill later */
4084 .ops = {
4085 .prepare = dualmic_capture_pcm_prepare,
4086 .cleanup = dualmic_capture_pcm_cleanup
4087 },
4088};
1da177e4
LT
4089
4090/*
4091 */
4092static struct hda_pcm_stream alc880_pcm_analog_playback = {
4093 .substreams = 1,
4094 .channels_min = 2,
4095 .channels_max = 8,
e9edcee0 4096 /* NID is set in alc_build_pcms */
1da177e4
LT
4097 .ops = {
4098 .open = alc880_playback_pcm_open,
4099 .prepare = alc880_playback_pcm_prepare,
4100 .cleanup = alc880_playback_pcm_cleanup
4101 },
4102};
4103
4104static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
4105 .substreams = 1,
4106 .channels_min = 2,
4107 .channels_max = 2,
4108 /* NID is set in alc_build_pcms */
4109};
4110
4111static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
4112 .substreams = 1,
4113 .channels_min = 2,
4114 .channels_max = 2,
4115 /* NID is set in alc_build_pcms */
4116};
4117
4118static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4119 .substreams = 2, /* can be overridden */
1da177e4
LT
4120 .channels_min = 2,
4121 .channels_max = 2,
e9edcee0 4122 /* NID is set in alc_build_pcms */
1da177e4 4123 .ops = {
6330079f
TI
4124 .prepare = alc880_alt_capture_pcm_prepare,
4125 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
4126 },
4127};
4128
4129static struct hda_pcm_stream alc880_pcm_digital_playback = {
4130 .substreams = 1,
4131 .channels_min = 2,
4132 .channels_max = 2,
4133 /* NID is set in alc_build_pcms */
4134 .ops = {
4135 .open = alc880_dig_playback_pcm_open,
6b97eb45 4136 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
4137 .prepare = alc880_dig_playback_pcm_prepare,
4138 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
4139 },
4140};
4141
4142static struct hda_pcm_stream alc880_pcm_digital_capture = {
4143 .substreams = 1,
4144 .channels_min = 2,
4145 .channels_max = 2,
4146 /* NID is set in alc_build_pcms */
4147};
4148
4c5186ed 4149/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 4150static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
4151 .substreams = 0,
4152 .channels_min = 0,
4153 .channels_max = 0,
4154};
4155
1da177e4
LT
4156static int alc_build_pcms(struct hda_codec *codec)
4157{
4158 struct alc_spec *spec = codec->spec;
4159 struct hda_pcm *info = spec->pcm_rec;
4160 int i;
4161
4162 codec->num_pcms = 1;
4163 codec->pcm_info = info;
4164
e64f14f4
TI
4165 if (spec->no_analog)
4166 goto skip_analog;
4167
812a2cca
TI
4168 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4169 "%s Analog", codec->chip_name);
1da177e4 4170 info->name = spec->stream_name_analog;
274693f3 4171
4a471b7d 4172 if (spec->stream_analog_playback) {
da3cec35
TI
4173 if (snd_BUG_ON(!spec->multiout.dac_nids))
4174 return -EINVAL;
4a471b7d
TI
4175 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4176 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4177 }
4178 if (spec->stream_analog_capture) {
da3cec35
TI
4179 if (snd_BUG_ON(!spec->adc_nids))
4180 return -EINVAL;
4a471b7d
TI
4181 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4182 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4183 }
4184
4185 if (spec->channel_mode) {
4186 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4187 for (i = 0; i < spec->num_channel_mode; i++) {
4188 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4189 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4190 }
1da177e4
LT
4191 }
4192 }
4193
e64f14f4 4194 skip_analog:
e08a007d 4195 /* SPDIF for stream index #1 */
1da177e4 4196 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
4197 snprintf(spec->stream_name_digital,
4198 sizeof(spec->stream_name_digital),
4199 "%s Digital", codec->chip_name);
e08a007d 4200 codec->num_pcms = 2;
b25c9da1 4201 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 4202 info = spec->pcm_rec + 1;
1da177e4 4203 info->name = spec->stream_name_digital;
8c441982
TI
4204 if (spec->dig_out_type)
4205 info->pcm_type = spec->dig_out_type;
4206 else
4207 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
4208 if (spec->multiout.dig_out_nid &&
4209 spec->stream_digital_playback) {
1da177e4
LT
4210 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4211 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4212 }
4a471b7d
TI
4213 if (spec->dig_in_nid &&
4214 spec->stream_digital_capture) {
1da177e4
LT
4215 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4216 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4217 }
963f803f
TI
4218 /* FIXME: do we need this for all Realtek codec models? */
4219 codec->spdif_status_reset = 1;
1da177e4
LT
4220 }
4221
e64f14f4
TI
4222 if (spec->no_analog)
4223 return 0;
4224
e08a007d
TI
4225 /* If the use of more than one ADC is requested for the current
4226 * model, configure a second analog capture-only PCM.
4227 */
4228 /* Additional Analaog capture for index #2 */
6330079f
TI
4229 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4230 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 4231 codec->num_pcms = 3;
c06134d7 4232 info = spec->pcm_rec + 2;
e08a007d 4233 info->name = spec->stream_name_analog;
6330079f
TI
4234 if (spec->alt_dac_nid) {
4235 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4236 *spec->stream_analog_alt_playback;
4237 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4238 spec->alt_dac_nid;
4239 } else {
4240 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4241 alc_pcm_null_stream;
4242 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4243 }
4244 if (spec->num_adc_nids > 1) {
4245 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4246 *spec->stream_analog_alt_capture;
4247 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4248 spec->adc_nids[1];
4249 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4250 spec->num_adc_nids - 1;
4251 } else {
4252 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4253 alc_pcm_null_stream;
4254 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4255 }
4256 }
4257
1da177e4
LT
4258 return 0;
4259}
4260
a4e09aa3
TI
4261static inline void alc_shutup(struct hda_codec *codec)
4262{
4263 snd_hda_shutup_pins(codec);
4264}
4265
603c4019
TI
4266static void alc_free_kctls(struct hda_codec *codec)
4267{
4268 struct alc_spec *spec = codec->spec;
4269
4270 if (spec->kctls.list) {
4271 struct snd_kcontrol_new *kctl = spec->kctls.list;
4272 int i;
4273 for (i = 0; i < spec->kctls.used; i++)
4274 kfree(kctl[i].name);
4275 }
4276 snd_array_free(&spec->kctls);
4277}
4278
1da177e4
LT
4279static void alc_free(struct hda_codec *codec)
4280{
e9edcee0 4281 struct alc_spec *spec = codec->spec;
e9edcee0 4282
f12ab1e0 4283 if (!spec)
e9edcee0
TI
4284 return;
4285
a4e09aa3 4286 alc_shutup(codec);
603c4019 4287 alc_free_kctls(codec);
e9edcee0 4288 kfree(spec);
680cd536 4289 snd_hda_detach_beep_device(codec);
1da177e4
LT
4290}
4291
f5de24b0 4292#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4293static void alc_power_eapd(struct hda_codec *codec)
4294{
4295 /* We currently only handle front, HP */
4296 switch (codec->vendor_id) {
4297 case 0x10ec0260:
9e4c8496
TI
4298 set_eapd(codec, 0x0f, 0);
4299 set_eapd(codec, 0x10, 0);
c97259df
DC
4300 break;
4301 case 0x10ec0262:
4302 case 0x10ec0267:
4303 case 0x10ec0268:
4304 case 0x10ec0269:
9e4c8496 4305 case 0x10ec0270:
c97259df
DC
4306 case 0x10ec0272:
4307 case 0x10ec0660:
4308 case 0x10ec0662:
4309 case 0x10ec0663:
4310 case 0x10ec0862:
4311 case 0x10ec0889:
9e4c8496
TI
4312 set_eapd(codec, 0x14, 0);
4313 set_eapd(codec, 0x15, 0);
c97259df
DC
4314 break;
4315 }
4316}
4317
f5de24b0
HM
4318static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4319{
4320 struct alc_spec *spec = codec->spec;
a4e09aa3 4321 alc_shutup(codec);
f5de24b0 4322 if (spec && spec->power_hook)
c97259df 4323 spec->power_hook(codec);
f5de24b0
HM
4324 return 0;
4325}
4326#endif
4327
e044c39a 4328#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4329static int alc_resume(struct hda_codec *codec)
4330{
e044c39a
TI
4331 codec->patch_ops.init(codec);
4332 snd_hda_codec_resume_amp(codec);
4333 snd_hda_codec_resume_cache(codec);
9e5341b9 4334 hda_call_check_power_status(codec, 0x01);
e044c39a
TI
4335 return 0;
4336}
e044c39a
TI
4337#endif
4338
1da177e4
LT
4339/*
4340 */
4341static struct hda_codec_ops alc_patch_ops = {
4342 .build_controls = alc_build_controls,
4343 .build_pcms = alc_build_pcms,
4344 .init = alc_init,
4345 .free = alc_free,
ae6b813a 4346 .unsol_event = alc_unsol_event,
e044c39a
TI
4347#ifdef SND_HDA_NEEDS_RESUME
4348 .resume = alc_resume,
4349#endif
cb53c626 4350#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4351 .suspend = alc_suspend,
cb53c626
TI
4352 .check_power_status = alc_check_power_status,
4353#endif
c97259df 4354 .reboot_notify = alc_shutup,
1da177e4
LT
4355};
4356
c027ddcd
KY
4357/* replace the codec chip_name with the given string */
4358static int alc_codec_rename(struct hda_codec *codec, const char *name)
4359{
4360 kfree(codec->chip_name);
4361 codec->chip_name = kstrdup(name, GFP_KERNEL);
4362 if (!codec->chip_name) {
4363 alc_free(codec);
4364 return -ENOMEM;
4365 }
4366 return 0;
4367}
4368
2fa522be
TI
4369/*
4370 * Test configuration for debugging
4371 *
4372 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4373 * enum controls.
4374 */
4375#ifdef CONFIG_SND_DEBUG
4376static hda_nid_t alc880_test_dac_nids[4] = {
4377 0x02, 0x03, 0x04, 0x05
4378};
4379
4380static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4381 .num_items = 7,
2fa522be
TI
4382 .items = {
4383 { "In-1", 0x0 },
4384 { "In-2", 0x1 },
4385 { "In-3", 0x2 },
4386 { "In-4", 0x3 },
4387 { "CD", 0x4 },
ae6b813a
TI
4388 { "Front", 0x5 },
4389 { "Surround", 0x6 },
2fa522be
TI
4390 },
4391};
4392
d2a6d7dc 4393static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4394 { 2, NULL },
fd2c326d 4395 { 4, NULL },
2fa522be 4396 { 6, NULL },
fd2c326d 4397 { 8, NULL },
2fa522be
TI
4398};
4399
9c7f852e
TI
4400static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4401 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4402{
4403 static char *texts[] = {
4404 "N/A", "Line Out", "HP Out",
4405 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4406 };
4407 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4408 uinfo->count = 1;
4409 uinfo->value.enumerated.items = 8;
4410 if (uinfo->value.enumerated.item >= 8)
4411 uinfo->value.enumerated.item = 7;
4412 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4413 return 0;
4414}
4415
9c7f852e
TI
4416static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4417 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4418{
4419 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4420 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4421 unsigned int pin_ctl, item = 0;
4422
4423 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4424 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4425 if (pin_ctl & AC_PINCTL_OUT_EN) {
4426 if (pin_ctl & AC_PINCTL_HP_EN)
4427 item = 2;
4428 else
4429 item = 1;
4430 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4431 switch (pin_ctl & AC_PINCTL_VREFEN) {
4432 case AC_PINCTL_VREF_HIZ: item = 3; break;
4433 case AC_PINCTL_VREF_50: item = 4; break;
4434 case AC_PINCTL_VREF_GRD: item = 5; break;
4435 case AC_PINCTL_VREF_80: item = 6; break;
4436 case AC_PINCTL_VREF_100: item = 7; break;
4437 }
4438 }
4439 ucontrol->value.enumerated.item[0] = item;
4440 return 0;
4441}
4442
9c7f852e
TI
4443static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4444 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4445{
4446 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4447 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4448 static unsigned int ctls[] = {
4449 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4450 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4451 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4452 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4453 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4454 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4455 };
4456 unsigned int old_ctl, new_ctl;
4457
4458 old_ctl = snd_hda_codec_read(codec, nid, 0,
4459 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4460 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4461 if (old_ctl != new_ctl) {
82beb8fd
TI
4462 int val;
4463 snd_hda_codec_write_cache(codec, nid, 0,
4464 AC_VERB_SET_PIN_WIDGET_CONTROL,
4465 new_ctl);
47fd830a
TI
4466 val = ucontrol->value.enumerated.item[0] >= 3 ?
4467 HDA_AMP_MUTE : 0;
4468 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4469 HDA_AMP_MUTE, val);
2fa522be
TI
4470 return 1;
4471 }
4472 return 0;
4473}
4474
9c7f852e
TI
4475static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4476 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4477{
4478 static char *texts[] = {
4479 "Front", "Surround", "CLFE", "Side"
4480 };
4481 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4482 uinfo->count = 1;
4483 uinfo->value.enumerated.items = 4;
4484 if (uinfo->value.enumerated.item >= 4)
4485 uinfo->value.enumerated.item = 3;
4486 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4487 return 0;
4488}
4489
9c7f852e
TI
4490static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4491 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4492{
4493 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4494 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4495 unsigned int sel;
4496
4497 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4498 ucontrol->value.enumerated.item[0] = sel & 3;
4499 return 0;
4500}
4501
9c7f852e
TI
4502static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4503 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4504{
4505 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4506 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4507 unsigned int sel;
4508
4509 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4510 if (ucontrol->value.enumerated.item[0] != sel) {
4511 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4512 snd_hda_codec_write_cache(codec, nid, 0,
4513 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4514 return 1;
4515 }
4516 return 0;
4517}
4518
4519#define PIN_CTL_TEST(xname,nid) { \
4520 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4521 .name = xname, \
5b0cb1d8 4522 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4523 .info = alc_test_pin_ctl_info, \
4524 .get = alc_test_pin_ctl_get, \
4525 .put = alc_test_pin_ctl_put, \
4526 .private_value = nid \
4527 }
4528
4529#define PIN_SRC_TEST(xname,nid) { \
4530 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4531 .name = xname, \
5b0cb1d8 4532 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4533 .info = alc_test_pin_src_info, \
4534 .get = alc_test_pin_src_get, \
4535 .put = alc_test_pin_src_put, \
4536 .private_value = nid \
4537 }
4538
c8b6bf9b 4539static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4540 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4541 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4542 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4543 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4544 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4545 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4546 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4547 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4548 PIN_CTL_TEST("Front Pin Mode", 0x14),
4549 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4550 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4551 PIN_CTL_TEST("Side Pin Mode", 0x17),
4552 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4553 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4554 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4555 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4556 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4557 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4558 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4559 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4560 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4561 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4562 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4563 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4564 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4565 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4566 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4567 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4568 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4569 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4570 {
4571 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4572 .name = "Channel Mode",
df694daa
KY
4573 .info = alc_ch_mode_info,
4574 .get = alc_ch_mode_get,
4575 .put = alc_ch_mode_put,
2fa522be
TI
4576 },
4577 { } /* end */
4578};
4579
4580static struct hda_verb alc880_test_init_verbs[] = {
4581 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4582 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4583 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4584 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4585 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4586 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4587 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4588 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4589 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4590 /* Vol output for 0x0c-0x0f */
05acb863
TI
4591 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4592 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4593 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4594 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4595 /* Set output pins 0x14-0x17 */
05acb863
TI
4596 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4597 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4598 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4599 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4600 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4601 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4602 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4603 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4604 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4605 /* Set input pins 0x18-0x1c */
16ded525
TI
4606 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4607 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4608 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4609 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4610 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4611 /* Mute input pins 0x18-0x1b */
05acb863
TI
4612 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4613 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4614 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4615 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4616 /* ADC set up */
05acb863 4617 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4618 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4619 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4620 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4621 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4622 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4623 /* Analog input/passthru */
4624 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4625 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4626 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4627 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4628 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4629 { }
4630};
4631#endif
4632
1da177e4
LT
4633/*
4634 */
4635
ea734963 4636static const char * const alc880_models[ALC880_MODEL_LAST] = {
f5fcc13c
TI
4637 [ALC880_3ST] = "3stack",
4638 [ALC880_TCL_S700] = "tcl",
4639 [ALC880_3ST_DIG] = "3stack-digout",
4640 [ALC880_CLEVO] = "clevo",
4641 [ALC880_5ST] = "5stack",
4642 [ALC880_5ST_DIG] = "5stack-digout",
4643 [ALC880_W810] = "w810",
4644 [ALC880_Z71V] = "z71v",
4645 [ALC880_6ST] = "6stack",
4646 [ALC880_6ST_DIG] = "6stack-digout",
4647 [ALC880_ASUS] = "asus",
4648 [ALC880_ASUS_W1V] = "asus-w1v",
4649 [ALC880_ASUS_DIG] = "asus-dig",
4650 [ALC880_ASUS_DIG2] = "asus-dig2",
4651 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4652 [ALC880_UNIWILL_P53] = "uniwill-p53",
4653 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4654 [ALC880_F1734] = "F1734",
4655 [ALC880_LG] = "lg",
4656 [ALC880_LG_LW] = "lg-lw",
df99cd33 4657 [ALC880_MEDION_RIM] = "medion",
2fa522be 4658#ifdef CONFIG_SND_DEBUG
f5fcc13c 4659 [ALC880_TEST] = "test",
2fa522be 4660#endif
f5fcc13c
TI
4661 [ALC880_AUTO] = "auto",
4662};
4663
4664static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4665 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4666 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4667 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4668 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4669 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4670 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4671 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4672 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4673 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4674 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4675 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4676 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4677 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4678 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4679 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4680 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4681 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4682 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4683 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4684 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4685 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4686 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4687 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4688 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4689 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4690 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4691 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4692 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4693 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4694 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4695 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4696 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4697 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4698 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4699 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4700 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4701 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4702 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4703 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4704 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 4705 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
4706 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4707 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4708 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4709 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4710 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4711 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4712 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4713 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4714 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4715 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4716 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c 4717 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
77c4d5cd 4718 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
f5fcc13c 4719 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4720 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4721 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4722 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4723 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4724 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4725 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4726 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4727 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4728 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4729 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4730 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4731 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4732 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4733 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4734 /* default Intel */
4735 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4736 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4737 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4738 {}
4739};
4740
16ded525 4741/*
df694daa 4742 * ALC880 codec presets
16ded525 4743 */
16ded525
TI
4744static struct alc_config_preset alc880_presets[] = {
4745 [ALC880_3ST] = {
e9edcee0 4746 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4747 .init_verbs = { alc880_volume_init_verbs,
4748 alc880_pin_3stack_init_verbs },
16ded525 4749 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4750 .dac_nids = alc880_dac_nids,
16ded525
TI
4751 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4752 .channel_mode = alc880_threestack_modes,
4e195a7b 4753 .need_dac_fix = 1,
16ded525
TI
4754 .input_mux = &alc880_capture_source,
4755 },
4756 [ALC880_3ST_DIG] = {
e9edcee0 4757 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4758 .init_verbs = { alc880_volume_init_verbs,
4759 alc880_pin_3stack_init_verbs },
16ded525 4760 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4761 .dac_nids = alc880_dac_nids,
4762 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4763 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4764 .channel_mode = alc880_threestack_modes,
4e195a7b 4765 .need_dac_fix = 1,
16ded525
TI
4766 .input_mux = &alc880_capture_source,
4767 },
df694daa
KY
4768 [ALC880_TCL_S700] = {
4769 .mixers = { alc880_tcl_s700_mixer },
4770 .init_verbs = { alc880_volume_init_verbs,
4771 alc880_pin_tcl_S700_init_verbs,
4772 alc880_gpio2_init_verbs },
4773 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4774 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4775 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4776 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4777 .hp_nid = 0x03,
4778 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4779 .channel_mode = alc880_2_jack_modes,
4780 .input_mux = &alc880_capture_source,
4781 },
16ded525 4782 [ALC880_5ST] = {
f12ab1e0
TI
4783 .mixers = { alc880_three_stack_mixer,
4784 alc880_five_stack_mixer},
4785 .init_verbs = { alc880_volume_init_verbs,
4786 alc880_pin_5stack_init_verbs },
16ded525
TI
4787 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4788 .dac_nids = alc880_dac_nids,
16ded525
TI
4789 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4790 .channel_mode = alc880_fivestack_modes,
4791 .input_mux = &alc880_capture_source,
4792 },
4793 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4794 .mixers = { alc880_three_stack_mixer,
4795 alc880_five_stack_mixer },
4796 .init_verbs = { alc880_volume_init_verbs,
4797 alc880_pin_5stack_init_verbs },
16ded525
TI
4798 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4799 .dac_nids = alc880_dac_nids,
4800 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4801 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4802 .channel_mode = alc880_fivestack_modes,
4803 .input_mux = &alc880_capture_source,
4804 },
b6482d48
TI
4805 [ALC880_6ST] = {
4806 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4807 .init_verbs = { alc880_volume_init_verbs,
4808 alc880_pin_6stack_init_verbs },
b6482d48
TI
4809 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4810 .dac_nids = alc880_6st_dac_nids,
4811 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4812 .channel_mode = alc880_sixstack_modes,
4813 .input_mux = &alc880_6stack_capture_source,
4814 },
16ded525 4815 [ALC880_6ST_DIG] = {
e9edcee0 4816 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4817 .init_verbs = { alc880_volume_init_verbs,
4818 alc880_pin_6stack_init_verbs },
16ded525
TI
4819 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4820 .dac_nids = alc880_6st_dac_nids,
4821 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4822 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4823 .channel_mode = alc880_sixstack_modes,
4824 .input_mux = &alc880_6stack_capture_source,
4825 },
4826 [ALC880_W810] = {
e9edcee0 4827 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4828 .init_verbs = { alc880_volume_init_verbs,
4829 alc880_pin_w810_init_verbs,
b0af0de5 4830 alc880_gpio2_init_verbs },
16ded525
TI
4831 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4832 .dac_nids = alc880_w810_dac_nids,
4833 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4834 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4835 .channel_mode = alc880_w810_modes,
4836 .input_mux = &alc880_capture_source,
4837 },
4838 [ALC880_Z71V] = {
e9edcee0 4839 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
4840 .init_verbs = { alc880_volume_init_verbs,
4841 alc880_pin_z71v_init_verbs },
16ded525
TI
4842 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4843 .dac_nids = alc880_z71v_dac_nids,
4844 .dig_out_nid = ALC880_DIGOUT_NID,
4845 .hp_nid = 0x03,
e9edcee0
TI
4846 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4847 .channel_mode = alc880_2_jack_modes,
16ded525
TI
4848 .input_mux = &alc880_capture_source,
4849 },
4850 [ALC880_F1734] = {
e9edcee0 4851 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
4852 .init_verbs = { alc880_volume_init_verbs,
4853 alc880_pin_f1734_init_verbs },
e9edcee0
TI
4854 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4855 .dac_nids = alc880_f1734_dac_nids,
4856 .hp_nid = 0x02,
4857 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4858 .channel_mode = alc880_2_jack_modes,
937b4160
TI
4859 .input_mux = &alc880_f1734_capture_source,
4860 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4861 .setup = alc880_uniwill_p53_setup,
4862 .init_hook = alc_automute_amp,
16ded525
TI
4863 },
4864 [ALC880_ASUS] = {
e9edcee0 4865 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4866 .init_verbs = { alc880_volume_init_verbs,
4867 alc880_pin_asus_init_verbs,
e9edcee0
TI
4868 alc880_gpio1_init_verbs },
4869 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4870 .dac_nids = alc880_asus_dac_nids,
4871 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4872 .channel_mode = alc880_asus_modes,
4e195a7b 4873 .need_dac_fix = 1,
16ded525
TI
4874 .input_mux = &alc880_capture_source,
4875 },
4876 [ALC880_ASUS_DIG] = {
e9edcee0 4877 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4878 .init_verbs = { alc880_volume_init_verbs,
4879 alc880_pin_asus_init_verbs,
e9edcee0
TI
4880 alc880_gpio1_init_verbs },
4881 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4882 .dac_nids = alc880_asus_dac_nids,
16ded525 4883 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4884 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4885 .channel_mode = alc880_asus_modes,
4e195a7b 4886 .need_dac_fix = 1,
16ded525
TI
4887 .input_mux = &alc880_capture_source,
4888 },
df694daa
KY
4889 [ALC880_ASUS_DIG2] = {
4890 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4891 .init_verbs = { alc880_volume_init_verbs,
4892 alc880_pin_asus_init_verbs,
df694daa
KY
4893 alc880_gpio2_init_verbs }, /* use GPIO2 */
4894 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4895 .dac_nids = alc880_asus_dac_nids,
4896 .dig_out_nid = ALC880_DIGOUT_NID,
4897 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4898 .channel_mode = alc880_asus_modes,
4e195a7b 4899 .need_dac_fix = 1,
df694daa
KY
4900 .input_mux = &alc880_capture_source,
4901 },
16ded525 4902 [ALC880_ASUS_W1V] = {
e9edcee0 4903 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
4904 .init_verbs = { alc880_volume_init_verbs,
4905 alc880_pin_asus_init_verbs,
e9edcee0
TI
4906 alc880_gpio1_init_verbs },
4907 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4908 .dac_nids = alc880_asus_dac_nids,
16ded525 4909 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4910 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4911 .channel_mode = alc880_asus_modes,
4e195a7b 4912 .need_dac_fix = 1,
16ded525
TI
4913 .input_mux = &alc880_capture_source,
4914 },
4915 [ALC880_UNIWILL_DIG] = {
45bdd1c1 4916 .mixers = { alc880_asus_mixer },
ccc656ce
KY
4917 .init_verbs = { alc880_volume_init_verbs,
4918 alc880_pin_asus_init_verbs },
e9edcee0
TI
4919 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4920 .dac_nids = alc880_asus_dac_nids,
16ded525 4921 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4922 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4923 .channel_mode = alc880_asus_modes,
4e195a7b 4924 .need_dac_fix = 1,
16ded525
TI
4925 .input_mux = &alc880_capture_source,
4926 },
ccc656ce
KY
4927 [ALC880_UNIWILL] = {
4928 .mixers = { alc880_uniwill_mixer },
4929 .init_verbs = { alc880_volume_init_verbs,
4930 alc880_uniwill_init_verbs },
4931 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4932 .dac_nids = alc880_asus_dac_nids,
4933 .dig_out_nid = ALC880_DIGOUT_NID,
4934 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4935 .channel_mode = alc880_threestack_modes,
4936 .need_dac_fix = 1,
4937 .input_mux = &alc880_capture_source,
4938 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 4939 .setup = alc880_uniwill_setup,
a9fd4f3f 4940 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
4941 },
4942 [ALC880_UNIWILL_P53] = {
4943 .mixers = { alc880_uniwill_p53_mixer },
4944 .init_verbs = { alc880_volume_init_verbs,
4945 alc880_uniwill_p53_init_verbs },
4946 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4947 .dac_nids = alc880_asus_dac_nids,
4948 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4949 .channel_mode = alc880_threestack_modes,
4950 .input_mux = &alc880_capture_source,
4951 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4952 .setup = alc880_uniwill_p53_setup,
4953 .init_hook = alc_automute_amp,
2cf9f0fc
TD
4954 },
4955 [ALC880_FUJITSU] = {
45bdd1c1 4956 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4957 .init_verbs = { alc880_volume_init_verbs,
4958 alc880_uniwill_p53_init_verbs,
4959 alc880_beep_init_verbs },
4960 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4961 .dac_nids = alc880_dac_nids,
d53d7d9e 4962 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4963 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4964 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4965 .input_mux = &alc880_capture_source,
4966 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4967 .setup = alc880_uniwill_p53_setup,
4968 .init_hook = alc_automute_amp,
ccc656ce 4969 },
df694daa
KY
4970 [ALC880_CLEVO] = {
4971 .mixers = { alc880_three_stack_mixer },
4972 .init_verbs = { alc880_volume_init_verbs,
4973 alc880_pin_clevo_init_verbs },
4974 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4975 .dac_nids = alc880_dac_nids,
4976 .hp_nid = 0x03,
4977 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4978 .channel_mode = alc880_threestack_modes,
4e195a7b 4979 .need_dac_fix = 1,
df694daa
KY
4980 .input_mux = &alc880_capture_source,
4981 },
ae6b813a
TI
4982 [ALC880_LG] = {
4983 .mixers = { alc880_lg_mixer },
4984 .init_verbs = { alc880_volume_init_verbs,
4985 alc880_lg_init_verbs },
4986 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4987 .dac_nids = alc880_lg_dac_nids,
4988 .dig_out_nid = ALC880_DIGOUT_NID,
4989 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4990 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4991 .need_dac_fix = 1,
ae6b813a 4992 .input_mux = &alc880_lg_capture_source,
a9fd4f3f 4993 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4994 .setup = alc880_lg_setup,
4995 .init_hook = alc_automute_amp,
cb53c626
TI
4996#ifdef CONFIG_SND_HDA_POWER_SAVE
4997 .loopbacks = alc880_lg_loopbacks,
4998#endif
ae6b813a 4999 },
d681518a
TI
5000 [ALC880_LG_LW] = {
5001 .mixers = { alc880_lg_lw_mixer },
5002 .init_verbs = { alc880_volume_init_verbs,
5003 alc880_lg_lw_init_verbs },
0a8c5da3 5004 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
5005 .dac_nids = alc880_dac_nids,
5006 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
5007 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5008 .channel_mode = alc880_lg_lw_modes,
d681518a 5009 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f 5010 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
5011 .setup = alc880_lg_lw_setup,
5012 .init_hook = alc_automute_amp,
d681518a 5013 },
df99cd33
TI
5014 [ALC880_MEDION_RIM] = {
5015 .mixers = { alc880_medion_rim_mixer },
5016 .init_verbs = { alc880_volume_init_verbs,
5017 alc880_medion_rim_init_verbs,
5018 alc_gpio2_init_verbs },
5019 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5020 .dac_nids = alc880_dac_nids,
5021 .dig_out_nid = ALC880_DIGOUT_NID,
5022 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5023 .channel_mode = alc880_2_jack_modes,
5024 .input_mux = &alc880_medion_rim_capture_source,
5025 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
5026 .setup = alc880_medion_rim_setup,
5027 .init_hook = alc880_medion_rim_automute,
df99cd33 5028 },
16ded525
TI
5029#ifdef CONFIG_SND_DEBUG
5030 [ALC880_TEST] = {
e9edcee0
TI
5031 .mixers = { alc880_test_mixer },
5032 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
5033 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5034 .dac_nids = alc880_test_dac_nids,
5035 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5036 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5037 .channel_mode = alc880_test_modes,
5038 .input_mux = &alc880_test_capture_source,
5039 },
5040#endif
5041};
5042
e9edcee0
TI
5043/*
5044 * Automatic parse of I/O pins from the BIOS configuration
5045 */
5046
e9edcee0
TI
5047enum {
5048 ALC_CTL_WIDGET_VOL,
5049 ALC_CTL_WIDGET_MUTE,
5050 ALC_CTL_BIND_MUTE,
5051};
c8b6bf9b 5052static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
5053 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5054 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 5055 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
5056};
5057
5058/* add dynamic controls */
f12ab1e0 5059static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 5060 int cidx, unsigned long val)
e9edcee0 5061{
c8b6bf9b 5062 struct snd_kcontrol_new *knew;
e9edcee0 5063
603c4019
TI
5064 snd_array_init(&spec->kctls, sizeof(*knew), 32);
5065 knew = snd_array_new(&spec->kctls);
5066 if (!knew)
5067 return -ENOMEM;
e9edcee0 5068 *knew = alc880_control_templates[type];
543537bd 5069 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 5070 if (!knew->name)
e9edcee0 5071 return -ENOMEM;
66ceeb6b 5072 knew->index = cidx;
4d02d1b6 5073 if (get_amp_nid_(val))
5e26dfd0 5074 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 5075 knew->private_value = val;
e9edcee0
TI
5076 return 0;
5077}
5078
0afe5f89
TI
5079static int add_control_with_pfx(struct alc_spec *spec, int type,
5080 const char *pfx, const char *dir,
66ceeb6b 5081 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
5082{
5083 char name[32];
5084 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 5085 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
5086}
5087
66ceeb6b
TI
5088#define add_pb_vol_ctrl(spec, type, pfx, val) \
5089 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5090#define add_pb_sw_ctrl(spec, type, pfx, val) \
5091 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5092#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5093 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5094#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5095 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 5096
e9edcee0
TI
5097#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5098#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5099#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5100#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
5101#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5102#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5103#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5104#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5105#define ALC880_PIN_CD_NID 0x1c
5106
5107/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
5108static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5109 const struct auto_pin_cfg *cfg)
e9edcee0
TI
5110{
5111 hda_nid_t nid;
5112 int assigned[4];
5113 int i, j;
5114
5115 memset(assigned, 0, sizeof(assigned));
b0af0de5 5116 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
5117
5118 /* check the pins hardwired to audio widget */
5119 for (i = 0; i < cfg->line_outs; i++) {
5120 nid = cfg->line_out_pins[i];
5121 if (alc880_is_fixed_pin(nid)) {
5122 int idx = alc880_fixed_pin_idx(nid);
5014f193 5123 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
5124 assigned[idx] = 1;
5125 }
5126 }
5127 /* left pins can be connect to any audio widget */
5128 for (i = 0; i < cfg->line_outs; i++) {
5129 nid = cfg->line_out_pins[i];
5130 if (alc880_is_fixed_pin(nid))
5131 continue;
5132 /* search for an empty channel */
5133 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
5134 if (!assigned[j]) {
5135 spec->multiout.dac_nids[i] =
5136 alc880_idx_to_dac(j);
e9edcee0
TI
5137 assigned[j] = 1;
5138 break;
5139 }
5140 }
5141 }
5142 spec->multiout.num_dacs = cfg->line_outs;
5143 return 0;
5144}
5145
bcb2f0f5
TI
5146static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg,
5147 bool can_be_master)
5148{
5149 if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5150 return "Master";
5151
5152 switch (cfg->line_out_type) {
5153 case AUTO_PIN_SPEAKER_OUT:
5154 return "Speaker";
5155 case AUTO_PIN_HP_OUT:
5156 return "Headphone";
5157 default:
5158 if (cfg->line_outs == 1)
5159 return "PCM";
5160 break;
5161 }
5162 return NULL;
5163}
5164
e9edcee0 5165/* add playback controls from the parsed DAC table */
df694daa
KY
5166static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5167 const struct auto_pin_cfg *cfg)
e9edcee0 5168{
ea734963 5169 static const char * const chname[4] = {
f12ab1e0
TI
5170 "Front", "Surround", NULL /*CLFE*/, "Side"
5171 };
bcb2f0f5 5172 const char *pfx = alc_get_line_out_pfx(cfg, false);
e9edcee0
TI
5173 hda_nid_t nid;
5174 int i, err;
5175
5176 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 5177 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
5178 continue;
5179 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
bcb2f0f5 5180 if (!pfx && i == 2) {
e9edcee0 5181 /* Center/LFE */
0afe5f89
TI
5182 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5183 "Center",
f12ab1e0
TI
5184 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5185 HDA_OUTPUT));
5186 if (err < 0)
e9edcee0 5187 return err;
0afe5f89
TI
5188 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5189 "LFE",
f12ab1e0
TI
5190 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5191 HDA_OUTPUT));
5192 if (err < 0)
e9edcee0 5193 return err;
0afe5f89
TI
5194 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5195 "Center",
f12ab1e0
TI
5196 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5197 HDA_INPUT));
5198 if (err < 0)
e9edcee0 5199 return err;
0afe5f89
TI
5200 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5201 "LFE",
f12ab1e0
TI
5202 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5203 HDA_INPUT));
5204 if (err < 0)
e9edcee0
TI
5205 return err;
5206 } else {
bcb2f0f5
TI
5207 const char *name = pfx;
5208 if (!name)
5209 name = chname[i];
5210 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5211 name, i,
f12ab1e0
TI
5212 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5213 HDA_OUTPUT));
5214 if (err < 0)
e9edcee0 5215 return err;
bcb2f0f5
TI
5216 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5217 name, i,
f12ab1e0
TI
5218 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5219 HDA_INPUT));
5220 if (err < 0)
e9edcee0
TI
5221 return err;
5222 }
5223 }
e9edcee0
TI
5224 return 0;
5225}
5226
8d88bc3d
TI
5227/* add playback controls for speaker and HP outputs */
5228static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5229 const char *pfx)
e9edcee0
TI
5230{
5231 hda_nid_t nid;
5232 int err;
5233
f12ab1e0 5234 if (!pin)
e9edcee0
TI
5235 return 0;
5236
5237 if (alc880_is_fixed_pin(pin)) {
5238 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5239 /* specify the DAC as the extra output */
f12ab1e0 5240 if (!spec->multiout.hp_nid)
e9edcee0 5241 spec->multiout.hp_nid = nid;
82bc955f
TI
5242 else
5243 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5244 /* control HP volume/switch on the output mixer amp */
5245 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5246 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5247 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5248 if (err < 0)
e9edcee0 5249 return err;
0afe5f89 5250 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5251 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5252 if (err < 0)
e9edcee0
TI
5253 return err;
5254 } else if (alc880_is_multi_pin(pin)) {
5255 /* set manual connection */
e9edcee0 5256 /* we have only a switch on HP-out PIN */
0afe5f89 5257 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5258 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5259 if (err < 0)
e9edcee0
TI
5260 return err;
5261 }
5262 return 0;
5263}
5264
5265/* create input playback/capture controls for the given pin */
f12ab1e0 5266static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5267 const char *ctlname, int ctlidx,
df694daa 5268 int idx, hda_nid_t mix_nid)
e9edcee0 5269{
df694daa 5270 int err;
e9edcee0 5271
66ceeb6b 5272 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5273 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5274 if (err < 0)
e9edcee0 5275 return err;
66ceeb6b 5276 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5277 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5278 if (err < 0)
e9edcee0
TI
5279 return err;
5280 return 0;
5281}
5282
05f5f477
TI
5283static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5284{
5285 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5286 return (pincap & AC_PINCAP_IN) != 0;
5287}
5288
e9edcee0 5289/* create playback/capture controls for input pins */
05f5f477
TI
5290static int alc_auto_create_input_ctls(struct hda_codec *codec,
5291 const struct auto_pin_cfg *cfg,
5292 hda_nid_t mixer,
5293 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5294{
05f5f477 5295 struct alc_spec *spec = codec->spec;
61b9b9b1 5296 struct hda_input_mux *imux = &spec->private_imux[0];
5322bf27
DH
5297 int i, err, idx, type_idx = 0;
5298 const char *prev_label = NULL;
e9edcee0 5299
66ceeb6b 5300 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5301 hda_nid_t pin;
10a20af7 5302 const char *label;
05f5f477 5303
66ceeb6b 5304 pin = cfg->inputs[i].pin;
05f5f477
TI
5305 if (!alc_is_input_pin(codec, pin))
5306 continue;
5307
5322bf27
DH
5308 label = hda_get_autocfg_input_label(codec, cfg, i);
5309 if (prev_label && !strcmp(label, prev_label))
66ceeb6b
TI
5310 type_idx++;
5311 else
5312 type_idx = 0;
5322bf27
DH
5313 prev_label = label;
5314
05f5f477
TI
5315 if (mixer) {
5316 idx = get_connection_index(codec, mixer, pin);
5317 if (idx >= 0) {
5318 err = new_analog_input(spec, pin,
10a20af7
TI
5319 label, type_idx,
5320 idx, mixer);
05f5f477
TI
5321 if (err < 0)
5322 return err;
5323 }
5324 }
5325
5326 if (!cap1)
5327 continue;
5328 idx = get_connection_index(codec, cap1, pin);
5329 if (idx < 0 && cap2)
5330 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5331 if (idx >= 0)
5332 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5333 }
5334 return 0;
5335}
5336
05f5f477
TI
5337static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5338 const struct auto_pin_cfg *cfg)
5339{
5340 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5341}
5342
f6c7e546
TI
5343static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5344 unsigned int pin_type)
5345{
5346 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5347 pin_type);
5348 /* unmute pin */
d260cdf6
TI
5349 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5350 AMP_OUT_UNMUTE);
f6c7e546
TI
5351}
5352
df694daa
KY
5353static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5354 hda_nid_t nid, int pin_type,
e9edcee0
TI
5355 int dac_idx)
5356{
f6c7e546 5357 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5358 /* need the manual connection? */
5359 if (alc880_is_multi_pin(nid)) {
5360 struct alc_spec *spec = codec->spec;
5361 int idx = alc880_multi_pin_idx(nid);
5362 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5363 AC_VERB_SET_CONNECT_SEL,
5364 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5365 }
5366}
5367
baba8ee9
TI
5368static int get_pin_type(int line_out_type)
5369{
5370 if (line_out_type == AUTO_PIN_HP_OUT)
5371 return PIN_HP;
5372 else
5373 return PIN_OUT;
5374}
5375
e9edcee0
TI
5376static void alc880_auto_init_multi_out(struct hda_codec *codec)
5377{
5378 struct alc_spec *spec = codec->spec;
5379 int i;
ea1fb29a 5380
e9edcee0
TI
5381 for (i = 0; i < spec->autocfg.line_outs; i++) {
5382 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5383 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5384 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5385 }
5386}
5387
8d88bc3d 5388static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5389{
5390 struct alc_spec *spec = codec->spec;
5391 hda_nid_t pin;
5392
82bc955f 5393 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5394 if (pin) /* connect to front */
5395 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5396 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5397 if (pin) /* connect to front */
5398 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5399}
5400
5401static void alc880_auto_init_analog_input(struct hda_codec *codec)
5402{
5403 struct alc_spec *spec = codec->spec;
66ceeb6b 5404 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5405 int i;
5406
66ceeb6b
TI
5407 for (i = 0; i < cfg->num_inputs; i++) {
5408 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5409 if (alc_is_input_pin(codec, nid)) {
30ea098f 5410 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
5411 if (nid != ALC880_PIN_CD_NID &&
5412 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5413 snd_hda_codec_write(codec, nid, 0,
5414 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5415 AMP_OUT_MUTE);
5416 }
5417 }
5418}
5419
7f311a46
TI
5420static void alc880_auto_init_input_src(struct hda_codec *codec)
5421{
5422 struct alc_spec *spec = codec->spec;
5423 int c;
5424
5425 for (c = 0; c < spec->num_adc_nids; c++) {
5426 unsigned int mux_idx;
5427 const struct hda_input_mux *imux;
5428 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5429 imux = &spec->input_mux[mux_idx];
5430 if (!imux->num_items && mux_idx > 0)
5431 imux = &spec->input_mux[0];
5432 if (imux)
5433 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5434 AC_VERB_SET_CONNECT_SEL,
5435 imux->items[0].index);
5436 }
5437}
5438
e9edcee0 5439/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5440/* return 1 if successful, 0 if the proper config is not found,
5441 * or a negative error code
5442 */
e9edcee0
TI
5443static int alc880_parse_auto_config(struct hda_codec *codec)
5444{
5445 struct alc_spec *spec = codec->spec;
757899ac 5446 int err;
df694daa 5447 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5448
f12ab1e0
TI
5449 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5450 alc880_ignore);
5451 if (err < 0)
e9edcee0 5452 return err;
f12ab1e0 5453 if (!spec->autocfg.line_outs)
e9edcee0 5454 return 0; /* can't find valid BIOS pin config */
df694daa 5455
f12ab1e0
TI
5456 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5457 if (err < 0)
5458 return err;
5459 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5460 if (err < 0)
5461 return err;
5462 err = alc880_auto_create_extra_out(spec,
5463 spec->autocfg.speaker_pins[0],
5464 "Speaker");
5465 if (err < 0)
5466 return err;
5467 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5468 "Headphone");
5469 if (err < 0)
5470 return err;
05f5f477 5471 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5472 if (err < 0)
e9edcee0
TI
5473 return err;
5474
5475 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5476
757899ac 5477 alc_auto_parse_digital(codec);
e9edcee0 5478
603c4019 5479 if (spec->kctls.list)
d88897ea 5480 add_mixer(spec, spec->kctls.list);
e9edcee0 5481
d88897ea 5482 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5483
a1e8d2da 5484 spec->num_mux_defs = 1;
61b9b9b1 5485 spec->input_mux = &spec->private_imux[0];
e9edcee0 5486
6227cdce 5487 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5488
e9edcee0
TI
5489 return 1;
5490}
5491
ae6b813a
TI
5492/* additional initialization for auto-configuration model */
5493static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5494{
f6c7e546 5495 struct alc_spec *spec = codec->spec;
e9edcee0 5496 alc880_auto_init_multi_out(codec);
8d88bc3d 5497 alc880_auto_init_extra_out(codec);
e9edcee0 5498 alc880_auto_init_analog_input(codec);
7f311a46 5499 alc880_auto_init_input_src(codec);
757899ac 5500 alc_auto_init_digital(codec);
f6c7e546 5501 if (spec->unsol_event)
7fb0d78f 5502 alc_inithook(codec);
e9edcee0
TI
5503}
5504
b59bdf3b
TI
5505/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5506 * one of two digital mic pins, e.g. on ALC272
5507 */
5508static void fixup_automic_adc(struct hda_codec *codec)
5509{
5510 struct alc_spec *spec = codec->spec;
5511 int i;
5512
5513 for (i = 0; i < spec->num_adc_nids; i++) {
5514 hda_nid_t cap = spec->capsrc_nids ?
5515 spec->capsrc_nids[i] : spec->adc_nids[i];
5516 int iidx, eidx;
5517
5518 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5519 if (iidx < 0)
5520 continue;
5521 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5522 if (eidx < 0)
5523 continue;
5524 spec->int_mic.mux_idx = iidx;
5525 spec->ext_mic.mux_idx = eidx;
5526 if (spec->capsrc_nids)
5527 spec->capsrc_nids += i;
5528 spec->adc_nids += i;
5529 spec->num_adc_nids = 1;
5530 return;
5531 }
5532 snd_printd(KERN_INFO "hda_codec: %s: "
5533 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5534 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5535 spec->auto_mic = 0; /* disable auto-mic to be sure */
5536}
5537
748cce43
TI
5538/* select or unmute the given capsrc route */
5539static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5540 int idx)
5541{
5542 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5543 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5544 HDA_AMP_MUTE, 0);
5545 } else {
5546 snd_hda_codec_write_cache(codec, cap, 0,
5547 AC_VERB_SET_CONNECT_SEL, idx);
5548 }
5549}
5550
840b64c0
TI
5551/* set the default connection to that pin */
5552static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5553{
5554 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5555 int i;
5556
eaa9b3a7
TI
5557 for (i = 0; i < spec->num_adc_nids; i++) {
5558 hda_nid_t cap = spec->capsrc_nids ?
5559 spec->capsrc_nids[i] : spec->adc_nids[i];
5560 int idx;
5561
5562 idx = get_connection_index(codec, cap, pin);
5563 if (idx < 0)
5564 continue;
748cce43 5565 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5566 return i; /* return the found index */
5567 }
5568 return -1; /* not found */
5569}
5570
5571/* choose the ADC/MUX containing the input pin and initialize the setup */
5572static void fixup_single_adc(struct hda_codec *codec)
5573{
5574 struct alc_spec *spec = codec->spec;
66ceeb6b 5575 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5576 int i;
5577
5578 /* search for the input pin; there must be only one */
66ceeb6b 5579 if (cfg->num_inputs != 1)
eaa9b3a7 5580 return;
66ceeb6b 5581 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5582 if (i >= 0) {
5583 /* use only this ADC */
5584 if (spec->capsrc_nids)
5585 spec->capsrc_nids += i;
5586 spec->adc_nids += i;
5587 spec->num_adc_nids = 1;
eaa9b3a7
TI
5588 }
5589}
5590
840b64c0
TI
5591/* initialize dual adcs */
5592static void fixup_dual_adc_switch(struct hda_codec *codec)
5593{
5594 struct alc_spec *spec = codec->spec;
5595 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5596 init_capsrc_for_pin(codec, spec->int_mic.pin);
5597}
5598
b59bdf3b 5599static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5600{
b59bdf3b 5601 struct alc_spec *spec = codec->spec;
a23b688f
TI
5602 static struct snd_kcontrol_new *caps[2][3] = {
5603 { alc_capture_mixer_nosrc1,
5604 alc_capture_mixer_nosrc2,
5605 alc_capture_mixer_nosrc3 },
5606 { alc_capture_mixer1,
5607 alc_capture_mixer2,
5608 alc_capture_mixer3 },
f9e336f6 5609 };
a23b688f 5610 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5611 int mux = 0;
840b64c0
TI
5612 int num_adcs = spec->num_adc_nids;
5613 if (spec->dual_adc_switch)
5614 fixup_dual_adc_switch(codec);
5615 else if (spec->auto_mic)
b59bdf3b 5616 fixup_automic_adc(codec);
eaa9b3a7
TI
5617 else if (spec->input_mux) {
5618 if (spec->input_mux->num_items > 1)
5619 mux = 1;
5620 else if (spec->input_mux->num_items == 1)
5621 fixup_single_adc(codec);
5622 }
840b64c0
TI
5623 if (spec->dual_adc_switch)
5624 num_adcs = 1;
5625 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5626 }
f9e336f6
TI
5627}
5628
6694635d
TI
5629/* fill adc_nids (and capsrc_nids) containing all active input pins */
5630static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5631 int num_nids)
5632{
5633 struct alc_spec *spec = codec->spec;
66ceeb6b 5634 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5635 int n;
5636 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5637
5638 for (n = 0; n < num_nids; n++) {
5639 hda_nid_t adc, cap;
5640 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5641 int nconns, i, j;
5642
5643 adc = nids[n];
5644 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5645 continue;
5646 cap = adc;
5647 nconns = snd_hda_get_connections(codec, cap, conn,
5648 ARRAY_SIZE(conn));
5649 if (nconns == 1) {
5650 cap = conn[0];
5651 nconns = snd_hda_get_connections(codec, cap, conn,
5652 ARRAY_SIZE(conn));
5653 }
5654 if (nconns <= 0)
5655 continue;
5656 if (!fallback_adc) {
5657 fallback_adc = adc;
5658 fallback_cap = cap;
5659 }
66ceeb6b
TI
5660 for (i = 0; i < cfg->num_inputs; i++) {
5661 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5662 for (j = 0; j < nconns; j++) {
5663 if (conn[j] == nid)
5664 break;
5665 }
5666 if (j >= nconns)
5667 break;
5668 }
66ceeb6b 5669 if (i >= cfg->num_inputs) {
6694635d
TI
5670 int num_adcs = spec->num_adc_nids;
5671 spec->private_adc_nids[num_adcs] = adc;
5672 spec->private_capsrc_nids[num_adcs] = cap;
5673 spec->num_adc_nids++;
5674 spec->adc_nids = spec->private_adc_nids;
5675 if (adc != cap)
5676 spec->capsrc_nids = spec->private_capsrc_nids;
5677 }
5678 }
5679 if (!spec->num_adc_nids) {
5680 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5681 " using fallback 0x%x\n",
5682 codec->chip_name, fallback_adc);
6694635d
TI
5683 spec->private_adc_nids[0] = fallback_adc;
5684 spec->adc_nids = spec->private_adc_nids;
5685 if (fallback_adc != fallback_cap) {
5686 spec->private_capsrc_nids[0] = fallback_cap;
5687 spec->capsrc_nids = spec->private_adc_nids;
5688 }
5689 }
5690}
5691
67d634c0 5692#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5693#define set_beep_amp(spec, nid, idx, dir) \
5694 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25
TI
5695
5696static struct snd_pci_quirk beep_white_list[] = {
5697 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5698 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
e096c8e6 5699 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5700 {}
5701};
5702
5703static inline int has_cdefine_beep(struct hda_codec *codec)
5704{
5705 struct alc_spec *spec = codec->spec;
5706 const struct snd_pci_quirk *q;
5707 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5708 if (q)
5709 return q->value;
5710 return spec->cdefine.enable_pcbeep;
5711}
67d634c0
TI
5712#else
5713#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5714#define has_cdefine_beep(codec) 0
67d634c0 5715#endif
45bdd1c1
TI
5716
5717/*
5718 * OK, here we have finally the patch for ALC880
5719 */
5720
1da177e4
LT
5721static int patch_alc880(struct hda_codec *codec)
5722{
5723 struct alc_spec *spec;
5724 int board_config;
df694daa 5725 int err;
1da177e4 5726
e560d8d8 5727 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5728 if (spec == NULL)
5729 return -ENOMEM;
5730
5731 codec->spec = spec;
5732
f5fcc13c
TI
5733 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5734 alc880_models,
5735 alc880_cfg_tbl);
5736 if (board_config < 0) {
9a11f1aa
TI
5737 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5738 codec->chip_name);
e9edcee0 5739 board_config = ALC880_AUTO;
1da177e4 5740 }
1da177e4 5741
e9edcee0
TI
5742 if (board_config == ALC880_AUTO) {
5743 /* automatic parse from the BIOS config */
5744 err = alc880_parse_auto_config(codec);
5745 if (err < 0) {
5746 alc_free(codec);
5747 return err;
f12ab1e0 5748 } else if (!err) {
9c7f852e
TI
5749 printk(KERN_INFO
5750 "hda_codec: Cannot set up configuration "
5751 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5752 board_config = ALC880_3ST;
5753 }
1da177e4
LT
5754 }
5755
680cd536
KK
5756 err = snd_hda_attach_beep_device(codec, 0x1);
5757 if (err < 0) {
5758 alc_free(codec);
5759 return err;
5760 }
5761
df694daa 5762 if (board_config != ALC880_AUTO)
e9c364c0 5763 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5764
1da177e4
LT
5765 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5766 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5767 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5768
1da177e4
LT
5769 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5770 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5771
f12ab1e0 5772 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5773 /* check whether NID 0x07 is valid */
54d17403 5774 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5775 /* get type */
a22d543a 5776 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5777 if (wcap != AC_WID_AUD_IN) {
5778 spec->adc_nids = alc880_adc_nids_alt;
5779 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5780 } else {
5781 spec->adc_nids = alc880_adc_nids;
5782 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5783 }
5784 }
b59bdf3b 5785 set_capture_mixer(codec);
45bdd1c1 5786 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5787
2134ea4f
TI
5788 spec->vmaster_nid = 0x0c;
5789
1da177e4 5790 codec->patch_ops = alc_patch_ops;
e9edcee0 5791 if (board_config == ALC880_AUTO)
ae6b813a 5792 spec->init_hook = alc880_auto_init;
cb53c626
TI
5793#ifdef CONFIG_SND_HDA_POWER_SAVE
5794 if (!spec->loopback.amplist)
5795 spec->loopback.amplist = alc880_loopbacks;
5796#endif
1da177e4
LT
5797
5798 return 0;
5799}
5800
e9edcee0 5801
1da177e4
LT
5802/*
5803 * ALC260 support
5804 */
5805
e9edcee0
TI
5806static hda_nid_t alc260_dac_nids[1] = {
5807 /* front */
5808 0x02,
5809};
5810
5811static hda_nid_t alc260_adc_nids[1] = {
5812 /* ADC0 */
5813 0x04,
5814};
5815
df694daa 5816static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5817 /* ADC1 */
5818 0x05,
5819};
5820
d57fdac0
JW
5821/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5822 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5823 */
5824static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5825 /* ADC0, ADC1 */
5826 0x04, 0x05
5827};
5828
e9edcee0
TI
5829#define ALC260_DIGOUT_NID 0x03
5830#define ALC260_DIGIN_NID 0x06
5831
5832static struct hda_input_mux alc260_capture_source = {
5833 .num_items = 4,
5834 .items = {
5835 { "Mic", 0x0 },
5836 { "Front Mic", 0x1 },
5837 { "Line", 0x2 },
5838 { "CD", 0x4 },
5839 },
5840};
5841
17e7aec6 5842/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5843 * headphone jack and the internal CD lines since these are the only pins at
5844 * which audio can appear. For flexibility, also allow the option of
5845 * recording the mixer output on the second ADC (ADC0 doesn't have a
5846 * connection to the mixer output).
a9430dd8 5847 */
a1e8d2da
JW
5848static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5849 {
5850 .num_items = 3,
5851 .items = {
5852 { "Mic/Line", 0x0 },
5853 { "CD", 0x4 },
5854 { "Headphone", 0x2 },
5855 },
a9430dd8 5856 },
a1e8d2da
JW
5857 {
5858 .num_items = 4,
5859 .items = {
5860 { "Mic/Line", 0x0 },
5861 { "CD", 0x4 },
5862 { "Headphone", 0x2 },
5863 { "Mixer", 0x5 },
5864 },
5865 },
5866
a9430dd8
JW
5867};
5868
a1e8d2da
JW
5869/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5870 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5871 */
a1e8d2da
JW
5872static struct hda_input_mux alc260_acer_capture_sources[2] = {
5873 {
5874 .num_items = 4,
5875 .items = {
5876 { "Mic", 0x0 },
5877 { "Line", 0x2 },
5878 { "CD", 0x4 },
5879 { "Headphone", 0x5 },
5880 },
5881 },
5882 {
5883 .num_items = 5,
5884 .items = {
5885 { "Mic", 0x0 },
5886 { "Line", 0x2 },
5887 { "CD", 0x4 },
5888 { "Headphone", 0x6 },
5889 { "Mixer", 0x5 },
5890 },
0bfc90e9
JW
5891 },
5892};
cc959489
MS
5893
5894/* Maxdata Favorit 100XS */
5895static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5896 {
5897 .num_items = 2,
5898 .items = {
5899 { "Line/Mic", 0x0 },
5900 { "CD", 0x4 },
5901 },
5902 },
5903 {
5904 .num_items = 3,
5905 .items = {
5906 { "Line/Mic", 0x0 },
5907 { "CD", 0x4 },
5908 { "Mixer", 0x5 },
5909 },
5910 },
5911};
5912
1da177e4
LT
5913/*
5914 * This is just place-holder, so there's something for alc_build_pcms to look
5915 * at when it calculates the maximum number of channels. ALC260 has no mixer
5916 * element which allows changing the channel mode, so the verb list is
5917 * never used.
5918 */
d2a6d7dc 5919static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5920 { 2, NULL },
5921};
5922
df694daa
KY
5923
5924/* Mixer combinations
5925 *
5926 * basic: base_output + input + pc_beep + capture
5927 * HP: base_output + input + capture_alt
5928 * HP_3013: hp_3013 + input + capture
5929 * fujitsu: fujitsu + capture
0bfc90e9 5930 * acer: acer + capture
df694daa
KY
5931 */
5932
5933static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5934 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5935 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5936 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5937 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5938 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5939 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5940 { } /* end */
f12ab1e0 5941};
1da177e4 5942
df694daa 5943static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5944 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5945 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5946 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5947 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5948 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5949 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5950 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5951 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5952 { } /* end */
5953};
5954
bec15c3a
TI
5955/* update HP, line and mono out pins according to the master switch */
5956static void alc260_hp_master_update(struct hda_codec *codec,
5957 hda_nid_t hp, hda_nid_t line,
5958 hda_nid_t mono)
5959{
5960 struct alc_spec *spec = codec->spec;
5961 unsigned int val = spec->master_sw ? PIN_HP : 0;
5962 /* change HP and line-out pins */
30cde0aa 5963 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5964 val);
30cde0aa 5965 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5966 val);
5967 /* mono (speaker) depending on the HP jack sense */
5968 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5969 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5970 val);
5971}
5972
5973static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5974 struct snd_ctl_elem_value *ucontrol)
5975{
5976 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5977 struct alc_spec *spec = codec->spec;
5978 *ucontrol->value.integer.value = spec->master_sw;
5979 return 0;
5980}
5981
5982static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5983 struct snd_ctl_elem_value *ucontrol)
5984{
5985 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5986 struct alc_spec *spec = codec->spec;
5987 int val = !!*ucontrol->value.integer.value;
5988 hda_nid_t hp, line, mono;
5989
5990 if (val == spec->master_sw)
5991 return 0;
5992 spec->master_sw = val;
5993 hp = (kcontrol->private_value >> 16) & 0xff;
5994 line = (kcontrol->private_value >> 8) & 0xff;
5995 mono = kcontrol->private_value & 0xff;
5996 alc260_hp_master_update(codec, hp, line, mono);
5997 return 1;
5998}
5999
6000static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
6001 {
6002 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6003 .name = "Master Playback Switch",
5b0cb1d8 6004 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6005 .info = snd_ctl_boolean_mono_info,
6006 .get = alc260_hp_master_sw_get,
6007 .put = alc260_hp_master_sw_put,
6008 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
6009 },
6010 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6011 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6012 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6013 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6014 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6015 HDA_OUTPUT),
6016 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6017 { } /* end */
6018};
6019
6020static struct hda_verb alc260_hp_unsol_verbs[] = {
6021 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6022 {},
6023};
6024
6025static void alc260_hp_automute(struct hda_codec *codec)
6026{
6027 struct alc_spec *spec = codec->spec;
bec15c3a 6028
864f92be 6029 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
6030 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
6031}
6032
6033static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
6034{
6035 if ((res >> 26) == ALC880_HP_EVENT)
6036 alc260_hp_automute(codec);
6037}
6038
df694daa 6039static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
6040 {
6041 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6042 .name = "Master Playback Switch",
5b0cb1d8 6043 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6044 .info = snd_ctl_boolean_mono_info,
6045 .get = alc260_hp_master_sw_get,
6046 .put = alc260_hp_master_sw_put,
30cde0aa 6047 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 6048 },
df694daa
KY
6049 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6050 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6051 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6052 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6053 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6054 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
6055 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6056 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
6057 { } /* end */
6058};
6059
3f878308
KY
6060static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6061 .ops = &snd_hda_bind_vol,
6062 .values = {
6063 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6064 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6065 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6066 0
6067 },
6068};
6069
6070static struct hda_bind_ctls alc260_dc7600_bind_switch = {
6071 .ops = &snd_hda_bind_sw,
6072 .values = {
6073 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6074 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6075 0
6076 },
6077};
6078
6079static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6080 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6081 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6082 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6083 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6084 { } /* end */
6085};
6086
bec15c3a
TI
6087static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6088 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6089 {},
6090};
6091
6092static void alc260_hp_3013_automute(struct hda_codec *codec)
6093{
6094 struct alc_spec *spec = codec->spec;
bec15c3a 6095
864f92be 6096 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 6097 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
6098}
6099
6100static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
6101 unsigned int res)
6102{
6103 if ((res >> 26) == ALC880_HP_EVENT)
6104 alc260_hp_3013_automute(codec);
6105}
6106
3f878308
KY
6107static void alc260_hp_3012_automute(struct hda_codec *codec)
6108{
864f92be 6109 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 6110
3f878308
KY
6111 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6112 bits);
6113 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6114 bits);
6115 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6116 bits);
6117}
6118
6119static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
6120 unsigned int res)
6121{
6122 if ((res >> 26) == ALC880_HP_EVENT)
6123 alc260_hp_3012_automute(codec);
6124}
6125
6126/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
6127 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6128 */
c8b6bf9b 6129static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 6130 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6131 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 6132 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
6133 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6134 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6135 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6136 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 6137 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
6138 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6139 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
6140 { } /* end */
6141};
6142
a1e8d2da
JW
6143/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6144 * versions of the ALC260 don't act on requests to enable mic bias from NID
6145 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6146 * datasheet doesn't mention this restriction. At this stage it's not clear
6147 * whether this behaviour is intentional or is a hardware bug in chip
6148 * revisions available in early 2006. Therefore for now allow the
6149 * "Headphone Jack Mode" control to span all choices, but if it turns out
6150 * that the lack of mic bias for this NID is intentional we could change the
6151 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6152 *
6153 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6154 * don't appear to make the mic bias available from the "line" jack, even
6155 * though the NID used for this jack (0x14) can supply it. The theory is
6156 * that perhaps Acer have included blocking capacitors between the ALC260
6157 * and the output jack. If this turns out to be the case for all such
6158 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6159 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
6160 *
6161 * The C20x Tablet series have a mono internal speaker which is controlled
6162 * via the chip's Mono sum widget and pin complex, so include the necessary
6163 * controls for such models. On models without a "mono speaker" the control
6164 * won't do anything.
a1e8d2da 6165 */
0bfc90e9
JW
6166static struct snd_kcontrol_new alc260_acer_mixer[] = {
6167 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6168 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 6169 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 6170 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 6171 HDA_OUTPUT),
31bffaa9 6172 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 6173 HDA_INPUT),
0bfc90e9
JW
6174 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6175 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6176 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6177 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6178 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6179 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6180 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6181 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
6182 { } /* end */
6183};
6184
cc959489
MS
6185/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6186 */
6187static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6188 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6189 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6190 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6191 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6192 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6193 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6194 { } /* end */
6195};
6196
bc9f98a9
KY
6197/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6198 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6199 */
6200static struct snd_kcontrol_new alc260_will_mixer[] = {
6201 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6202 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6203 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6204 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6205 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6206 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6207 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6208 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6209 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6210 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
6211 { } /* end */
6212};
6213
6214/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6215 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6216 */
6217static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6218 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6219 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6220 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6221 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6222 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6223 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6224 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6225 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6226 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6227 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6228 { } /* end */
6229};
6230
df694daa
KY
6231/*
6232 * initialization verbs
6233 */
1da177e4
LT
6234static struct hda_verb alc260_init_verbs[] = {
6235 /* Line In pin widget for input */
05acb863 6236 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6237 /* CD pin widget for input */
05acb863 6238 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6239 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6240 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6241 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6242 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6243 /* LINE-2 is used for line-out in rear */
05acb863 6244 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6245 /* select line-out */
fd56f2db 6246 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6247 /* LINE-OUT pin */
05acb863 6248 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6249 /* enable HP */
05acb863 6250 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6251 /* enable Mono */
05acb863
TI
6252 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6253 /* mute capture amp left and right */
16ded525 6254 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6255 /* set connection select to line in (default select for this ADC) */
6256 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6257 /* mute capture amp left and right */
6258 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6259 /* set connection select to line in (default select for this ADC) */
6260 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6261 /* set vol=0 Line-Out mixer amp left and right */
6262 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6263 /* unmute pin widget amp left and right (no gain on this amp) */
6264 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6265 /* set vol=0 HP mixer amp left and right */
6266 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6267 /* unmute pin widget amp left and right (no gain on this amp) */
6268 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6269 /* set vol=0 Mono mixer amp left and right */
6270 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6271 /* unmute pin widget amp left and right (no gain on this amp) */
6272 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6273 /* unmute LINE-2 out pin */
6274 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6275 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6276 * Line In 2 = 0x03
6277 */
cb53c626
TI
6278 /* mute analog inputs */
6279 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6280 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6281 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6282 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6283 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6284 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6285 /* mute Front out path */
6286 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6287 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6288 /* mute Headphone out path */
6289 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6290 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6291 /* mute Mono out path */
6292 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6293 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6294 { }
6295};
6296
474167d6 6297#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
6298static struct hda_verb alc260_hp_init_verbs[] = {
6299 /* Headphone and output */
6300 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6301 /* mono output */
6302 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6303 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6304 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6305 /* Mic2 (front panel) pin widget for input and vref at 80% */
6306 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6307 /* Line In pin widget for input */
6308 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6309 /* Line-2 pin widget for output */
6310 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6311 /* CD pin widget for input */
6312 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6313 /* unmute amp left and right */
6314 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6315 /* set connection select to line in (default select for this ADC) */
6316 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6317 /* unmute Line-Out mixer amp left and right (volume = 0) */
6318 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6319 /* mute pin widget amp left and right (no gain on this amp) */
6320 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6321 /* unmute HP mixer amp left and right (volume = 0) */
6322 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6323 /* mute pin widget amp left and right (no gain on this amp) */
6324 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6325 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6326 * Line In 2 = 0x03
6327 */
cb53c626
TI
6328 /* mute analog inputs */
6329 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6330 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6331 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6332 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6333 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6334 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6335 /* Unmute Front out path */
6336 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6337 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6338 /* Unmute Headphone out path */
6339 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6340 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6341 /* Unmute Mono out path */
6342 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6343 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6344 { }
6345};
474167d6 6346#endif
df694daa
KY
6347
6348static struct hda_verb alc260_hp_3013_init_verbs[] = {
6349 /* Line out and output */
6350 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6351 /* mono output */
6352 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6353 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6354 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6355 /* Mic2 (front panel) pin widget for input and vref at 80% */
6356 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6357 /* Line In pin widget for input */
6358 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6359 /* Headphone pin widget for output */
6360 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6361 /* CD pin widget for input */
6362 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6363 /* unmute amp left and right */
6364 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6365 /* set connection select to line in (default select for this ADC) */
6366 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6367 /* unmute Line-Out mixer amp left and right (volume = 0) */
6368 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6369 /* mute pin widget amp left and right (no gain on this amp) */
6370 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6371 /* unmute HP mixer amp left and right (volume = 0) */
6372 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6373 /* mute pin widget amp left and right (no gain on this amp) */
6374 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6375 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6376 * Line In 2 = 0x03
6377 */
cb53c626
TI
6378 /* mute analog inputs */
6379 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6380 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6381 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6382 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6383 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6384 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6385 /* Unmute Front out path */
6386 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6387 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6388 /* Unmute Headphone out path */
6389 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6390 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6391 /* Unmute Mono out path */
6392 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6393 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6394 { }
6395};
6396
a9430dd8 6397/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6398 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6399 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
6400 */
6401static struct hda_verb alc260_fujitsu_init_verbs[] = {
6402 /* Disable all GPIOs */
6403 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6404 /* Internal speaker is connected to headphone pin */
6405 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6406 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6407 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6408 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6409 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6410 /* Ensure all other unused pins are disabled and muted. */
6411 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6412 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6413 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6414 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6415 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6416 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6417 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6418 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6419
6420 /* Disable digital (SPDIF) pins */
6421 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6422 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6423
ea1fb29a 6424 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6425 * when acting as an output.
6426 */
6427 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6428
f7ace40d 6429 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6430 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6431 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6432 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6433 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6434 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6435 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6436 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6437 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6438 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6439
f7ace40d
JW
6440 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6441 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6442 /* Unmute Line1 pin widget output buffer since it starts as an output.
6443 * If the pin mode is changed by the user the pin mode control will
6444 * take care of enabling the pin's input/output buffers as needed.
6445 * Therefore there's no need to enable the input buffer at this
6446 * stage.
cdcd9268 6447 */
f7ace40d 6448 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6449 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6450 * mixer ctrl)
6451 */
f7ace40d
JW
6452 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6453
6454 /* Mute capture amp left and right */
6455 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6456 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6457 * in (on mic1 pin)
6458 */
6459 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6460
6461 /* Do the same for the second ADC: mute capture input amp and
6462 * set ADC connection to line in (on mic1 pin)
6463 */
6464 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6465 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6466
6467 /* Mute all inputs to mixer widget (even unconnected ones) */
6468 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6469 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6470 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6471 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6472 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6473 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6474 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6475 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6476
6477 { }
a9430dd8
JW
6478};
6479
0bfc90e9
JW
6480/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6481 * similar laptops (adapted from Fujitsu init verbs).
6482 */
6483static struct hda_verb alc260_acer_init_verbs[] = {
6484 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6485 * the headphone jack. Turn this on and rely on the standard mute
6486 * methods whenever the user wants to turn these outputs off.
6487 */
6488 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6489 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6490 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6491 /* Internal speaker/Headphone jack is connected to Line-out pin */
6492 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6493 /* Internal microphone/Mic jack is connected to Mic1 pin */
6494 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6495 /* Line In jack is connected to Line1 pin */
6496 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6497 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6498 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6499 /* Ensure all other unused pins are disabled and muted. */
6500 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6501 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6502 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6503 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6504 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6505 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6506 /* Disable digital (SPDIF) pins */
6507 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6508 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6509
ea1fb29a 6510 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6511 * bus when acting as outputs.
6512 */
6513 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6514 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6515
6516 /* Start with output sum widgets muted and their output gains at min */
6517 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6518 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6519 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6520 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6521 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6522 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6523 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6524 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6525 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6526
f12ab1e0
TI
6527 /* Unmute Line-out pin widget amp left and right
6528 * (no equiv mixer ctrl)
6529 */
0bfc90e9 6530 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6531 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6532 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6533 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6534 * inputs. If the pin mode is changed by the user the pin mode control
6535 * will take care of enabling the pin's input/output buffers as needed.
6536 * Therefore there's no need to enable the input buffer at this
6537 * stage.
6538 */
6539 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6540 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6541
6542 /* Mute capture amp left and right */
6543 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6544 /* Set ADC connection select to match default mixer setting - mic
6545 * (on mic1 pin)
6546 */
6547 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6548
6549 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6550 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6551 */
6552 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6553 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6554
6555 /* Mute all inputs to mixer widget (even unconnected ones) */
6556 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6557 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6558 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6559 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6560 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6561 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6562 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6563 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6564
6565 { }
6566};
6567
cc959489
MS
6568/* Initialisation sequence for Maxdata Favorit 100XS
6569 * (adapted from Acer init verbs).
6570 */
6571static struct hda_verb alc260_favorit100_init_verbs[] = {
6572 /* GPIO 0 enables the output jack.
6573 * Turn this on and rely on the standard mute
6574 * methods whenever the user wants to turn these outputs off.
6575 */
6576 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6577 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6578 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6579 /* Line/Mic input jack is connected to Mic1 pin */
6580 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6581 /* Ensure all other unused pins are disabled and muted. */
6582 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6583 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6584 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6585 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6586 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6587 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6588 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6589 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6590 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6591 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6592 /* Disable digital (SPDIF) pins */
6593 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6594 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6595
6596 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6597 * bus when acting as outputs.
6598 */
6599 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6600 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6601
6602 /* Start with output sum widgets muted and their output gains at min */
6603 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6604 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6605 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6606 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6607 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6608 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6609 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6610 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6611 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6612
6613 /* Unmute Line-out pin widget amp left and right
6614 * (no equiv mixer ctrl)
6615 */
6616 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6617 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6618 * inputs. If the pin mode is changed by the user the pin mode control
6619 * will take care of enabling the pin's input/output buffers as needed.
6620 * Therefore there's no need to enable the input buffer at this
6621 * stage.
6622 */
6623 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6624
6625 /* Mute capture amp left and right */
6626 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6627 /* Set ADC connection select to match default mixer setting - mic
6628 * (on mic1 pin)
6629 */
6630 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6631
6632 /* Do similar with the second ADC: mute capture input amp and
6633 * set ADC connection to mic to match ALSA's default state.
6634 */
6635 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6636 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6637
6638 /* Mute all inputs to mixer widget (even unconnected ones) */
6639 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6640 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6641 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6642 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6643 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6644 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6645 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6646 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6647
6648 { }
6649};
6650
bc9f98a9
KY
6651static struct hda_verb alc260_will_verbs[] = {
6652 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6653 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6654 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6655 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6656 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6657 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6658 {}
6659};
6660
6661static struct hda_verb alc260_replacer_672v_verbs[] = {
6662 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6663 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6664 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6665
6666 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6667 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6668 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6669
6670 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6671 {}
6672};
6673
6674/* toggle speaker-output according to the hp-jack state */
6675static void alc260_replacer_672v_automute(struct hda_codec *codec)
6676{
6677 unsigned int present;
6678
6679 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6680 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6681 if (present) {
82beb8fd
TI
6682 snd_hda_codec_write_cache(codec, 0x01, 0,
6683 AC_VERB_SET_GPIO_DATA, 1);
6684 snd_hda_codec_write_cache(codec, 0x0f, 0,
6685 AC_VERB_SET_PIN_WIDGET_CONTROL,
6686 PIN_HP);
bc9f98a9 6687 } else {
82beb8fd
TI
6688 snd_hda_codec_write_cache(codec, 0x01, 0,
6689 AC_VERB_SET_GPIO_DATA, 0);
6690 snd_hda_codec_write_cache(codec, 0x0f, 0,
6691 AC_VERB_SET_PIN_WIDGET_CONTROL,
6692 PIN_OUT);
bc9f98a9
KY
6693 }
6694}
6695
6696static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6697 unsigned int res)
6698{
6699 if ((res >> 26) == ALC880_HP_EVENT)
6700 alc260_replacer_672v_automute(codec);
6701}
6702
3f878308
KY
6703static struct hda_verb alc260_hp_dc7600_verbs[] = {
6704 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6705 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6706 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6707 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6708 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6709 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6710 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6711 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6712 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6713 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6714 {}
6715};
6716
7cf51e48
JW
6717/* Test configuration for debugging, modelled after the ALC880 test
6718 * configuration.
6719 */
6720#ifdef CONFIG_SND_DEBUG
6721static hda_nid_t alc260_test_dac_nids[1] = {
6722 0x02,
6723};
6724static hda_nid_t alc260_test_adc_nids[2] = {
6725 0x04, 0x05,
6726};
a1e8d2da 6727/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6728 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6729 * is NID 0x04.
17e7aec6 6730 */
a1e8d2da
JW
6731static struct hda_input_mux alc260_test_capture_sources[2] = {
6732 {
6733 .num_items = 7,
6734 .items = {
6735 { "MIC1 pin", 0x0 },
6736 { "MIC2 pin", 0x1 },
6737 { "LINE1 pin", 0x2 },
6738 { "LINE2 pin", 0x3 },
6739 { "CD pin", 0x4 },
6740 { "LINE-OUT pin", 0x5 },
6741 { "HP-OUT pin", 0x6 },
6742 },
6743 },
6744 {
6745 .num_items = 8,
6746 .items = {
6747 { "MIC1 pin", 0x0 },
6748 { "MIC2 pin", 0x1 },
6749 { "LINE1 pin", 0x2 },
6750 { "LINE2 pin", 0x3 },
6751 { "CD pin", 0x4 },
6752 { "Mixer", 0x5 },
6753 { "LINE-OUT pin", 0x6 },
6754 { "HP-OUT pin", 0x7 },
6755 },
7cf51e48
JW
6756 },
6757};
6758static struct snd_kcontrol_new alc260_test_mixer[] = {
6759 /* Output driver widgets */
6760 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6761 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6762 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6763 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6764 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6765 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6766
a1e8d2da
JW
6767 /* Modes for retasking pin widgets
6768 * Note: the ALC260 doesn't seem to act on requests to enable mic
6769 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6770 * mention this restriction. At this stage it's not clear whether
6771 * this behaviour is intentional or is a hardware bug in chip
6772 * revisions available at least up until early 2006. Therefore for
6773 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6774 * choices, but if it turns out that the lack of mic bias for these
6775 * NIDs is intentional we could change their modes from
6776 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6777 */
7cf51e48
JW
6778 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6779 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6780 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6781 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6782 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6783 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6784
6785 /* Loopback mixer controls */
6786 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6787 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6788 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6789 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6790 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6791 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6792 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6793 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6794 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6795 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6796 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6797 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6798 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6799 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6800
6801 /* Controls for GPIO pins, assuming they are configured as outputs */
6802 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6803 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6804 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6805 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6806
92621f13
JW
6807 /* Switches to allow the digital IO pins to be enabled. The datasheet
6808 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6809 * make this output available should provide clarification.
92621f13
JW
6810 */
6811 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6812 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6813
f8225f6d
JW
6814 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6815 * this output to turn on an external amplifier.
6816 */
6817 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6818 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6819
7cf51e48
JW
6820 { } /* end */
6821};
6822static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6823 /* Enable all GPIOs as outputs with an initial value of 0 */
6824 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6825 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6826 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6827
7cf51e48
JW
6828 /* Enable retasking pins as output, initially without power amp */
6829 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6830 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6831 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6832 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6833 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6834 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6835
92621f13
JW
6836 /* Disable digital (SPDIF) pins initially, but users can enable
6837 * them via a mixer switch. In the case of SPDIF-out, this initverb
6838 * payload also sets the generation to 0, output to be in "consumer"
6839 * PCM format, copyright asserted, no pre-emphasis and no validity
6840 * control.
6841 */
7cf51e48
JW
6842 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6843 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6844
ea1fb29a 6845 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6846 * OUT1 sum bus when acting as an output.
6847 */
6848 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6849 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6850 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6851 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6852
6853 /* Start with output sum widgets muted and their output gains at min */
6854 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6855 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6856 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6857 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6858 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6859 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6860 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6861 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6862 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6863
cdcd9268
JW
6864 /* Unmute retasking pin widget output buffers since the default
6865 * state appears to be output. As the pin mode is changed by the
6866 * user the pin mode control will take care of enabling the pin's
6867 * input/output buffers as needed.
6868 */
7cf51e48
JW
6869 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6870 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6871 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6872 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6873 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6874 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6875 /* Also unmute the mono-out pin widget */
6876 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6877
7cf51e48
JW
6878 /* Mute capture amp left and right */
6879 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6880 /* Set ADC connection select to match default mixer setting (mic1
6881 * pin)
7cf51e48
JW
6882 */
6883 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6884
6885 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6886 * set ADC connection to mic1 pin
7cf51e48
JW
6887 */
6888 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6889 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6890
6891 /* Mute all inputs to mixer widget (even unconnected ones) */
6892 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6893 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6894 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6895 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6896 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6897 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6898 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6899 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6900
6901 { }
6902};
6903#endif
6904
6330079f
TI
6905#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6906#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6907
a3bcba38
TI
6908#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6909#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6910
df694daa
KY
6911/*
6912 * for BIOS auto-configuration
6913 */
16ded525 6914
df694daa 6915static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6916 const char *pfx, int *vol_bits)
df694daa
KY
6917{
6918 hda_nid_t nid_vol;
6919 unsigned long vol_val, sw_val;
df694daa
KY
6920 int err;
6921
6922 if (nid >= 0x0f && nid < 0x11) {
6923 nid_vol = nid - 0x7;
6924 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6925 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6926 } else if (nid == 0x11) {
6927 nid_vol = nid - 0x7;
6928 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6929 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6930 } else if (nid >= 0x12 && nid <= 0x15) {
6931 nid_vol = 0x08;
6932 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6933 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6934 } else
6935 return 0; /* N/A */
ea1fb29a 6936
863b4518
TI
6937 if (!(*vol_bits & (1 << nid_vol))) {
6938 /* first control for the volume widget */
0afe5f89 6939 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6940 if (err < 0)
6941 return err;
6942 *vol_bits |= (1 << nid_vol);
6943 }
0afe5f89 6944 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6945 if (err < 0)
df694daa
KY
6946 return err;
6947 return 1;
6948}
6949
6950/* add playback controls from the parsed DAC table */
6951static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6952 const struct auto_pin_cfg *cfg)
6953{
6954 hda_nid_t nid;
6955 int err;
863b4518 6956 int vols = 0;
df694daa
KY
6957
6958 spec->multiout.num_dacs = 1;
6959 spec->multiout.dac_nids = spec->private_dac_nids;
6960 spec->multiout.dac_nids[0] = 0x02;
6961
6962 nid = cfg->line_out_pins[0];
6963 if (nid) {
23112d6d
TI
6964 const char *pfx;
6965 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6966 pfx = "Master";
6967 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6968 pfx = "Speaker";
6969 else
6970 pfx = "Front";
6971 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6972 if (err < 0)
6973 return err;
6974 }
6975
82bc955f 6976 nid = cfg->speaker_pins[0];
df694daa 6977 if (nid) {
863b4518 6978 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6979 if (err < 0)
6980 return err;
6981 }
6982
eb06ed8f 6983 nid = cfg->hp_pins[0];
df694daa 6984 if (nid) {
863b4518
TI
6985 err = alc260_add_playback_controls(spec, nid, "Headphone",
6986 &vols);
df694daa
KY
6987 if (err < 0)
6988 return err;
6989 }
f12ab1e0 6990 return 0;
df694daa
KY
6991}
6992
6993/* create playback/capture controls for input pins */
05f5f477 6994static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6995 const struct auto_pin_cfg *cfg)
6996{
05f5f477 6997 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6998}
6999
7000static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
7001 hda_nid_t nid, int pin_type,
7002 int sel_idx)
7003{
f6c7e546 7004 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
7005 /* need the manual connection? */
7006 if (nid >= 0x12) {
7007 int idx = nid - 0x12;
7008 snd_hda_codec_write(codec, idx + 0x0b, 0,
7009 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
7010 }
7011}
7012
7013static void alc260_auto_init_multi_out(struct hda_codec *codec)
7014{
7015 struct alc_spec *spec = codec->spec;
7016 hda_nid_t nid;
7017
f12ab1e0 7018 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
7019 if (nid) {
7020 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7021 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7022 }
ea1fb29a 7023
82bc955f 7024 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
7025 if (nid)
7026 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7027
eb06ed8f 7028 nid = spec->autocfg.hp_pins[0];
df694daa 7029 if (nid)
baba8ee9 7030 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 7031}
df694daa
KY
7032
7033#define ALC260_PIN_CD_NID 0x16
7034static void alc260_auto_init_analog_input(struct hda_codec *codec)
7035{
7036 struct alc_spec *spec = codec->spec;
66ceeb6b 7037 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
7038 int i;
7039
66ceeb6b
TI
7040 for (i = 0; i < cfg->num_inputs; i++) {
7041 hda_nid_t nid = cfg->inputs[i].pin;
df694daa 7042 if (nid >= 0x12) {
30ea098f 7043 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
7044 if (nid != ALC260_PIN_CD_NID &&
7045 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
7046 snd_hda_codec_write(codec, nid, 0,
7047 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
7048 AMP_OUT_MUTE);
7049 }
7050 }
7051}
7052
7f311a46
TI
7053#define alc260_auto_init_input_src alc880_auto_init_input_src
7054
df694daa
KY
7055/*
7056 * generic initialization of ADC, input mixers and output mixers
7057 */
7058static struct hda_verb alc260_volume_init_verbs[] = {
7059 /*
7060 * Unmute ADC0-1 and set the default input to mic-in
7061 */
7062 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7063 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7064 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7065 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 7066
df694daa
KY
7067 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7068 * mixer widget
f12ab1e0
TI
7069 * Note: PASD motherboards uses the Line In 2 as the input for
7070 * front panel mic (mic 2)
df694daa
KY
7071 */
7072 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
7073 /* mute analog inputs */
7074 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7075 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7076 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7077 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7078 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
7079
7080 /*
7081 * Set up output mixers (0x08 - 0x0a)
7082 */
7083 /* set vol=0 to output mixers */
7084 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7085 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7086 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7087 /* set up input amps for analog loopback */
7088 /* Amp Indices: DAC = 0, mixer = 1 */
7089 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7090 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7091 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7092 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7093 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7094 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 7095
df694daa
KY
7096 { }
7097};
7098
7099static int alc260_parse_auto_config(struct hda_codec *codec)
7100{
7101 struct alc_spec *spec = codec->spec;
df694daa
KY
7102 int err;
7103 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
7104
f12ab1e0
TI
7105 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7106 alc260_ignore);
7107 if (err < 0)
df694daa 7108 return err;
f12ab1e0
TI
7109 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7110 if (err < 0)
4a471b7d 7111 return err;
603c4019 7112 if (!spec->kctls.list)
df694daa 7113 return 0; /* can't find valid BIOS pin config */
05f5f477 7114 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 7115 if (err < 0)
df694daa
KY
7116 return err;
7117
7118 spec->multiout.max_channels = 2;
7119
0852d7a6 7120 if (spec->autocfg.dig_outs)
df694daa 7121 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 7122 if (spec->kctls.list)
d88897ea 7123 add_mixer(spec, spec->kctls.list);
df694daa 7124
d88897ea 7125 add_verb(spec, alc260_volume_init_verbs);
df694daa 7126
a1e8d2da 7127 spec->num_mux_defs = 1;
61b9b9b1 7128 spec->input_mux = &spec->private_imux[0];
df694daa 7129
6227cdce 7130 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 7131
df694daa
KY
7132 return 1;
7133}
7134
ae6b813a
TI
7135/* additional initialization for auto-configuration model */
7136static void alc260_auto_init(struct hda_codec *codec)
df694daa 7137{
f6c7e546 7138 struct alc_spec *spec = codec->spec;
df694daa
KY
7139 alc260_auto_init_multi_out(codec);
7140 alc260_auto_init_analog_input(codec);
7f311a46 7141 alc260_auto_init_input_src(codec);
757899ac 7142 alc_auto_init_digital(codec);
f6c7e546 7143 if (spec->unsol_event)
7fb0d78f 7144 alc_inithook(codec);
df694daa
KY
7145}
7146
cb53c626
TI
7147#ifdef CONFIG_SND_HDA_POWER_SAVE
7148static struct hda_amp_list alc260_loopbacks[] = {
7149 { 0x07, HDA_INPUT, 0 },
7150 { 0x07, HDA_INPUT, 1 },
7151 { 0x07, HDA_INPUT, 2 },
7152 { 0x07, HDA_INPUT, 3 },
7153 { 0x07, HDA_INPUT, 4 },
7154 { } /* end */
7155};
7156#endif
7157
fc091769
TI
7158/*
7159 * Pin config fixes
7160 */
7161enum {
7162 PINFIX_HP_DC5750,
7163};
7164
fc091769
TI
7165static const struct alc_fixup alc260_fixups[] = {
7166 [PINFIX_HP_DC5750] = {
b5bfbc67
TI
7167 .type = ALC_FIXUP_PINS,
7168 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
7169 { 0x11, 0x90130110 }, /* speaker */
7170 { }
7171 }
fc091769
TI
7172 },
7173};
7174
7175static struct snd_pci_quirk alc260_fixup_tbl[] = {
7176 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7177 {}
7178};
7179
df694daa
KY
7180/*
7181 * ALC260 configurations
7182 */
ea734963 7183static const char * const alc260_models[ALC260_MODEL_LAST] = {
f5fcc13c
TI
7184 [ALC260_BASIC] = "basic",
7185 [ALC260_HP] = "hp",
7186 [ALC260_HP_3013] = "hp-3013",
2922c9af 7187 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
7188 [ALC260_FUJITSU_S702X] = "fujitsu",
7189 [ALC260_ACER] = "acer",
bc9f98a9
KY
7190 [ALC260_WILL] = "will",
7191 [ALC260_REPLACER_672V] = "replacer",
cc959489 7192 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 7193#ifdef CONFIG_SND_DEBUG
f5fcc13c 7194 [ALC260_TEST] = "test",
7cf51e48 7195#endif
f5fcc13c
TI
7196 [ALC260_AUTO] = "auto",
7197};
7198
7199static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 7200 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 7201 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 7202 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 7203 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 7204 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 7205 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 7206 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 7207 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 7208 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
7209 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7210 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7211 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7212 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7213 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7214 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7215 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7216 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7217 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7218 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7219 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7220 {}
7221};
7222
7223static struct alc_config_preset alc260_presets[] = {
7224 [ALC260_BASIC] = {
7225 .mixers = { alc260_base_output_mixer,
45bdd1c1 7226 alc260_input_mixer },
df694daa
KY
7227 .init_verbs = { alc260_init_verbs },
7228 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7229 .dac_nids = alc260_dac_nids,
f9e336f6 7230 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7231 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7232 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7233 .channel_mode = alc260_modes,
7234 .input_mux = &alc260_capture_source,
7235 },
7236 [ALC260_HP] = {
bec15c3a 7237 .mixers = { alc260_hp_output_mixer,
f9e336f6 7238 alc260_input_mixer },
bec15c3a
TI
7239 .init_verbs = { alc260_init_verbs,
7240 alc260_hp_unsol_verbs },
df694daa
KY
7241 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7242 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7243 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7244 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7245 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7246 .channel_mode = alc260_modes,
7247 .input_mux = &alc260_capture_source,
bec15c3a
TI
7248 .unsol_event = alc260_hp_unsol_event,
7249 .init_hook = alc260_hp_automute,
df694daa 7250 },
3f878308
KY
7251 [ALC260_HP_DC7600] = {
7252 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7253 alc260_input_mixer },
3f878308
KY
7254 .init_verbs = { alc260_init_verbs,
7255 alc260_hp_dc7600_verbs },
7256 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7257 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7258 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7259 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7260 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7261 .channel_mode = alc260_modes,
7262 .input_mux = &alc260_capture_source,
7263 .unsol_event = alc260_hp_3012_unsol_event,
7264 .init_hook = alc260_hp_3012_automute,
7265 },
df694daa
KY
7266 [ALC260_HP_3013] = {
7267 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7268 alc260_input_mixer },
bec15c3a
TI
7269 .init_verbs = { alc260_hp_3013_init_verbs,
7270 alc260_hp_3013_unsol_verbs },
df694daa
KY
7271 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7272 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7273 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7274 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7275 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7276 .channel_mode = alc260_modes,
7277 .input_mux = &alc260_capture_source,
bec15c3a
TI
7278 .unsol_event = alc260_hp_3013_unsol_event,
7279 .init_hook = alc260_hp_3013_automute,
df694daa
KY
7280 },
7281 [ALC260_FUJITSU_S702X] = {
f9e336f6 7282 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7283 .init_verbs = { alc260_fujitsu_init_verbs },
7284 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7285 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7286 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7287 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7288 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7289 .channel_mode = alc260_modes,
a1e8d2da
JW
7290 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7291 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7292 },
0bfc90e9 7293 [ALC260_ACER] = {
f9e336f6 7294 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7295 .init_verbs = { alc260_acer_init_verbs },
7296 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7297 .dac_nids = alc260_dac_nids,
7298 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7299 .adc_nids = alc260_dual_adc_nids,
7300 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7301 .channel_mode = alc260_modes,
a1e8d2da
JW
7302 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7303 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7304 },
cc959489
MS
7305 [ALC260_FAVORIT100] = {
7306 .mixers = { alc260_favorit100_mixer },
7307 .init_verbs = { alc260_favorit100_init_verbs },
7308 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7309 .dac_nids = alc260_dac_nids,
7310 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7311 .adc_nids = alc260_dual_adc_nids,
7312 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7313 .channel_mode = alc260_modes,
7314 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7315 .input_mux = alc260_favorit100_capture_sources,
7316 },
bc9f98a9 7317 [ALC260_WILL] = {
f9e336f6 7318 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7319 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7320 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7321 .dac_nids = alc260_dac_nids,
7322 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7323 .adc_nids = alc260_adc_nids,
7324 .dig_out_nid = ALC260_DIGOUT_NID,
7325 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7326 .channel_mode = alc260_modes,
7327 .input_mux = &alc260_capture_source,
7328 },
7329 [ALC260_REPLACER_672V] = {
f9e336f6 7330 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7331 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7332 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7333 .dac_nids = alc260_dac_nids,
7334 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7335 .adc_nids = alc260_adc_nids,
7336 .dig_out_nid = ALC260_DIGOUT_NID,
7337 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7338 .channel_mode = alc260_modes,
7339 .input_mux = &alc260_capture_source,
7340 .unsol_event = alc260_replacer_672v_unsol_event,
7341 .init_hook = alc260_replacer_672v_automute,
7342 },
7cf51e48
JW
7343#ifdef CONFIG_SND_DEBUG
7344 [ALC260_TEST] = {
f9e336f6 7345 .mixers = { alc260_test_mixer },
7cf51e48
JW
7346 .init_verbs = { alc260_test_init_verbs },
7347 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7348 .dac_nids = alc260_test_dac_nids,
7349 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7350 .adc_nids = alc260_test_adc_nids,
7351 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7352 .channel_mode = alc260_modes,
a1e8d2da
JW
7353 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7354 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7355 },
7356#endif
df694daa
KY
7357};
7358
7359static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7360{
7361 struct alc_spec *spec;
df694daa 7362 int err, board_config;
1da177e4 7363
e560d8d8 7364 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7365 if (spec == NULL)
7366 return -ENOMEM;
7367
7368 codec->spec = spec;
7369
f5fcc13c
TI
7370 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7371 alc260_models,
7372 alc260_cfg_tbl);
7373 if (board_config < 0) {
9a11f1aa 7374 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7375 codec->chip_name);
df694daa 7376 board_config = ALC260_AUTO;
16ded525 7377 }
1da177e4 7378
b5bfbc67
TI
7379 if (board_config == ALC260_AUTO) {
7380 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7381 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7382 }
fc091769 7383
df694daa
KY
7384 if (board_config == ALC260_AUTO) {
7385 /* automatic parse from the BIOS config */
7386 err = alc260_parse_auto_config(codec);
7387 if (err < 0) {
7388 alc_free(codec);
7389 return err;
f12ab1e0 7390 } else if (!err) {
9c7f852e
TI
7391 printk(KERN_INFO
7392 "hda_codec: Cannot set up configuration "
7393 "from BIOS. Using base mode...\n");
df694daa
KY
7394 board_config = ALC260_BASIC;
7395 }
a9430dd8 7396 }
e9edcee0 7397
680cd536
KK
7398 err = snd_hda_attach_beep_device(codec, 0x1);
7399 if (err < 0) {
7400 alc_free(codec);
7401 return err;
7402 }
7403
df694daa 7404 if (board_config != ALC260_AUTO)
e9c364c0 7405 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7406
1da177e4
LT
7407 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7408 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7409 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7410
a3bcba38
TI
7411 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7412 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7413
4ef0ef19
TI
7414 if (!spec->adc_nids && spec->input_mux) {
7415 /* check whether NID 0x04 is valid */
7416 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7417 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7418 /* get type */
7419 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7420 spec->adc_nids = alc260_adc_nids_alt;
7421 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7422 } else {
7423 spec->adc_nids = alc260_adc_nids;
7424 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7425 }
7426 }
b59bdf3b 7427 set_capture_mixer(codec);
45bdd1c1 7428 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7429
b5bfbc67 7430 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
fc091769 7431
2134ea4f
TI
7432 spec->vmaster_nid = 0x08;
7433
1da177e4 7434 codec->patch_ops = alc_patch_ops;
df694daa 7435 if (board_config == ALC260_AUTO)
ae6b813a 7436 spec->init_hook = alc260_auto_init;
cb53c626
TI
7437#ifdef CONFIG_SND_HDA_POWER_SAVE
7438 if (!spec->loopback.amplist)
7439 spec->loopback.amplist = alc260_loopbacks;
7440#endif
1da177e4
LT
7441
7442 return 0;
7443}
7444
e9edcee0 7445
1da177e4 7446/*
4953550a 7447 * ALC882/883/885/888/889 support
1da177e4
LT
7448 *
7449 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7450 * configuration. Each pin widget can choose any input DACs and a mixer.
7451 * Each ADC is connected from a mixer of all inputs. This makes possible
7452 * 6-channel independent captures.
7453 *
7454 * In addition, an independent DAC for the multi-playback (not used in this
7455 * driver yet).
7456 */
df694daa
KY
7457#define ALC882_DIGOUT_NID 0x06
7458#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7459#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7460#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7461#define ALC1200_DIGOUT_NID 0x10
7462
1da177e4 7463
d2a6d7dc 7464static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7465 { 8, NULL }
7466};
7467
4953550a 7468/* DACs */
1da177e4
LT
7469static hda_nid_t alc882_dac_nids[4] = {
7470 /* front, rear, clfe, rear_surr */
7471 0x02, 0x03, 0x04, 0x05
7472};
4953550a 7473#define alc883_dac_nids alc882_dac_nids
1da177e4 7474
4953550a 7475/* ADCs */
df694daa
KY
7476#define alc882_adc_nids alc880_adc_nids
7477#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
7478#define alc883_adc_nids alc882_adc_nids_alt
7479static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7480static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7481#define alc889_adc_nids alc880_adc_nids
1da177e4 7482
e1406348
TI
7483static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7484static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
7485#define alc883_capsrc_nids alc882_capsrc_nids_alt
7486static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7487#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7488
1da177e4
LT
7489/* input MUX */
7490/* FIXME: should be a matrix-type input source selection */
7491
7492static struct hda_input_mux alc882_capture_source = {
7493 .num_items = 4,
7494 .items = {
7495 { "Mic", 0x0 },
7496 { "Front Mic", 0x1 },
7497 { "Line", 0x2 },
7498 { "CD", 0x4 },
7499 },
7500};
41d5545d 7501
4953550a
TI
7502#define alc883_capture_source alc882_capture_source
7503
87a8c370
JK
7504static struct hda_input_mux alc889_capture_source = {
7505 .num_items = 3,
7506 .items = {
7507 { "Front Mic", 0x0 },
7508 { "Mic", 0x3 },
7509 { "Line", 0x2 },
7510 },
7511};
7512
41d5545d
KS
7513static struct hda_input_mux mb5_capture_source = {
7514 .num_items = 3,
7515 .items = {
7516 { "Mic", 0x1 },
b8f171e7 7517 { "Line", 0x7 },
41d5545d
KS
7518 { "CD", 0x4 },
7519 },
7520};
7521
e458b1fa
LY
7522static struct hda_input_mux macmini3_capture_source = {
7523 .num_items = 2,
7524 .items = {
7525 { "Line", 0x2 },
7526 { "CD", 0x4 },
7527 },
7528};
7529
4953550a
TI
7530static struct hda_input_mux alc883_3stack_6ch_intel = {
7531 .num_items = 4,
7532 .items = {
7533 { "Mic", 0x1 },
7534 { "Front Mic", 0x0 },
7535 { "Line", 0x2 },
7536 { "CD", 0x4 },
7537 },
7538};
7539
7540static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7541 .num_items = 2,
7542 .items = {
7543 { "Mic", 0x1 },
7544 { "Line", 0x2 },
7545 },
7546};
7547
7548static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7549 .num_items = 4,
7550 .items = {
7551 { "Mic", 0x0 },
28c4edb7 7552 { "Internal Mic", 0x1 },
4953550a
TI
7553 { "Line", 0x2 },
7554 { "CD", 0x4 },
7555 },
7556};
7557
7558static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7559 .num_items = 2,
7560 .items = {
7561 { "Mic", 0x0 },
28c4edb7 7562 { "Internal Mic", 0x1 },
4953550a
TI
7563 },
7564};
7565
7566static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7567 .num_items = 3,
7568 .items = {
7569 { "Mic", 0x0 },
7570 { "Front Mic", 0x1 },
7571 { "Line", 0x4 },
7572 },
7573};
7574
7575static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7576 .num_items = 2,
7577 .items = {
7578 { "Mic", 0x0 },
7579 { "Line", 0x2 },
7580 },
7581};
7582
7583static struct hda_input_mux alc889A_mb31_capture_source = {
7584 .num_items = 2,
7585 .items = {
7586 { "Mic", 0x0 },
7587 /* Front Mic (0x01) unused */
7588 { "Line", 0x2 },
7589 /* Line 2 (0x03) unused */
af901ca1 7590 /* CD (0x04) unused? */
4953550a
TI
7591 },
7592};
7593
b7cccc52
JM
7594static struct hda_input_mux alc889A_imac91_capture_source = {
7595 .num_items = 2,
7596 .items = {
7597 { "Mic", 0x01 },
7598 { "Line", 0x2 }, /* Not sure! */
7599 },
7600};
7601
4953550a
TI
7602/*
7603 * 2ch mode
7604 */
7605static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7606 { 2, NULL }
7607};
7608
272a527c
KY
7609/*
7610 * 2ch mode
7611 */
7612static struct hda_verb alc882_3ST_ch2_init[] = {
7613 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7614 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7615 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7616 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7617 { } /* end */
7618};
7619
4953550a
TI
7620/*
7621 * 4ch mode
7622 */
7623static struct hda_verb alc882_3ST_ch4_init[] = {
7624 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7625 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7626 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7627 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7628 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7629 { } /* end */
7630};
7631
272a527c
KY
7632/*
7633 * 6ch mode
7634 */
7635static struct hda_verb alc882_3ST_ch6_init[] = {
7636 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7637 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7638 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7639 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7640 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7641 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7642 { } /* end */
7643};
7644
4953550a 7645static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7646 { 2, alc882_3ST_ch2_init },
4953550a 7647 { 4, alc882_3ST_ch4_init },
272a527c
KY
7648 { 6, alc882_3ST_ch6_init },
7649};
7650
4953550a
TI
7651#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7652
a65cc60f 7653/*
7654 * 2ch mode
7655 */
7656static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7657 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7658 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7659 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7660 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7661 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7662 { } /* end */
7663};
7664
7665/*
7666 * 4ch mode
7667 */
7668static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7669 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7670 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7671 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7672 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7673 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7674 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7675 { } /* end */
7676};
7677
7678/*
7679 * 6ch mode
7680 */
7681static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7682 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7683 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7684 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7685 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7686 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7687 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7688 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7689 { } /* end */
7690};
7691
7692static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7693 { 2, alc883_3ST_ch2_clevo_init },
7694 { 4, alc883_3ST_ch4_clevo_init },
7695 { 6, alc883_3ST_ch6_clevo_init },
7696};
7697
7698
df694daa
KY
7699/*
7700 * 6ch mode
7701 */
7702static struct hda_verb alc882_sixstack_ch6_init[] = {
7703 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7704 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7705 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7706 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7707 { } /* end */
7708};
7709
7710/*
7711 * 8ch mode
7712 */
7713static struct hda_verb alc882_sixstack_ch8_init[] = {
7714 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7715 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7716 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7717 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7718 { } /* end */
7719};
7720
7721static struct hda_channel_mode alc882_sixstack_modes[2] = {
7722 { 6, alc882_sixstack_ch6_init },
7723 { 8, alc882_sixstack_ch8_init },
7724};
7725
76e6f5a9
RH
7726
7727/* Macbook Air 2,1 */
7728
7729static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7730 { 2, NULL },
7731};
7732
87350ad0 7733/*
def319f9 7734 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7735 */
7736
7737/*
7738 * 2ch mode
7739 */
7740static struct hda_verb alc885_mbp_ch2_init[] = {
7741 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7742 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7743 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7744 { } /* end */
7745};
7746
7747/*
a3f730af 7748 * 4ch mode
87350ad0 7749 */
a3f730af 7750static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7751 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7752 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7753 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7754 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7755 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7756 { } /* end */
7757};
7758
a3f730af 7759static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7760 { 2, alc885_mbp_ch2_init },
a3f730af 7761 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7762};
7763
92b9de83
KS
7764/*
7765 * 2ch
7766 * Speakers/Woofer/HP = Front
7767 * LineIn = Input
7768 */
7769static struct hda_verb alc885_mb5_ch2_init[] = {
7770 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7771 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7772 { } /* end */
7773};
7774
7775/*
7776 * 6ch mode
7777 * Speakers/HP = Front
7778 * Woofer = LFE
7779 * LineIn = Surround
7780 */
7781static struct hda_verb alc885_mb5_ch6_init[] = {
7782 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7783 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7784 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7785 { } /* end */
7786};
7787
7788static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7789 { 2, alc885_mb5_ch2_init },
7790 { 6, alc885_mb5_ch6_init },
7791};
87350ad0 7792
d01aecdf 7793#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7794
7795/*
7796 * 2ch mode
7797 */
7798static struct hda_verb alc883_4ST_ch2_init[] = {
7799 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7800 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7801 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7802 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7803 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7804 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7805 { } /* end */
7806};
7807
7808/*
7809 * 4ch mode
7810 */
7811static struct hda_verb alc883_4ST_ch4_init[] = {
7812 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7813 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7814 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7815 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7816 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7817 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7818 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7819 { } /* end */
7820};
7821
7822/*
7823 * 6ch mode
7824 */
7825static struct hda_verb alc883_4ST_ch6_init[] = {
7826 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7827 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7828 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7829 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7830 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7831 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7832 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7833 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7834 { } /* end */
7835};
7836
7837/*
7838 * 8ch mode
7839 */
7840static struct hda_verb alc883_4ST_ch8_init[] = {
7841 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7842 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7843 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7844 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7845 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7846 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7847 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7848 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7849 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7850 { } /* end */
7851};
7852
7853static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7854 { 2, alc883_4ST_ch2_init },
7855 { 4, alc883_4ST_ch4_init },
7856 { 6, alc883_4ST_ch6_init },
7857 { 8, alc883_4ST_ch8_init },
7858};
7859
7860
7861/*
7862 * 2ch mode
7863 */
7864static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7865 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7866 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7867 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7868 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7869 { } /* end */
7870};
7871
7872/*
7873 * 4ch mode
7874 */
7875static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7876 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7877 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7878 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7879 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7880 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7881 { } /* end */
7882};
7883
7884/*
7885 * 6ch mode
7886 */
7887static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7888 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7889 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7890 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7891 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7892 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7893 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7894 { } /* end */
7895};
7896
7897static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7898 { 2, alc883_3ST_ch2_intel_init },
7899 { 4, alc883_3ST_ch4_intel_init },
7900 { 6, alc883_3ST_ch6_intel_init },
7901};
7902
dd7714c9
WF
7903/*
7904 * 2ch mode
7905 */
7906static struct hda_verb alc889_ch2_intel_init[] = {
7907 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7908 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7909 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7910 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7911 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7912 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7913 { } /* end */
7914};
7915
87a8c370
JK
7916/*
7917 * 6ch mode
7918 */
7919static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7920 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7921 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7922 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7923 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7924 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7925 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7926 { } /* end */
7927};
7928
7929/*
7930 * 8ch mode
7931 */
7932static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7933 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7934 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7935 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7936 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7937 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7938 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7939 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7940 { } /* end */
7941};
7942
dd7714c9
WF
7943static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7944 { 2, alc889_ch2_intel_init },
87a8c370
JK
7945 { 6, alc889_ch6_intel_init },
7946 { 8, alc889_ch8_intel_init },
7947};
7948
4953550a
TI
7949/*
7950 * 6ch mode
7951 */
7952static struct hda_verb alc883_sixstack_ch6_init[] = {
7953 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7954 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7955 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7956 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7957 { } /* end */
7958};
7959
7960/*
7961 * 8ch mode
7962 */
7963static struct hda_verb alc883_sixstack_ch8_init[] = {
7964 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7965 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7966 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7967 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7968 { } /* end */
7969};
7970
7971static struct hda_channel_mode alc883_sixstack_modes[2] = {
7972 { 6, alc883_sixstack_ch6_init },
7973 { 8, alc883_sixstack_ch8_init },
7974};
7975
7976
1da177e4
LT
7977/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7978 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7979 */
c8b6bf9b 7980static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7981 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7982 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7983 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7984 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7985 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7986 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7987 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7988 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7989 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7990 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7991 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7992 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7993 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7994 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7995 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7996 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 7997 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1da177e4
LT
7998 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7999 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8000 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1da177e4 8001 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
8002 { } /* end */
8003};
8004
76e6f5a9
RH
8005/* Macbook Air 2,1 same control for HP and internal Speaker */
8006
8007static struct snd_kcontrol_new alc885_mba21_mixer[] = {
8008 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8009 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8010 { }
8011};
8012
8013
87350ad0 8014static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
8015 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8016 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8017 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8018 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8019 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
8020 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8021 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
8022 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8023 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5f99f86a
DH
8024 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8025 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
87350ad0
TI
8026 { } /* end */
8027};
41d5545d
KS
8028
8029static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
8030 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8031 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8032 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8033 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8034 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8035 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
8036 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8037 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
8038 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8039 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
8040 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8041 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
8042 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8043 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
41d5545d
KS
8044 { } /* end */
8045};
92b9de83 8046
e458b1fa
LY
8047static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
8048 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8049 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8050 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8051 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8052 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8053 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8054 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8055 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8056 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8057 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
5f99f86a 8058 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
e458b1fa
LY
8059 { } /* end */
8060};
8061
4b7e1803 8062static struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
8063 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8064 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
8065 { } /* end */
8066};
8067
8068
bdd148a3
KY
8069static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8070 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8071 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8072 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8073 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8074 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8075 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8076 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8077 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3 8078 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
8079 { } /* end */
8080};
8081
272a527c
KY
8082static struct snd_kcontrol_new alc882_targa_mixer[] = {
8083 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8084 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8085 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8086 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8087 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8088 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8089 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8090 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8091 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8092 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8093 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8094 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8095 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272a527c
KY
8096 { } /* end */
8097};
8098
8099/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8100 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8101 */
8102static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8103 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8104 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8105 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8106 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8107 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8108 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8109 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8110 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8111 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8112 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8113 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8114 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8115 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8116 { } /* end */
8117};
8118
914759b7
TI
8119static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8120 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8121 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8122 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8123 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8124 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8125 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8126 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8127 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8128 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
914759b7 8129 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
8130 { } /* end */
8131};
8132
df694daa
KY
8133static struct snd_kcontrol_new alc882_chmode_mixer[] = {
8134 {
8135 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8136 .name = "Channel Mode",
8137 .info = alc_ch_mode_info,
8138 .get = alc_ch_mode_get,
8139 .put = alc_ch_mode_put,
8140 },
8141 { } /* end */
8142};
8143
4953550a 8144static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 8145 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
8146 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8147 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8148 /* Rear mixer */
05acb863
TI
8149 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8150 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8151 /* CLFE mixer */
05acb863
TI
8152 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8153 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8154 /* Side mixer */
05acb863
TI
8155 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8156 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8157
e9edcee0 8158 /* Front Pin: output 0 (0x0c) */
05acb863 8159 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8160 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8161 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 8162 /* Rear Pin: output 1 (0x0d) */
05acb863 8163 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8164 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8165 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 8166 /* CLFE Pin: output 2 (0x0e) */
05acb863 8167 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8168 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8169 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 8170 /* Side Pin: output 3 (0x0f) */
05acb863 8171 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8172 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8173 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 8174 /* Mic (rear) pin: input vref at 80% */
16ded525 8175 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8176 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8177 /* Front Mic pin: input vref at 80% */
16ded525 8178 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8179 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8180 /* Line In pin: input */
05acb863 8181 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
8182 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8183 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8184 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8185 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8186 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 8187 /* CD pin widget for input */
05acb863 8188 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
8189
8190 /* FIXME: use matrix-type input source selection */
8191 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 8192 /* Input mixer2 */
05acb863 8193 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 8194 /* Input mixer3 */
05acb863 8195 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
8196 /* ADC2: mute amp left and right */
8197 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8198 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
8199 /* ADC3: mute amp left and right */
8200 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8201 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
8202
8203 { }
8204};
8205
4953550a
TI
8206static struct hda_verb alc882_adc1_init_verbs[] = {
8207 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8208 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8209 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8210 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8211 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8212 /* ADC1: mute amp left and right */
8213 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8214 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8215 { }
8216};
8217
4b146cb0
TI
8218static struct hda_verb alc882_eapd_verbs[] = {
8219 /* change to EAPD mode */
8220 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8221 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8222 { }
4b146cb0
TI
8223};
8224
87a8c370
JK
8225static struct hda_verb alc889_eapd_verbs[] = {
8226 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8227 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8228 { }
8229};
8230
6732bd0d
WF
8231static struct hda_verb alc_hp15_unsol_verbs[] = {
8232 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8233 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8234 {}
8235};
87a8c370
JK
8236
8237static struct hda_verb alc885_init_verbs[] = {
8238 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8239 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8240 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8241 /* Rear mixer */
88102f3f
KY
8242 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8243 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8244 /* CLFE mixer */
88102f3f
KY
8245 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8246 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8247 /* Side mixer */
88102f3f
KY
8248 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8249 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8250
8251 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8252 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8253 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8254 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8255 /* Front Pin: output 0 (0x0c) */
8256 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8257 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8258 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8259 /* Rear Pin: output 1 (0x0d) */
8260 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8261 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8262 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8263 /* CLFE Pin: output 2 (0x0e) */
8264 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8265 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8266 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8267 /* Side Pin: output 3 (0x0f) */
8268 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8269 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8270 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8271 /* Mic (rear) pin: input vref at 80% */
8272 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8273 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8274 /* Front Mic pin: input vref at 80% */
8275 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8276 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8277 /* Line In pin: input */
8278 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8279 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8280
8281 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8282 /* Input mixer1 */
88102f3f 8283 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8284 /* Input mixer2 */
8285 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8286 /* Input mixer3 */
88102f3f 8287 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8288 /* ADC2: mute amp left and right */
8289 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8290 /* ADC3: mute amp left and right */
8291 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8292
8293 { }
8294};
8295
8296static struct hda_verb alc885_init_input_verbs[] = {
8297 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8298 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8299 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8300 { }
8301};
8302
8303
8304/* Unmute Selector 24h and set the default input to front mic */
8305static struct hda_verb alc889_init_input_verbs[] = {
8306 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8307 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8308 { }
8309};
8310
8311
4953550a
TI
8312#define alc883_init_verbs alc882_base_init_verbs
8313
9102cd1c
TD
8314/* Mac Pro test */
8315static struct snd_kcontrol_new alc882_macpro_mixer[] = {
8316 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8317 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8318 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8319 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8320 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8321 /* FIXME: this looks suspicious...
d355c82a
JK
8322 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8323 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8324 */
9102cd1c
TD
8325 { } /* end */
8326};
8327
8328static struct hda_verb alc882_macpro_init_verbs[] = {
8329 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8330 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8331 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8332 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8333 /* Front Pin: output 0 (0x0c) */
8334 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8335 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8336 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8337 /* Front Mic pin: input vref at 80% */
8338 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8339 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8340 /* Speaker: output */
8341 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8342 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8343 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8344 /* Headphone output (output 0 - 0x0c) */
8345 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8346 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8347 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8348
8349 /* FIXME: use matrix-type input source selection */
8350 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8351 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8352 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8353 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8354 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8356 /* Input mixer2 */
8357 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8358 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8359 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8360 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8361 /* Input mixer3 */
8362 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8363 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8364 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8365 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8366 /* ADC1: mute amp left and right */
8367 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8368 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8369 /* ADC2: mute amp left and right */
8370 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8371 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8372 /* ADC3: mute amp left and right */
8373 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8374 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8375
8376 { }
8377};
f12ab1e0 8378
41d5545d
KS
8379/* Macbook 5,1 */
8380static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8381 /* DACs */
8382 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8383 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8384 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8385 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8386 /* Front mixer */
41d5545d
KS
8387 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8388 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8389 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8390 /* Surround mixer */
8391 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8392 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8393 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8394 /* LFE mixer */
8395 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8396 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8397 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8398 /* HP mixer */
8399 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8400 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8401 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8402 /* Front Pin (0x0c) */
41d5545d
KS
8403 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8404 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8405 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8406 /* LFE Pin (0x0e) */
8407 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8408 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8409 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8410 /* HP Pin (0x0f) */
41d5545d
KS
8411 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8412 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8413 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8414 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8415 /* Front Mic pin: input vref at 80% */
8416 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8417 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8418 /* Line In pin */
8419 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8420 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8421
b8f171e7
AM
8422 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8423 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8424 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8425 { }
8426};
8427
e458b1fa
LY
8428/* Macmini 3,1 */
8429static struct hda_verb alc885_macmini3_init_verbs[] = {
8430 /* DACs */
8431 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8432 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8433 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8434 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8435 /* Front mixer */
8436 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8437 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8438 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8439 /* Surround mixer */
8440 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8441 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8442 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8443 /* LFE mixer */
8444 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8445 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8446 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8447 /* HP mixer */
8448 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8449 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8450 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8451 /* Front Pin (0x0c) */
8452 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8453 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8454 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8455 /* LFE Pin (0x0e) */
8456 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8457 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8458 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8459 /* HP Pin (0x0f) */
8460 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8461 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8462 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8463 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8464 /* Line In pin */
8465 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8466 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8467
8468 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8469 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8470 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8471 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8472 { }
8473};
8474
76e6f5a9
RH
8475
8476static struct hda_verb alc885_mba21_init_verbs[] = {
8477 /*Internal and HP Speaker Mixer*/
8478 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8479 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8480 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8481 /*Internal Speaker Pin (0x0c)*/
8482 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8483 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8484 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8485 /* HP Pin: output 0 (0x0e) */
8486 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8487 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8488 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8489 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8490 /* Line in (is hp when jack connected)*/
8491 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8492 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8493
8494 { }
8495 };
8496
8497
87350ad0
TI
8498/* Macbook Pro rev3 */
8499static struct hda_verb alc885_mbp3_init_verbs[] = {
8500 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8501 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8502 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8503 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8504 /* Rear mixer */
8505 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8506 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8507 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8508 /* HP mixer */
8509 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8510 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8511 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8512 /* Front Pin: output 0 (0x0c) */
8513 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8514 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8515 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8516 /* HP Pin: output 0 (0x0e) */
87350ad0 8517 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8518 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8519 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8520 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8521 /* Mic (rear) pin: input vref at 80% */
8522 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8523 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8524 /* Front Mic pin: input vref at 80% */
8525 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8526 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8527 /* Line In pin: use output 1 when in LineOut mode */
8528 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8529 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8530 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8531
8532 /* FIXME: use matrix-type input source selection */
8533 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8534 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8535 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8536 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8537 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8538 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8539 /* Input mixer2 */
8540 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8541 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8542 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8543 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8544 /* Input mixer3 */
8545 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8546 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8547 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8548 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8549 /* ADC1: mute amp left and right */
8550 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8551 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8552 /* ADC2: mute amp left and right */
8553 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8554 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8555 /* ADC3: mute amp left and right */
8556 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8557 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8558
8559 { }
8560};
8561
4b7e1803
JM
8562/* iMac 9,1 */
8563static struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8564 /* Internal Speaker Pin (0x0c) */
8565 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8566 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8567 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8568 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8569 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8570 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8571 /* HP Pin: Rear */
4b7e1803
JM
8572 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8573 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8574 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8575 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8576 /* Line in Rear */
8577 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8578 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8579 /* Front Mic pin: input vref at 80% */
8580 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8581 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8582 /* Rear mixer */
8583 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8584 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8585 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8586 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8587 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8588 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8589 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8590 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8591 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8592 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8593 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8594 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8595 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8596 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8597 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8598 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8599 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8600 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8601 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8602 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8603 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8604 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8605 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8606 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8607 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8608 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8609 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8610 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8611 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8612 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8613 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8614 { }
8615};
8616
c54728d8
NF
8617/* iMac 24 mixer. */
8618static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8619 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8620 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8621 { } /* end */
8622};
8623
8624/* iMac 24 init verbs. */
8625static struct hda_verb alc885_imac24_init_verbs[] = {
8626 /* Internal speakers: output 0 (0x0c) */
8627 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8628 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8629 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8630 /* Internal speakers: output 0 (0x0c) */
8631 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8632 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8633 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8634 /* Headphone: output 0 (0x0c) */
8635 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8636 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8637 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8638 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8639 /* Front Mic: input vref at 80% */
8640 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8641 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8642 { }
8643};
8644
8645/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8646static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8647{
a9fd4f3f 8648 struct alc_spec *spec = codec->spec;
c54728d8 8649
a9fd4f3f
TI
8650 spec->autocfg.hp_pins[0] = 0x14;
8651 spec->autocfg.speaker_pins[0] = 0x18;
8652 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8653}
8654
9d54f08b
TI
8655#define alc885_mb5_setup alc885_imac24_setup
8656#define alc885_macmini3_setup alc885_imac24_setup
8657
76e6f5a9
RH
8658/* Macbook Air 2,1 */
8659static void alc885_mba21_setup(struct hda_codec *codec)
8660{
8661 struct alc_spec *spec = codec->spec;
8662
8663 spec->autocfg.hp_pins[0] = 0x14;
8664 spec->autocfg.speaker_pins[0] = 0x18;
8665}
8666
8667
8668
4f5d1706 8669static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8670{
a9fd4f3f 8671 struct alc_spec *spec = codec->spec;
87350ad0 8672
a9fd4f3f
TI
8673 spec->autocfg.hp_pins[0] = 0x15;
8674 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8675}
8676
9d54f08b 8677static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8678{
9d54f08b 8679 struct alc_spec *spec = codec->spec;
4b7e1803 8680
9d54f08b 8681 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8682 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8683 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8684}
87350ad0 8685
272a527c
KY
8686static struct hda_verb alc882_targa_verbs[] = {
8687 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8688 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8689
8690 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8691 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8692
272a527c
KY
8693 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8694 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8695 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8696
8697 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8698 { } /* end */
8699};
8700
8701/* toggle speaker-output according to the hp-jack state */
8702static void alc882_targa_automute(struct hda_codec *codec)
8703{
a9fd4f3f
TI
8704 struct alc_spec *spec = codec->spec;
8705 alc_automute_amp(codec);
82beb8fd 8706 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8707 spec->jack_present ? 1 : 3);
8708}
8709
4f5d1706 8710static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8711{
8712 struct alc_spec *spec = codec->spec;
8713
8714 spec->autocfg.hp_pins[0] = 0x14;
8715 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8716}
8717
8718static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8719{
a9fd4f3f 8720 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8721 alc882_targa_automute(codec);
272a527c
KY
8722}
8723
8724static struct hda_verb alc882_asus_a7j_verbs[] = {
8725 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8726 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8727
8728 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8729 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8730 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8731
272a527c
KY
8732 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8733 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8734 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8735
8736 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8737 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8738 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8739 { } /* end */
8740};
8741
914759b7
TI
8742static struct hda_verb alc882_asus_a7m_verbs[] = {
8743 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8744 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8745
8746 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8747 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8748 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8749
914759b7
TI
8750 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8751 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8752 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8753
8754 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8755 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8756 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8757 { } /* end */
8758};
8759
9102cd1c
TD
8760static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8761{
8762 unsigned int gpiostate, gpiomask, gpiodir;
8763
8764 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8765 AC_VERB_GET_GPIO_DATA, 0);
8766
8767 if (!muted)
8768 gpiostate |= (1 << pin);
8769 else
8770 gpiostate &= ~(1 << pin);
8771
8772 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8773 AC_VERB_GET_GPIO_MASK, 0);
8774 gpiomask |= (1 << pin);
8775
8776 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8777 AC_VERB_GET_GPIO_DIRECTION, 0);
8778 gpiodir |= (1 << pin);
8779
8780
8781 snd_hda_codec_write(codec, codec->afg, 0,
8782 AC_VERB_SET_GPIO_MASK, gpiomask);
8783 snd_hda_codec_write(codec, codec->afg, 0,
8784 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8785
8786 msleep(1);
8787
8788 snd_hda_codec_write(codec, codec->afg, 0,
8789 AC_VERB_SET_GPIO_DATA, gpiostate);
8790}
8791
7debbe51
TI
8792/* set up GPIO at initialization */
8793static void alc885_macpro_init_hook(struct hda_codec *codec)
8794{
8795 alc882_gpio_mute(codec, 0, 0);
8796 alc882_gpio_mute(codec, 1, 0);
8797}
8798
8799/* set up GPIO and update auto-muting at initialization */
8800static void alc885_imac24_init_hook(struct hda_codec *codec)
8801{
8802 alc885_macpro_init_hook(codec);
4f5d1706 8803 alc_automute_amp(codec);
7debbe51
TI
8804}
8805
df694daa
KY
8806/*
8807 * generic initialization of ADC, input mixers and output mixers
8808 */
4953550a 8809static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8810 /*
8811 * Unmute ADC0-2 and set the default input to mic-in
8812 */
4953550a
TI
8813 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8814 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8815 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8816 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8817
4953550a
TI
8818 /*
8819 * Set up output mixers (0x0c - 0x0f)
8820 */
8821 /* set vol=0 to output mixers */
8822 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8823 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8824 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8825 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8826 /* set up input amps for analog loopback */
8827 /* Amp Indices: DAC = 0, mixer = 1 */
8828 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8829 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8830 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8831 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8832 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8833 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8834 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8835 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8836 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8837 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8838
4953550a
TI
8839 /* FIXME: use matrix-type input source selection */
8840 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8841 /* Input mixer2 */
88102f3f 8842 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8843 /* Input mixer3 */
88102f3f 8844 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8845 { }
9c7f852e
TI
8846};
8847
eb4c41d3
TS
8848/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8849static struct hda_verb alc889A_mb31_ch2_init[] = {
8850 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8851 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8852 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8853 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8854 { } /* end */
8855};
8856
8857/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8858static struct hda_verb alc889A_mb31_ch4_init[] = {
8859 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8860 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8861 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8862 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8863 { } /* end */
8864};
8865
8866/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8867static struct hda_verb alc889A_mb31_ch5_init[] = {
8868 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8869 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8870 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8871 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8872 { } /* end */
8873};
8874
8875/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8876static struct hda_verb alc889A_mb31_ch6_init[] = {
8877 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8878 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8879 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8880 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8881 { } /* end */
8882};
8883
8884static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8885 { 2, alc889A_mb31_ch2_init },
8886 { 4, alc889A_mb31_ch4_init },
8887 { 5, alc889A_mb31_ch5_init },
8888 { 6, alc889A_mb31_ch6_init },
8889};
8890
b373bdeb
AN
8891static struct hda_verb alc883_medion_eapd_verbs[] = {
8892 /* eanable EAPD on medion laptop */
8893 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8894 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8895 { }
8896};
8897
4953550a 8898#define alc883_base_mixer alc882_base_mixer
834be88d 8899
a8848bd6
AS
8900static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8901 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8902 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8903 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8904 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8905 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8906 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8907 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8908 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8909 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
a8848bd6
AS
8910 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8911 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8912 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
a8848bd6 8913 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8914 { } /* end */
8915};
8916
0c4cc443 8917static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8918 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8919 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8920 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8921 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8922 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8923 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
368c7a95 8924 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8925 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8926 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8927 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8928 { } /* end */
8929};
8930
fb97dc67
J
8931static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8932 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8933 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8934 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8935 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8936 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8937 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
fb97dc67 8938 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8939 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8940 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8941 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8942 { } /* end */
8943};
8944
9c7f852e
TI
8945static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8946 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8947 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8948 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8949 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8950 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8951 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8952 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8953 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8954 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8955 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8956 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8957 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8958 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8959 { } /* end */
8960};
df694daa 8961
9c7f852e
TI
8962static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8963 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8964 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8965 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8966 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8967 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8968 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8969 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8970 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8971 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8972 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8973 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8974 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8975 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8977 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8978 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8979 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8980 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8981 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8982 { } /* end */
8983};
8984
17bba1b7
J
8985static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8986 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8987 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8988 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8989 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8990 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8991 HDA_OUTPUT),
8992 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8993 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8994 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8995 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8996 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8997 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8998 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8999 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9000 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9001 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
17bba1b7
J
9002 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9003 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9004 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
17bba1b7 9005 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
9006 { } /* end */
9007};
9008
87a8c370
JK
9009static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
9010 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9011 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9012 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9013 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9014 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9015 HDA_OUTPUT),
9016 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9017 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9018 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9019 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9020 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9021 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9022 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9023 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9024 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
5f99f86a 9025 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
87a8c370
JK
9026 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9027 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9028 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
87a8c370
JK
9029 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9030 { } /* end */
9031};
9032
d1d985f0 9033static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 9034 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 9035 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 9036 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 9037 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
9038 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9039 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
9040 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9041 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
9042 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9043 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9044 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9045 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9046 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9047 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9048 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
c07584c8
TD
9049 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9050 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9051 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
c07584c8 9052 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
9053 { } /* end */
9054};
9055
c259249f 9056static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 9057 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9058 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9059 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9060 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9061 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9062 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9063 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9064 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9065 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9066 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9067 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9068 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9069 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9070 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9071 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9072 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9073 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 9074 { } /* end */
f12ab1e0 9075};
ccc656ce 9076
c259249f 9077static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 9078 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9079 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9080 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9081 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9082 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9083 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9084 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9085 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9086 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9087 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9088 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9089 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 9090 { } /* end */
f12ab1e0 9091};
ccc656ce 9092
b99dba34
TI
9093static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9094 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9095 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
28c4edb7 9096 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9097 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9098 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
b99dba34
TI
9099 { } /* end */
9100};
9101
bc9f98a9
KY
9102static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9103 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9104 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
9105 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9106 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
9107 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9108 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9109 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bc9f98a9 9110 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 9111 { } /* end */
f12ab1e0 9112};
bc9f98a9 9113
272a527c
KY
9114static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9115 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9116 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9117 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9118 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9119 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9120 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9121 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
9122 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9123 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c 9124 { } /* end */
ea1fb29a 9125};
272a527c 9126
7ad7b218
MC
9127static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9128 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9129 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9130 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9131 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9132 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9133 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9134 { } /* end */
9135};
9136
9137static struct hda_verb alc883_medion_wim2160_verbs[] = {
9138 /* Unmute front mixer */
9139 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9140 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9141
9142 /* Set speaker pin to front mixer */
9143 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9144
9145 /* Init headphone pin */
9146 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9147 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9148 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9149 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9150
9151 { } /* end */
9152};
9153
9154/* toggle speaker-output according to the hp-jack state */
9155static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9156{
9157 struct alc_spec *spec = codec->spec;
9158
9159 spec->autocfg.hp_pins[0] = 0x1a;
9160 spec->autocfg.speaker_pins[0] = 0x15;
9161}
9162
2880a867 9163static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
9164 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9165 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 9166 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
9167 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9168 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6 9169 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9170 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d1a991a6 9171 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 9172 { } /* end */
d1a991a6 9173};
2880a867 9174
d2fd4b09
TV
9175static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9176 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 9177 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
9178 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9179 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
9180 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9181 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9182 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9183 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d2fd4b09
TV
9184 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9185 { } /* end */
9186};
9187
e2757d5e
KY
9188static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9189 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9190 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9191 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9192 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9193 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9194 0x0d, 1, 0x0, HDA_OUTPUT),
9195 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9196 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9197 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9198 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9199 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
9200 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9201 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9202 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9203 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9204 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9205 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e2757d5e
KY
9206 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9207 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9208 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
e2757d5e 9209 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9210 { } /* end */
9211};
9212
eb4c41d3
TS
9213static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9214 /* Output mixers */
9215 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9216 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9217 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9218 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9219 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9220 HDA_OUTPUT),
9221 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9222 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9223 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9224 /* Output switches */
9225 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9226 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9227 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9228 /* Boost mixers */
5f99f86a
DH
9229 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9230 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
eb4c41d3
TS
9231 /* Input mixers */
9232 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9233 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9234 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9235 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9236 { } /* end */
9237};
9238
3e1647c5
GG
9239static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9240 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9241 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9242 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9243 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9244 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
3e1647c5
GG
9245 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9246 { } /* end */
9247};
9248
e2757d5e
KY
9249static struct hda_bind_ctls alc883_bind_cap_vol = {
9250 .ops = &snd_hda_bind_vol,
9251 .values = {
9252 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9253 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9254 0
9255 },
9256};
9257
9258static struct hda_bind_ctls alc883_bind_cap_switch = {
9259 .ops = &snd_hda_bind_sw,
9260 .values = {
9261 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9262 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9263 0
9264 },
9265};
9266
9267static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9268 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9269 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9270 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9271 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9272 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9273 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9274 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
4953550a
TI
9275 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9276 { } /* end */
9277};
df694daa 9278
4953550a
TI
9279static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9280 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9281 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9282 {
9283 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9284 /* .name = "Capture Source", */
9285 .name = "Input Source",
9286 .count = 1,
9287 .info = alc_mux_enum_info,
9288 .get = alc_mux_enum_get,
9289 .put = alc_mux_enum_put,
9290 },
9291 { } /* end */
9292};
9c7f852e 9293
4953550a
TI
9294static struct snd_kcontrol_new alc883_chmode_mixer[] = {
9295 {
9296 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9297 .name = "Channel Mode",
9298 .info = alc_ch_mode_info,
9299 .get = alc_ch_mode_get,
9300 .put = alc_ch_mode_put,
9301 },
9302 { } /* end */
9c7f852e
TI
9303};
9304
a8848bd6 9305/* toggle speaker-output according to the hp-jack state */
4f5d1706 9306static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9307{
a9fd4f3f 9308 struct alc_spec *spec = codec->spec;
a8848bd6 9309
a9fd4f3f
TI
9310 spec->autocfg.hp_pins[0] = 0x15;
9311 spec->autocfg.speaker_pins[0] = 0x14;
9312 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
9313}
9314
a8848bd6
AS
9315static struct hda_verb alc883_mitac_verbs[] = {
9316 /* HP */
9317 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9318 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9319 /* Subwoofer */
9320 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9321 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9322
9323 /* enable unsolicited event */
9324 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9325 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9326
9327 { } /* end */
9328};
9329
a65cc60f 9330static struct hda_verb alc883_clevo_m540r_verbs[] = {
9331 /* HP */
9332 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9333 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9334 /* Int speaker */
9335 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9336
9337 /* enable unsolicited event */
9338 /*
9339 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9340 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9341 */
9342
9343 { } /* end */
9344};
9345
0c4cc443 9346static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9347 /* HP */
9348 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9349 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9350 /* Int speaker */
9351 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9352 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9353
9354 /* enable unsolicited event */
9355 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9356 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9357
9358 { } /* end */
9359};
9360
fb97dc67
J
9361static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9362 /* HP */
9363 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9364 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9365 /* Subwoofer */
9366 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9367 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9368
9369 /* enable unsolicited event */
9370 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9371
9372 { } /* end */
9373};
9374
c259249f 9375static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
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
9379 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9380 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9381
64a8be74
DH
9382/* Connect Line-Out side jack (SPDIF) to Side */
9383 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9384 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9385 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9386/* Connect Mic jack to CLFE */
9387 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9388 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9389 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9390/* Connect Line-in jack to Surround */
9391 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9392 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9393 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9394/* Connect HP out jack to Front */
9395 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9396 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9397 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9398
9399 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9400
9401 { } /* end */
9402};
9403
bc9f98a9
KY
9404static struct hda_verb alc883_lenovo_101e_verbs[] = {
9405 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9406 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9407 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9408 { } /* end */
9409};
9410
272a527c
KY
9411static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9412 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9413 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9414 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9415 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9416 { } /* end */
9417};
9418
9419static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9420 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9421 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9422 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9423 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9424 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9425 { } /* end */
9426};
9427
189609ae
KY
9428static struct hda_verb alc883_haier_w66_verbs[] = {
9429 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9430 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9431
9432 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9433
9434 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9435 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9436 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9437 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9438 { } /* end */
9439};
9440
e2757d5e
KY
9441static struct hda_verb alc888_lenovo_sky_verbs[] = {
9442 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9443 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9444 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9445 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9446 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9447 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9448 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9449 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9450 { } /* end */
9451};
9452
8718b700
HRK
9453static struct hda_verb alc888_6st_dell_verbs[] = {
9454 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9455 { }
9456};
9457
3e1647c5
GG
9458static struct hda_verb alc883_vaiott_verbs[] = {
9459 /* HP */
9460 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9461 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9462
9463 /* enable unsolicited event */
9464 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9465
9466 { } /* end */
9467};
9468
4f5d1706 9469static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9470{
a9fd4f3f 9471 struct alc_spec *spec = codec->spec;
8718b700 9472
a9fd4f3f
TI
9473 spec->autocfg.hp_pins[0] = 0x1b;
9474 spec->autocfg.speaker_pins[0] = 0x14;
9475 spec->autocfg.speaker_pins[1] = 0x16;
9476 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
9477}
9478
4723c022 9479static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9480 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9481 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9482 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9483 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9484 { } /* end */
5795b9e6
CM
9485};
9486
3ea0d7cf
HRK
9487/*
9488 * 2ch mode
9489 */
4723c022 9490static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9491 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9492 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9493 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9494 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9495 { } /* end */
8341de60
CM
9496};
9497
3ea0d7cf
HRK
9498/*
9499 * 4ch mode
9500 */
9501static struct hda_verb alc888_3st_hp_4ch_init[] = {
9502 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9503 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9504 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9505 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9506 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9507 { } /* end */
9508};
9509
9510/*
9511 * 6ch mode
9512 */
4723c022 9513static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9514 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9515 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9516 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9517 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9518 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9519 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9520 { } /* end */
8341de60
CM
9521};
9522
3ea0d7cf 9523static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9524 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9525 { 4, alc888_3st_hp_4ch_init },
4723c022 9526 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9527};
9528
272a527c
KY
9529/* toggle front-jack and RCA according to the hp-jack state */
9530static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9531{
864f92be 9532 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 9533
47fd830a
TI
9534 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9535 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9536 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9537 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
9538}
9539
9540/* toggle RCA according to the front-jack state */
9541static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9542{
864f92be 9543 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 9544
47fd830a
TI
9545 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9546 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 9547}
47fd830a 9548
272a527c
KY
9549static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9550 unsigned int res)
9551{
9552 if ((res >> 26) == ALC880_HP_EVENT)
9553 alc888_lenovo_ms7195_front_automute(codec);
9554 if ((res >> 26) == ALC880_FRONT_EVENT)
9555 alc888_lenovo_ms7195_rca_automute(codec);
9556}
9557
272a527c 9558/* toggle speaker-output according to the hp-jack state */
dc427170 9559static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
272a527c 9560{
a9fd4f3f 9561 struct alc_spec *spec = codec->spec;
272a527c 9562
a9fd4f3f
TI
9563 spec->autocfg.hp_pins[0] = 0x14;
9564 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
9565}
9566
ccc656ce 9567/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9568#define alc883_targa_init_hook alc882_targa_init_hook
9569#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9570
4f5d1706 9571static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9572{
a9fd4f3f
TI
9573 struct alc_spec *spec = codec->spec;
9574
9575 spec->autocfg.hp_pins[0] = 0x15;
9576 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
9577}
9578
9579static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9580{
a9fd4f3f 9581 alc_automute_amp(codec);
eeb43387 9582 alc88x_simple_mic_automute(codec);
0c4cc443
HRK
9583}
9584
9585static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9586 unsigned int res)
9587{
0c4cc443 9588 switch (res >> 26) {
0c4cc443 9589 case ALC880_MIC_EVENT:
eeb43387 9590 alc88x_simple_mic_automute(codec);
0c4cc443 9591 break;
a9fd4f3f
TI
9592 default:
9593 alc_automute_amp_unsol_event(codec, res);
9594 break;
0c4cc443 9595 }
368c7a95
J
9596}
9597
fb97dc67 9598/* toggle speaker-output according to the hp-jack state */
4f5d1706 9599static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9600{
a9fd4f3f 9601 struct alc_spec *spec = codec->spec;
fb97dc67 9602
a9fd4f3f
TI
9603 spec->autocfg.hp_pins[0] = 0x14;
9604 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9605}
9606
4f5d1706 9607static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9608{
a9fd4f3f 9609 struct alc_spec *spec = codec->spec;
189609ae 9610
a9fd4f3f
TI
9611 spec->autocfg.hp_pins[0] = 0x1b;
9612 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9613}
9614
bc9f98a9
KY
9615static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9616{
864f92be 9617 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9618
47fd830a
TI
9619 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9620 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9621}
9622
9623static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9624{
864f92be 9625 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9626
47fd830a
TI
9627 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9628 HDA_AMP_MUTE, bits);
9629 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9630 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9631}
9632
9633static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9634 unsigned int res)
9635{
9636 if ((res >> 26) == ALC880_HP_EVENT)
9637 alc883_lenovo_101e_all_automute(codec);
9638 if ((res >> 26) == ALC880_FRONT_EVENT)
9639 alc883_lenovo_101e_ispeaker_automute(codec);
9640}
9641
676a9b53 9642/* toggle speaker-output according to the hp-jack state */
4f5d1706 9643static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9644{
a9fd4f3f 9645 struct alc_spec *spec = codec->spec;
676a9b53 9646
a9fd4f3f
TI
9647 spec->autocfg.hp_pins[0] = 0x14;
9648 spec->autocfg.speaker_pins[0] = 0x15;
9649 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9650}
9651
d1a991a6
KY
9652static struct hda_verb alc883_acer_eapd_verbs[] = {
9653 /* HP Pin: output 0 (0x0c) */
9654 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9655 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9656 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9657 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9658 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9659 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9660 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9661 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9662 /* eanable EAPD on medion laptop */
9663 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9664 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9665 /* enable unsolicited event */
9666 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9667 { }
9668};
9669
4f5d1706 9670static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9671{
a9fd4f3f 9672 struct alc_spec *spec = codec->spec;
5795b9e6 9673
a9fd4f3f
TI
9674 spec->autocfg.hp_pins[0] = 0x1b;
9675 spec->autocfg.speaker_pins[0] = 0x14;
9676 spec->autocfg.speaker_pins[1] = 0x15;
9677 spec->autocfg.speaker_pins[2] = 0x16;
9678 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9679}
9680
4f5d1706 9681static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9682{
a9fd4f3f 9683 struct alc_spec *spec = codec->spec;
e2757d5e 9684
a9fd4f3f
TI
9685 spec->autocfg.hp_pins[0] = 0x1b;
9686 spec->autocfg.speaker_pins[0] = 0x14;
9687 spec->autocfg.speaker_pins[1] = 0x15;
9688 spec->autocfg.speaker_pins[2] = 0x16;
9689 spec->autocfg.speaker_pins[3] = 0x17;
9690 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9691}
9692
4f5d1706 9693static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9694{
9695 struct alc_spec *spec = codec->spec;
9696
9697 spec->autocfg.hp_pins[0] = 0x15;
9698 spec->autocfg.speaker_pins[0] = 0x14;
9699 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9700}
9701
e2757d5e
KY
9702static struct hda_verb alc888_asus_m90v_verbs[] = {
9703 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9704 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9705 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9706 /* enable unsolicited event */
9707 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9708 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9709 { } /* end */
9710};
9711
4f5d1706 9712static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9713{
a9fd4f3f 9714 struct alc_spec *spec = codec->spec;
e2757d5e 9715
a9fd4f3f
TI
9716 spec->autocfg.hp_pins[0] = 0x1b;
9717 spec->autocfg.speaker_pins[0] = 0x14;
9718 spec->autocfg.speaker_pins[1] = 0x15;
9719 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9720 spec->ext_mic.pin = 0x18;
9721 spec->int_mic.pin = 0x19;
9722 spec->ext_mic.mux_idx = 0;
9723 spec->int_mic.mux_idx = 1;
9724 spec->auto_mic = 1;
e2757d5e
KY
9725}
9726
9727static struct hda_verb alc888_asus_eee1601_verbs[] = {
9728 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9729 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9730 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9731 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9732 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9733 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9734 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9735 /* enable unsolicited event */
9736 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9737 { } /* end */
9738};
9739
e2757d5e
KY
9740static void alc883_eee1601_inithook(struct hda_codec *codec)
9741{
a9fd4f3f
TI
9742 struct alc_spec *spec = codec->spec;
9743
9744 spec->autocfg.hp_pins[0] = 0x14;
9745 spec->autocfg.speaker_pins[0] = 0x1b;
9746 alc_automute_pin(codec);
e2757d5e
KY
9747}
9748
eb4c41d3
TS
9749static struct hda_verb alc889A_mb31_verbs[] = {
9750 /* Init rear pin (used as headphone output) */
9751 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9752 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9753 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9754 /* Init line pin (used as output in 4ch and 6ch mode) */
9755 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9756 /* Init line 2 pin (used as headphone out by default) */
9757 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9758 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9759 { } /* end */
9760};
9761
9762/* Mute speakers according to the headphone jack state */
9763static void alc889A_mb31_automute(struct hda_codec *codec)
9764{
9765 unsigned int present;
9766
9767 /* Mute only in 2ch or 4ch mode */
9768 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9769 == 0x00) {
864f92be 9770 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9771 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9772 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9773 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9774 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9775 }
9776}
9777
9778static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9779{
9780 if ((res >> 26) == ALC880_HP_EVENT)
9781 alc889A_mb31_automute(codec);
9782}
9783
4953550a 9784
cb53c626 9785#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9786#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9787#endif
9788
def319f9 9789/* pcm configuration: identical with ALC880 */
4953550a
TI
9790#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9791#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9792#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9793#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9794
9795static hda_nid_t alc883_slave_dig_outs[] = {
9796 ALC1200_DIGOUT_NID, 0,
9797};
9798
9799static hda_nid_t alc1200_slave_dig_outs[] = {
9800 ALC883_DIGOUT_NID, 0,
9801};
9c7f852e
TI
9802
9803/*
9804 * configuration and preset
9805 */
ea734963 9806static const char * const alc882_models[ALC882_MODEL_LAST] = {
4953550a
TI
9807 [ALC882_3ST_DIG] = "3stack-dig",
9808 [ALC882_6ST_DIG] = "6stack-dig",
9809 [ALC882_ARIMA] = "arima",
9810 [ALC882_W2JC] = "w2jc",
9811 [ALC882_TARGA] = "targa",
9812 [ALC882_ASUS_A7J] = "asus-a7j",
9813 [ALC882_ASUS_A7M] = "asus-a7m",
9814 [ALC885_MACPRO] = "macpro",
9815 [ALC885_MB5] = "mb5",
e458b1fa 9816 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9817 [ALC885_MBA21] = "mba21",
4953550a
TI
9818 [ALC885_MBP3] = "mbp3",
9819 [ALC885_IMAC24] = "imac24",
4b7e1803 9820 [ALC885_IMAC91] = "imac91",
4953550a 9821 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9822 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9823 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9824 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9825 [ALC883_TARGA_DIG] = "targa-dig",
9826 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9827 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9828 [ALC883_ACER] = "acer",
2880a867 9829 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9830 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9831 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9832 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9833 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9834 [ALC883_MEDION] = "medion",
7ad7b218 9835 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9836 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9837 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9838 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9839 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9840 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9841 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9842 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9843 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9844 [ALC883_MITAC] = "mitac",
a65cc60f 9845 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9846 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9847 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9848 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9849 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9850 [ALC889A_INTEL] = "intel-alc889a",
9851 [ALC889_INTEL] = "intel-x58",
3ab90935 9852 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9853 [ALC889A_MB31] = "mb31",
3e1647c5 9854 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9855 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9856};
9857
4953550a
TI
9858static struct snd_pci_quirk alc882_cfg_tbl[] = {
9859 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9860
ac3e3741 9861 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9862 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9863 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9864 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9865 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9866 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9867 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9868 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9869 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9870 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9871 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9872 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9873 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9874 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9875 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9876 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9877 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9878 ALC888_ACER_ASPIRE_6530G),
cc374c47 9879 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9880 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9881 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9882 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9883 /* default Acer -- disabled as it causes more problems.
9884 * model=auto should work fine now
9885 */
9886 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9887
5795b9e6 9888 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9889
febe3375 9890 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9891 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9892 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9893 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9894 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9895 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9896
9897 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9898 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9899 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9900 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9901 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9902 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9903 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9904 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9905 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9906 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9907 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9908
9909 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9910 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9911 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9912 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9913 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9914 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9915 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9916 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9917 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9918
6f3bf657 9919 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9920 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9921 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9922 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9923 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9924 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9925 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9926 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9927 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9928 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9929 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9930 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9931 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9932 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9933 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9934 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9935 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9936 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9937 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9938 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9939 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9940 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9941 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9942 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9943 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9944 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9945 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9946 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9947 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9948 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9949 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9950
ac3e3741 9951 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9952 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9953 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9954 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9955 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9956 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9957 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9958 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9959 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9960 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9961 ALC883_FUJITSU_PI2515),
bfb53037 9962 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9963 ALC888_FUJITSU_XA3530),
272a527c 9964 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9965 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9966 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9967 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9968 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
959973b9 9969 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9970 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9971 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9972
17bba1b7
J
9973 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9974 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9975 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9976 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9977 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9978 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9979 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9980
4953550a 9981 {}
f3cd3f5d
WF
9982};
9983
4953550a
TI
9984/* codec SSID table for Intel Mac */
9985static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9986 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9987 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9988 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9989 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9990 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9991 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9992 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 9993 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 9994 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 9995 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 9996 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
9997 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9998 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9999 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 10000 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 10001 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 10002 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
10003 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10004 * so apparently no perfect solution yet
4953550a
TI
10005 */
10006 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 10007 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 10008 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 10009 {} /* terminator */
b25c9da1
WF
10010};
10011
4953550a
TI
10012static struct alc_config_preset alc882_presets[] = {
10013 [ALC882_3ST_DIG] = {
10014 .mixers = { alc882_base_mixer },
8ab9e0af
TI
10015 .init_verbs = { alc882_base_init_verbs,
10016 alc882_adc1_init_verbs },
4953550a
TI
10017 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10018 .dac_nids = alc882_dac_nids,
10019 .dig_out_nid = ALC882_DIGOUT_NID,
10020 .dig_in_nid = ALC882_DIGIN_NID,
10021 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10022 .channel_mode = alc882_ch_modes,
10023 .need_dac_fix = 1,
10024 .input_mux = &alc882_capture_source,
10025 },
10026 [ALC882_6ST_DIG] = {
10027 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10028 .init_verbs = { alc882_base_init_verbs,
10029 alc882_adc1_init_verbs },
4953550a
TI
10030 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10031 .dac_nids = alc882_dac_nids,
10032 .dig_out_nid = ALC882_DIGOUT_NID,
10033 .dig_in_nid = ALC882_DIGIN_NID,
10034 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10035 .channel_mode = alc882_sixstack_modes,
10036 .input_mux = &alc882_capture_source,
10037 },
10038 [ALC882_ARIMA] = {
10039 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10040 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10041 alc882_eapd_verbs },
4953550a
TI
10042 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10043 .dac_nids = alc882_dac_nids,
10044 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10045 .channel_mode = alc882_sixstack_modes,
10046 .input_mux = &alc882_capture_source,
10047 },
10048 [ALC882_W2JC] = {
10049 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10050 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10051 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
10052 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10053 .dac_nids = alc882_dac_nids,
10054 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10055 .channel_mode = alc880_threestack_modes,
10056 .need_dac_fix = 1,
10057 .input_mux = &alc882_capture_source,
10058 .dig_out_nid = ALC882_DIGOUT_NID,
10059 },
76e6f5a9
RH
10060 [ALC885_MBA21] = {
10061 .mixers = { alc885_mba21_mixer },
10062 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10063 .num_dacs = 2,
10064 .dac_nids = alc882_dac_nids,
10065 .channel_mode = alc885_mba21_ch_modes,
10066 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10067 .input_mux = &alc882_capture_source,
10068 .unsol_event = alc_automute_amp_unsol_event,
10069 .setup = alc885_mba21_setup,
10070 .init_hook = alc_automute_amp,
10071 },
4953550a
TI
10072 [ALC885_MBP3] = {
10073 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10074 .init_verbs = { alc885_mbp3_init_verbs,
10075 alc880_gpio1_init_verbs },
be0ae923 10076 .num_dacs = 2,
4953550a 10077 .dac_nids = alc882_dac_nids,
be0ae923
TI
10078 .hp_nid = 0x04,
10079 .channel_mode = alc885_mbp_4ch_modes,
10080 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
10081 .input_mux = &alc882_capture_source,
10082 .dig_out_nid = ALC882_DIGOUT_NID,
10083 .dig_in_nid = ALC882_DIGIN_NID,
10084 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10085 .setup = alc885_mbp3_setup,
10086 .init_hook = alc_automute_amp,
4953550a
TI
10087 },
10088 [ALC885_MB5] = {
10089 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10090 .init_verbs = { alc885_mb5_init_verbs,
10091 alc880_gpio1_init_verbs },
10092 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10093 .dac_nids = alc882_dac_nids,
10094 .channel_mode = alc885_mb5_6ch_modes,
10095 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10096 .input_mux = &mb5_capture_source,
10097 .dig_out_nid = ALC882_DIGOUT_NID,
10098 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10099 .unsol_event = alc_automute_amp_unsol_event,
10100 .setup = alc885_mb5_setup,
10101 .init_hook = alc_automute_amp,
4953550a 10102 },
e458b1fa
LY
10103 [ALC885_MACMINI3] = {
10104 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10105 .init_verbs = { alc885_macmini3_init_verbs,
10106 alc880_gpio1_init_verbs },
10107 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10108 .dac_nids = alc882_dac_nids,
10109 .channel_mode = alc885_macmini3_6ch_modes,
10110 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10111 .input_mux = &macmini3_capture_source,
10112 .dig_out_nid = ALC882_DIGOUT_NID,
10113 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10114 .unsol_event = alc_automute_amp_unsol_event,
10115 .setup = alc885_macmini3_setup,
10116 .init_hook = alc_automute_amp,
e458b1fa 10117 },
4953550a
TI
10118 [ALC885_MACPRO] = {
10119 .mixers = { alc882_macpro_mixer },
10120 .init_verbs = { alc882_macpro_init_verbs },
10121 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10122 .dac_nids = alc882_dac_nids,
10123 .dig_out_nid = ALC882_DIGOUT_NID,
10124 .dig_in_nid = ALC882_DIGIN_NID,
10125 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10126 .channel_mode = alc882_ch_modes,
10127 .input_mux = &alc882_capture_source,
10128 .init_hook = alc885_macpro_init_hook,
10129 },
10130 [ALC885_IMAC24] = {
10131 .mixers = { alc885_imac24_mixer },
10132 .init_verbs = { alc885_imac24_init_verbs },
10133 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10134 .dac_nids = alc882_dac_nids,
10135 .dig_out_nid = ALC882_DIGOUT_NID,
10136 .dig_in_nid = ALC882_DIGIN_NID,
10137 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10138 .channel_mode = alc882_ch_modes,
10139 .input_mux = &alc882_capture_source,
10140 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 10141 .setup = alc885_imac24_setup,
4953550a
TI
10142 .init_hook = alc885_imac24_init_hook,
10143 },
4b7e1803 10144 [ALC885_IMAC91] = {
b7cccc52 10145 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
10146 .init_verbs = { alc885_imac91_init_verbs,
10147 alc880_gpio1_init_verbs },
10148 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10149 .dac_nids = alc882_dac_nids,
b7cccc52
JM
10150 .channel_mode = alc885_mba21_ch_modes,
10151 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10152 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
10153 .dig_out_nid = ALC882_DIGOUT_NID,
10154 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
10155 .unsol_event = alc_automute_amp_unsol_event,
10156 .setup = alc885_imac91_setup,
10157 .init_hook = alc_automute_amp,
4b7e1803 10158 },
4953550a
TI
10159 [ALC882_TARGA] = {
10160 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 10161 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 10162 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
10163 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10164 .dac_nids = alc882_dac_nids,
10165 .dig_out_nid = ALC882_DIGOUT_NID,
10166 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10167 .adc_nids = alc882_adc_nids,
10168 .capsrc_nids = alc882_capsrc_nids,
10169 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10170 .channel_mode = alc882_3ST_6ch_modes,
10171 .need_dac_fix = 1,
10172 .input_mux = &alc882_capture_source,
10173 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
10174 .setup = alc882_targa_setup,
10175 .init_hook = alc882_targa_automute,
4953550a
TI
10176 },
10177 [ALC882_ASUS_A7J] = {
10178 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10179 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10180 alc882_asus_a7j_verbs},
4953550a
TI
10181 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10182 .dac_nids = alc882_dac_nids,
10183 .dig_out_nid = ALC882_DIGOUT_NID,
10184 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10185 .adc_nids = alc882_adc_nids,
10186 .capsrc_nids = alc882_capsrc_nids,
10187 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10188 .channel_mode = alc882_3ST_6ch_modes,
10189 .need_dac_fix = 1,
10190 .input_mux = &alc882_capture_source,
10191 },
10192 [ALC882_ASUS_A7M] = {
10193 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10194 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10195 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10196 alc882_asus_a7m_verbs },
10197 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10198 .dac_nids = alc882_dac_nids,
10199 .dig_out_nid = ALC882_DIGOUT_NID,
10200 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10201 .channel_mode = alc880_threestack_modes,
10202 .need_dac_fix = 1,
10203 .input_mux = &alc882_capture_source,
10204 },
9c7f852e
TI
10205 [ALC883_3ST_2ch_DIG] = {
10206 .mixers = { alc883_3ST_2ch_mixer },
10207 .init_verbs = { alc883_init_verbs },
10208 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10209 .dac_nids = alc883_dac_nids,
10210 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10211 .dig_in_nid = ALC883_DIGIN_NID,
10212 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10213 .channel_mode = alc883_3ST_2ch_modes,
10214 .input_mux = &alc883_capture_source,
10215 },
10216 [ALC883_3ST_6ch_DIG] = {
10217 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10218 .init_verbs = { alc883_init_verbs },
10219 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10220 .dac_nids = alc883_dac_nids,
10221 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10222 .dig_in_nid = ALC883_DIGIN_NID,
10223 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10224 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10225 .need_dac_fix = 1,
9c7f852e 10226 .input_mux = &alc883_capture_source,
f12ab1e0 10227 },
9c7f852e
TI
10228 [ALC883_3ST_6ch] = {
10229 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10230 .init_verbs = { alc883_init_verbs },
10231 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10232 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10233 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10234 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10235 .need_dac_fix = 1,
9c7f852e 10236 .input_mux = &alc883_capture_source,
f12ab1e0 10237 },
17bba1b7
J
10238 [ALC883_3ST_6ch_INTEL] = {
10239 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10240 .init_verbs = { alc883_init_verbs },
10241 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10242 .dac_nids = alc883_dac_nids,
10243 .dig_out_nid = ALC883_DIGOUT_NID,
10244 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10245 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10246 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10247 .channel_mode = alc883_3ST_6ch_intel_modes,
10248 .need_dac_fix = 1,
10249 .input_mux = &alc883_3stack_6ch_intel,
10250 },
87a8c370
JK
10251 [ALC889A_INTEL] = {
10252 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10253 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10254 alc_hp15_unsol_verbs },
87a8c370
JK
10255 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10256 .dac_nids = alc883_dac_nids,
10257 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10258 .adc_nids = alc889_adc_nids,
10259 .dig_out_nid = ALC883_DIGOUT_NID,
10260 .dig_in_nid = ALC883_DIGIN_NID,
10261 .slave_dig_outs = alc883_slave_dig_outs,
10262 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10263 .channel_mode = alc889_8ch_intel_modes,
10264 .capsrc_nids = alc889_capsrc_nids,
10265 .input_mux = &alc889_capture_source,
4f5d1706
TI
10266 .setup = alc889_automute_setup,
10267 .init_hook = alc_automute_amp,
6732bd0d 10268 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10269 .need_dac_fix = 1,
10270 },
10271 [ALC889_INTEL] = {
10272 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10273 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10274 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10275 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10276 .dac_nids = alc883_dac_nids,
10277 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10278 .adc_nids = alc889_adc_nids,
10279 .dig_out_nid = ALC883_DIGOUT_NID,
10280 .dig_in_nid = ALC883_DIGIN_NID,
10281 .slave_dig_outs = alc883_slave_dig_outs,
10282 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10283 .channel_mode = alc889_8ch_intel_modes,
10284 .capsrc_nids = alc889_capsrc_nids,
10285 .input_mux = &alc889_capture_source,
4f5d1706 10286 .setup = alc889_automute_setup,
6732bd0d
WF
10287 .init_hook = alc889_intel_init_hook,
10288 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10289 .need_dac_fix = 1,
10290 },
9c7f852e
TI
10291 [ALC883_6ST_DIG] = {
10292 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10293 .init_verbs = { alc883_init_verbs },
10294 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10295 .dac_nids = alc883_dac_nids,
10296 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10297 .dig_in_nid = ALC883_DIGIN_NID,
10298 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10299 .channel_mode = alc883_sixstack_modes,
10300 .input_mux = &alc883_capture_source,
10301 },
ccc656ce 10302 [ALC883_TARGA_DIG] = {
c259249f 10303 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10304 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10305 alc883_targa_verbs},
ccc656ce
KY
10306 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10307 .dac_nids = alc883_dac_nids,
10308 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10309 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10310 .channel_mode = alc883_3ST_6ch_modes,
10311 .need_dac_fix = 1,
10312 .input_mux = &alc883_capture_source,
c259249f 10313 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10314 .setup = alc882_targa_setup,
10315 .init_hook = alc882_targa_automute,
ccc656ce
KY
10316 },
10317 [ALC883_TARGA_2ch_DIG] = {
c259249f 10318 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10319 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10320 alc883_targa_verbs},
ccc656ce
KY
10321 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10322 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10323 .adc_nids = alc883_adc_nids_alt,
10324 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10325 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10326 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10327 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10328 .channel_mode = alc883_3ST_2ch_modes,
10329 .input_mux = &alc883_capture_source,
c259249f 10330 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10331 .setup = alc882_targa_setup,
10332 .init_hook = alc882_targa_automute,
ccc656ce 10333 },
64a8be74 10334 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10335 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10336 alc883_chmode_mixer },
64a8be74 10337 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10338 alc883_targa_verbs },
64a8be74
DH
10339 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10340 .dac_nids = alc883_dac_nids,
10341 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10342 .adc_nids = alc883_adc_nids_rev,
10343 .capsrc_nids = alc883_capsrc_nids_rev,
10344 .dig_out_nid = ALC883_DIGOUT_NID,
10345 .dig_in_nid = ALC883_DIGIN_NID,
10346 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10347 .channel_mode = alc883_4ST_8ch_modes,
10348 .need_dac_fix = 1,
10349 .input_mux = &alc883_capture_source,
c259249f 10350 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10351 .setup = alc882_targa_setup,
10352 .init_hook = alc882_targa_automute,
64a8be74 10353 },
bab282b9 10354 [ALC883_ACER] = {
676a9b53 10355 .mixers = { alc883_base_mixer },
bab282b9
VA
10356 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10357 * and the headphone jack. Turn this on and rely on the
10358 * standard mute methods whenever the user wants to turn
10359 * these outputs off.
10360 */
10361 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10362 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10363 .dac_nids = alc883_dac_nids,
bab282b9
VA
10364 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10365 .channel_mode = alc883_3ST_2ch_modes,
10366 .input_mux = &alc883_capture_source,
10367 },
2880a867 10368 [ALC883_ACER_ASPIRE] = {
676a9b53 10369 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10370 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10371 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10372 .dac_nids = alc883_dac_nids,
10373 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10374 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10375 .channel_mode = alc883_3ST_2ch_modes,
10376 .input_mux = &alc883_capture_source,
a9fd4f3f 10377 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10378 .setup = alc883_acer_aspire_setup,
10379 .init_hook = alc_automute_amp,
d1a991a6 10380 },
5b2d1eca 10381 [ALC888_ACER_ASPIRE_4930G] = {
460c92fa 10382 .mixers = { alc888_acer_aspire_4930g_mixer,
5b2d1eca
VP
10383 alc883_chmode_mixer },
10384 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10385 alc888_acer_aspire_4930g_verbs },
10386 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10387 .dac_nids = alc883_dac_nids,
10388 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10389 .adc_nids = alc883_adc_nids_rev,
10390 .capsrc_nids = alc883_capsrc_nids_rev,
10391 .dig_out_nid = ALC883_DIGOUT_NID,
10392 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10393 .channel_mode = alc883_3ST_6ch_modes,
10394 .need_dac_fix = 1,
973b8cb0 10395 .const_channel_count = 6,
5b2d1eca 10396 .num_mux_defs =
ef8ef5fb
VP
10397 ARRAY_SIZE(alc888_2_capture_sources),
10398 .input_mux = alc888_2_capture_sources,
d2fd4b09 10399 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10400 .setup = alc888_acer_aspire_4930g_setup,
10401 .init_hook = alc_automute_amp,
d2fd4b09
TV
10402 },
10403 [ALC888_ACER_ASPIRE_6530G] = {
10404 .mixers = { alc888_acer_aspire_6530_mixer },
10405 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10406 alc888_acer_aspire_6530g_verbs },
10407 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10408 .dac_nids = alc883_dac_nids,
10409 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10410 .adc_nids = alc883_adc_nids_rev,
10411 .capsrc_nids = alc883_capsrc_nids_rev,
10412 .dig_out_nid = ALC883_DIGOUT_NID,
10413 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10414 .channel_mode = alc883_3ST_2ch_modes,
10415 .num_mux_defs =
10416 ARRAY_SIZE(alc888_2_capture_sources),
10417 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 10418 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10419 .setup = alc888_acer_aspire_6530g_setup,
10420 .init_hook = alc_automute_amp,
5b2d1eca 10421 },
3b315d70 10422 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10423 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10424 alc883_chmode_mixer },
10425 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10426 alc889_acer_aspire_8930g_verbs,
10427 alc889_eapd_verbs},
3b315d70
HM
10428 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10429 .dac_nids = alc883_dac_nids,
018df418
HM
10430 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10431 .adc_nids = alc889_adc_nids,
10432 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10433 .dig_out_nid = ALC883_DIGOUT_NID,
10434 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10435 .channel_mode = alc883_3ST_6ch_modes,
10436 .need_dac_fix = 1,
10437 .const_channel_count = 6,
10438 .num_mux_defs =
018df418
HM
10439 ARRAY_SIZE(alc889_capture_sources),
10440 .input_mux = alc889_capture_sources,
3b315d70 10441 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10442 .setup = alc889_acer_aspire_8930g_setup,
10443 .init_hook = alc_automute_amp,
f5de24b0 10444#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10445 .power_hook = alc_power_eapd,
f5de24b0 10446#endif
3b315d70 10447 },
fc86f954
DK
10448 [ALC888_ACER_ASPIRE_7730G] = {
10449 .mixers = { alc883_3ST_6ch_mixer,
10450 alc883_chmode_mixer },
10451 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10452 alc888_acer_aspire_7730G_verbs },
10453 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10454 .dac_nids = alc883_dac_nids,
10455 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10456 .adc_nids = alc883_adc_nids_rev,
10457 .capsrc_nids = alc883_capsrc_nids_rev,
10458 .dig_out_nid = ALC883_DIGOUT_NID,
10459 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10460 .channel_mode = alc883_3ST_6ch_modes,
10461 .need_dac_fix = 1,
10462 .const_channel_count = 6,
10463 .input_mux = &alc883_capture_source,
10464 .unsol_event = alc_automute_amp_unsol_event,
d9477207 10465 .setup = alc888_acer_aspire_7730g_setup,
fc86f954
DK
10466 .init_hook = alc_automute_amp,
10467 },
c07584c8
TD
10468 [ALC883_MEDION] = {
10469 .mixers = { alc883_fivestack_mixer,
10470 alc883_chmode_mixer },
10471 .init_verbs = { alc883_init_verbs,
b373bdeb 10472 alc883_medion_eapd_verbs },
c07584c8
TD
10473 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10474 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10475 .adc_nids = alc883_adc_nids_alt,
10476 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10477 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10478 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10479 .channel_mode = alc883_sixstack_modes,
10480 .input_mux = &alc883_capture_source,
b373bdeb 10481 },
7ad7b218
MC
10482 [ALC883_MEDION_WIM2160] = {
10483 .mixers = { alc883_medion_wim2160_mixer },
10484 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10485 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10486 .dac_nids = alc883_dac_nids,
10487 .dig_out_nid = ALC883_DIGOUT_NID,
10488 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10489 .adc_nids = alc883_adc_nids,
10490 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10491 .channel_mode = alc883_3ST_2ch_modes,
10492 .input_mux = &alc883_capture_source,
10493 .unsol_event = alc_automute_amp_unsol_event,
10494 .setup = alc883_medion_wim2160_setup,
10495 .init_hook = alc_automute_amp,
10496 },
b373bdeb 10497 [ALC883_LAPTOP_EAPD] = {
676a9b53 10498 .mixers = { alc883_base_mixer },
b373bdeb
AN
10499 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10500 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10501 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10502 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10503 .channel_mode = alc883_3ST_2ch_modes,
10504 .input_mux = &alc883_capture_source,
10505 },
a65cc60f 10506 [ALC883_CLEVO_M540R] = {
10507 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10508 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10509 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10510 .dac_nids = alc883_dac_nids,
10511 .dig_out_nid = ALC883_DIGOUT_NID,
10512 .dig_in_nid = ALC883_DIGIN_NID,
10513 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10514 .channel_mode = alc883_3ST_6ch_clevo_modes,
10515 .need_dac_fix = 1,
10516 .input_mux = &alc883_capture_source,
10517 /* This machine has the hardware HP auto-muting, thus
10518 * we need no software mute via unsol event
10519 */
10520 },
0c4cc443
HRK
10521 [ALC883_CLEVO_M720] = {
10522 .mixers = { alc883_clevo_m720_mixer },
10523 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10524 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10525 .dac_nids = alc883_dac_nids,
10526 .dig_out_nid = ALC883_DIGOUT_NID,
10527 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10528 .channel_mode = alc883_3ST_2ch_modes,
10529 .input_mux = &alc883_capture_source,
0c4cc443 10530 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10531 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10532 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10533 },
bc9f98a9
KY
10534 [ALC883_LENOVO_101E_2ch] = {
10535 .mixers = { alc883_lenovo_101e_2ch_mixer},
10536 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10537 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10538 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10539 .adc_nids = alc883_adc_nids_alt,
10540 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10541 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10542 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10543 .channel_mode = alc883_3ST_2ch_modes,
10544 .input_mux = &alc883_lenovo_101e_capture_source,
10545 .unsol_event = alc883_lenovo_101e_unsol_event,
10546 .init_hook = alc883_lenovo_101e_all_automute,
10547 },
272a527c
KY
10548 [ALC883_LENOVO_NB0763] = {
10549 .mixers = { alc883_lenovo_nb0763_mixer },
10550 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10551 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10552 .dac_nids = alc883_dac_nids,
272a527c
KY
10553 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10554 .channel_mode = alc883_3ST_2ch_modes,
10555 .need_dac_fix = 1,
10556 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 10557 .unsol_event = alc_automute_amp_unsol_event,
dc427170 10558 .setup = alc883_lenovo_nb0763_setup,
4f5d1706 10559 .init_hook = alc_automute_amp,
272a527c
KY
10560 },
10561 [ALC888_LENOVO_MS7195_DIG] = {
10562 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10563 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10564 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10565 .dac_nids = alc883_dac_nids,
10566 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10567 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10568 .channel_mode = alc883_3ST_6ch_modes,
10569 .need_dac_fix = 1,
10570 .input_mux = &alc883_capture_source,
10571 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10572 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
10573 },
10574 [ALC883_HAIER_W66] = {
c259249f 10575 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10576 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10577 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10578 .dac_nids = alc883_dac_nids,
10579 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10580 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10581 .channel_mode = alc883_3ST_2ch_modes,
10582 .input_mux = &alc883_capture_source,
a9fd4f3f 10583 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10584 .setup = alc883_haier_w66_setup,
10585 .init_hook = alc_automute_amp,
eea6419e 10586 },
4723c022 10587 [ALC888_3ST_HP] = {
eea6419e 10588 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10589 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10590 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10591 .dac_nids = alc883_dac_nids,
4723c022
CM
10592 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10593 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10594 .need_dac_fix = 1,
10595 .input_mux = &alc883_capture_source,
a9fd4f3f 10596 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10597 .setup = alc888_3st_hp_setup,
10598 .init_hook = alc_automute_amp,
8341de60 10599 },
5795b9e6 10600 [ALC888_6ST_DELL] = {
f24dbdc6 10601 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10602 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10603 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10604 .dac_nids = alc883_dac_nids,
10605 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10606 .dig_in_nid = ALC883_DIGIN_NID,
10607 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10608 .channel_mode = alc883_sixstack_modes,
10609 .input_mux = &alc883_capture_source,
a9fd4f3f 10610 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10611 .setup = alc888_6st_dell_setup,
10612 .init_hook = alc_automute_amp,
5795b9e6 10613 },
a8848bd6
AS
10614 [ALC883_MITAC] = {
10615 .mixers = { alc883_mitac_mixer },
10616 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10617 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10618 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10619 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10620 .channel_mode = alc883_3ST_2ch_modes,
10621 .input_mux = &alc883_capture_source,
a9fd4f3f 10622 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10623 .setup = alc883_mitac_setup,
10624 .init_hook = alc_automute_amp,
a8848bd6 10625 },
fb97dc67
J
10626 [ALC883_FUJITSU_PI2515] = {
10627 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10628 .init_verbs = { alc883_init_verbs,
10629 alc883_2ch_fujitsu_pi2515_verbs},
10630 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10631 .dac_nids = alc883_dac_nids,
10632 .dig_out_nid = ALC883_DIGOUT_NID,
10633 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10634 .channel_mode = alc883_3ST_2ch_modes,
10635 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10636 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10637 .setup = alc883_2ch_fujitsu_pi2515_setup,
10638 .init_hook = alc_automute_amp,
fb97dc67 10639 },
ef8ef5fb
VP
10640 [ALC888_FUJITSU_XA3530] = {
10641 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10642 .init_verbs = { alc883_init_verbs,
10643 alc888_fujitsu_xa3530_verbs },
10644 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10645 .dac_nids = alc883_dac_nids,
10646 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10647 .adc_nids = alc883_adc_nids_rev,
10648 .capsrc_nids = alc883_capsrc_nids_rev,
10649 .dig_out_nid = ALC883_DIGOUT_NID,
10650 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10651 .channel_mode = alc888_4ST_8ch_intel_modes,
10652 .num_mux_defs =
10653 ARRAY_SIZE(alc888_2_capture_sources),
10654 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10655 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10656 .setup = alc888_fujitsu_xa3530_setup,
10657 .init_hook = alc_automute_amp,
ef8ef5fb 10658 },
e2757d5e
KY
10659 [ALC888_LENOVO_SKY] = {
10660 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10661 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10662 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10663 .dac_nids = alc883_dac_nids,
10664 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10665 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10666 .channel_mode = alc883_sixstack_modes,
10667 .need_dac_fix = 1,
10668 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10669 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10670 .setup = alc888_lenovo_sky_setup,
10671 .init_hook = alc_automute_amp,
e2757d5e
KY
10672 },
10673 [ALC888_ASUS_M90V] = {
10674 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10675 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10676 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10677 .dac_nids = alc883_dac_nids,
10678 .dig_out_nid = ALC883_DIGOUT_NID,
10679 .dig_in_nid = ALC883_DIGIN_NID,
10680 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10681 .channel_mode = alc883_3ST_6ch_modes,
10682 .need_dac_fix = 1,
10683 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10684 .unsol_event = alc_sku_unsol_event,
10685 .setup = alc883_mode2_setup,
10686 .init_hook = alc_inithook,
e2757d5e
KY
10687 },
10688 [ALC888_ASUS_EEE1601] = {
10689 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10690 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10691 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10692 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10693 .dac_nids = alc883_dac_nids,
10694 .dig_out_nid = ALC883_DIGOUT_NID,
10695 .dig_in_nid = ALC883_DIGIN_NID,
10696 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10697 .channel_mode = alc883_3ST_2ch_modes,
10698 .need_dac_fix = 1,
10699 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10700 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10701 .init_hook = alc883_eee1601_inithook,
10702 },
3ab90935
WF
10703 [ALC1200_ASUS_P5Q] = {
10704 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10705 .init_verbs = { alc883_init_verbs },
10706 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10707 .dac_nids = alc883_dac_nids,
10708 .dig_out_nid = ALC1200_DIGOUT_NID,
10709 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10710 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10711 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10712 .channel_mode = alc883_sixstack_modes,
10713 .input_mux = &alc883_capture_source,
10714 },
eb4c41d3
TS
10715 [ALC889A_MB31] = {
10716 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10717 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10718 alc880_gpio1_init_verbs },
10719 .adc_nids = alc883_adc_nids,
10720 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10721 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10722 .dac_nids = alc883_dac_nids,
10723 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10724 .channel_mode = alc889A_mb31_6ch_modes,
10725 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10726 .input_mux = &alc889A_mb31_capture_source,
10727 .dig_out_nid = ALC883_DIGOUT_NID,
10728 .unsol_event = alc889A_mb31_unsol_event,
10729 .init_hook = alc889A_mb31_automute,
10730 },
3e1647c5
GG
10731 [ALC883_SONY_VAIO_TT] = {
10732 .mixers = { alc883_vaiott_mixer },
10733 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10734 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10735 .dac_nids = alc883_dac_nids,
10736 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10737 .channel_mode = alc883_3ST_2ch_modes,
10738 .input_mux = &alc883_capture_source,
10739 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10740 .setup = alc883_vaiott_setup,
10741 .init_hook = alc_automute_amp,
3e1647c5 10742 },
9c7f852e
TI
10743};
10744
10745
4953550a
TI
10746/*
10747 * Pin config fixes
10748 */
10749enum {
954a29c8
TI
10750 PINFIX_ABIT_AW9D_MAX,
10751 PINFIX_PB_M5210,
c3d226ab 10752 PINFIX_ACER_ASPIRE_7736,
4953550a
TI
10753};
10754
f8f25ba3
TI
10755static const struct alc_fixup alc882_fixups[] = {
10756 [PINFIX_ABIT_AW9D_MAX] = {
b5bfbc67
TI
10757 .type = ALC_FIXUP_PINS,
10758 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
10759 { 0x15, 0x01080104 }, /* side */
10760 { 0x16, 0x01011012 }, /* rear */
10761 { 0x17, 0x01016011 }, /* clfe */
10762 { }
10763 }
f8f25ba3 10764 },
954a29c8 10765 [PINFIX_PB_M5210] = {
b5bfbc67
TI
10766 .type = ALC_FIXUP_VERBS,
10767 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
10768 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10769 {}
10770 }
954a29c8 10771 },
c3d226ab 10772 [PINFIX_ACER_ASPIRE_7736] = {
b5bfbc67
TI
10773 .type = ALC_FIXUP_SKU,
10774 .v.sku = ALC_FIXUP_SKU_IGNORE,
c3d226ab 10775 },
4953550a
TI
10776};
10777
f8f25ba3 10778static struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10779 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
4953550a 10780 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
c3d226ab 10781 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
4953550a
TI
10782 {}
10783};
10784
9c7f852e
TI
10785/*
10786 * BIOS auto configuration
10787 */
05f5f477
TI
10788static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10789 const struct auto_pin_cfg *cfg)
10790{
10791 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10792}
10793
4953550a 10794static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10795 hda_nid_t nid, int pin_type,
489008cd 10796 hda_nid_t dac)
9c7f852e 10797{
f12ab1e0
TI
10798 int idx;
10799
489008cd 10800 /* set as output */
f6c7e546 10801 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10802
10803 if (dac == 0x25)
9c7f852e 10804 idx = 4;
489008cd
TI
10805 else if (dac >= 0x02 && dac <= 0x05)
10806 idx = dac - 2;
f9700d5a 10807 else
489008cd 10808 return;
9c7f852e 10809 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
10810}
10811
4953550a 10812static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10813{
10814 struct alc_spec *spec = codec->spec;
10815 int i;
10816
10817 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10818 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10819 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10820 if (nid)
4953550a 10821 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 10822 spec->multiout.dac_nids[i]);
9c7f852e
TI
10823 }
10824}
10825
4953550a 10826static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10827{
10828 struct alc_spec *spec = codec->spec;
489008cd 10829 hda_nid_t pin, dac;
5855fb80 10830 int i;
9c7f852e 10831
5855fb80
TI
10832 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
10833 pin = spec->autocfg.hp_pins[i];
10834 if (!pin)
10835 break;
489008cd
TI
10836 dac = spec->multiout.hp_nid;
10837 if (!dac)
10838 dac = spec->multiout.dac_nids[0]; /* to front */
10839 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10840 }
5855fb80
TI
10841 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
10842 pin = spec->autocfg.speaker_pins[i];
10843 if (!pin)
10844 break;
489008cd
TI
10845 dac = spec->multiout.extra_out_nid[0];
10846 if (!dac)
10847 dac = spec->multiout.dac_nids[0]; /* to front */
10848 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10849 }
9c7f852e
TI
10850}
10851
4953550a 10852static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10853{
10854 struct alc_spec *spec = codec->spec;
66ceeb6b 10855 struct auto_pin_cfg *cfg = &spec->autocfg;
9c7f852e
TI
10856 int i;
10857
66ceeb6b
TI
10858 for (i = 0; i < cfg->num_inputs; i++) {
10859 hda_nid_t nid = cfg->inputs[i].pin;
30ea098f 10860 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
4953550a
TI
10861 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10862 snd_hda_codec_write(codec, nid, 0,
10863 AC_VERB_SET_AMP_GAIN_MUTE,
10864 AMP_OUT_MUTE);
10865 }
10866}
10867
10868static void alc882_auto_init_input_src(struct hda_codec *codec)
10869{
10870 struct alc_spec *spec = codec->spec;
10871 int c;
10872
10873 for (c = 0; c < spec->num_adc_nids; c++) {
10874 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10875 hda_nid_t nid = spec->capsrc_nids[c];
10876 unsigned int mux_idx;
10877 const struct hda_input_mux *imux;
10878 int conns, mute, idx, item;
10879
10880 conns = snd_hda_get_connections(codec, nid, conn_list,
10881 ARRAY_SIZE(conn_list));
10882 if (conns < 0)
10883 continue;
10884 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10885 imux = &spec->input_mux[mux_idx];
5311114d
TI
10886 if (!imux->num_items && mux_idx > 0)
10887 imux = &spec->input_mux[0];
4953550a
TI
10888 for (idx = 0; idx < conns; idx++) {
10889 /* if the current connection is the selected one,
10890 * unmute it as default - otherwise mute it
10891 */
10892 mute = AMP_IN_MUTE(idx);
10893 for (item = 0; item < imux->num_items; item++) {
10894 if (imux->items[item].index == idx) {
10895 if (spec->cur_mux[c] == item)
10896 mute = AMP_IN_UNMUTE(idx);
10897 break;
10898 }
10899 }
10900 /* check if we have a selector or mixer
10901 * we could check for the widget type instead, but
10902 * just check for Amp-In presence (in case of mixer
10903 * without amp-in there is something wrong, this
10904 * function shouldn't be used or capsrc nid is wrong)
10905 */
10906 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10907 snd_hda_codec_write(codec, nid, 0,
10908 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10909 mute);
10910 else if (mute != AMP_IN_MUTE(idx))
10911 snd_hda_codec_write(codec, nid, 0,
10912 AC_VERB_SET_CONNECT_SEL,
10913 idx);
9c7f852e
TI
10914 }
10915 }
10916}
10917
4953550a
TI
10918/* add mic boosts if needed */
10919static int alc_auto_add_mic_boost(struct hda_codec *codec)
10920{
10921 struct alc_spec *spec = codec->spec;
66ceeb6b 10922 struct auto_pin_cfg *cfg = &spec->autocfg;
5322bf27 10923 int i, err;
53e8c323 10924 int type_idx = 0;
4953550a 10925 hda_nid_t nid;
5322bf27 10926 const char *prev_label = NULL;
4953550a 10927
66ceeb6b 10928 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 10929 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
10930 break;
10931 nid = cfg->inputs[i].pin;
10932 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
5322bf27
DH
10933 const char *label;
10934 char boost_label[32];
10935
10936 label = hda_get_autocfg_input_label(codec, cfg, i);
10937 if (prev_label && !strcmp(label, prev_label))
53e8c323
TI
10938 type_idx++;
10939 else
10940 type_idx = 0;
5322bf27
DH
10941 prev_label = label;
10942
10943 snprintf(boost_label, sizeof(boost_label),
10944 "%s Boost Volume", label);
10945 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10946 boost_label, type_idx,
4953550a 10947 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
10948 if (err < 0)
10949 return err;
10950 }
4953550a
TI
10951 }
10952 return 0;
10953}
f511b01c 10954
9c7f852e 10955/* almost identical with ALC880 parser... */
4953550a 10956static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10957{
10958 struct alc_spec *spec = codec->spec;
05f5f477 10959 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 10960 int err;
9c7f852e 10961
05f5f477
TI
10962 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10963 alc882_ignore);
9c7f852e
TI
10964 if (err < 0)
10965 return err;
05f5f477
TI
10966 if (!spec->autocfg.line_outs)
10967 return 0; /* can't find valid BIOS pin config */
776e184e 10968
05f5f477
TI
10969 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10970 if (err < 0)
10971 return err;
569ed348 10972 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
10973 if (err < 0)
10974 return err;
10975 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10976 "Headphone");
05f5f477
TI
10977 if (err < 0)
10978 return err;
10979 err = alc880_auto_create_extra_out(spec,
10980 spec->autocfg.speaker_pins[0],
10981 "Speaker");
10982 if (err < 0)
10983 return err;
05f5f477 10984 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10985 if (err < 0)
10986 return err;
10987
05f5f477
TI
10988 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10989
757899ac 10990 alc_auto_parse_digital(codec);
05f5f477
TI
10991
10992 if (spec->kctls.list)
10993 add_mixer(spec, spec->kctls.list);
10994
10995 add_verb(spec, alc883_auto_init_verbs);
4953550a 10996 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10997 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10998 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10999
05f5f477
TI
11000 spec->num_mux_defs = 1;
11001 spec->input_mux = &spec->private_imux[0];
11002
6227cdce 11003 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
11004
11005 err = alc_auto_add_mic_boost(codec);
11006 if (err < 0)
11007 return err;
61b9b9b1 11008
776e184e 11009 return 1; /* config found */
9c7f852e
TI
11010}
11011
11012/* additional initialization for auto-configuration model */
4953550a 11013static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 11014{
f6c7e546 11015 struct alc_spec *spec = codec->spec;
4953550a
TI
11016 alc882_auto_init_multi_out(codec);
11017 alc882_auto_init_hp_out(codec);
11018 alc882_auto_init_analog_input(codec);
11019 alc882_auto_init_input_src(codec);
757899ac 11020 alc_auto_init_digital(codec);
f6c7e546 11021 if (spec->unsol_event)
7fb0d78f 11022 alc_inithook(codec);
9c7f852e
TI
11023}
11024
4953550a 11025static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
11026{
11027 struct alc_spec *spec;
11028 int err, board_config;
11029
11030 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11031 if (spec == NULL)
11032 return -ENOMEM;
11033
11034 codec->spec = spec;
11035
4953550a
TI
11036 switch (codec->vendor_id) {
11037 case 0x10ec0882:
11038 case 0x10ec0885:
11039 break;
11040 default:
11041 /* ALC883 and variants */
11042 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11043 break;
11044 }
2c3bf9ab 11045
4953550a
TI
11046 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
11047 alc882_models,
11048 alc882_cfg_tbl);
11049
11050 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11051 board_config = snd_hda_check_board_codec_sid_config(codec,
11052 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11053
11054 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 11055 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
11056 codec->chip_name);
11057 board_config = ALC882_AUTO;
9c7f852e
TI
11058 }
11059
b5bfbc67
TI
11060 if (board_config == ALC882_AUTO) {
11061 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11062 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11063 }
4953550a 11064
90622917
DH
11065 alc_auto_parse_customize_define(codec);
11066
4953550a 11067 if (board_config == ALC882_AUTO) {
9c7f852e 11068 /* automatic parse from the BIOS config */
4953550a 11069 err = alc882_parse_auto_config(codec);
9c7f852e
TI
11070 if (err < 0) {
11071 alc_free(codec);
11072 return err;
f12ab1e0 11073 } else if (!err) {
9c7f852e
TI
11074 printk(KERN_INFO
11075 "hda_codec: Cannot set up configuration "
11076 "from BIOS. Using base mode...\n");
4953550a 11077 board_config = ALC882_3ST_DIG;
9c7f852e
TI
11078 }
11079 }
11080
dc1eae25 11081 if (has_cdefine_beep(codec)) {
8af2591d
TI
11082 err = snd_hda_attach_beep_device(codec, 0x1);
11083 if (err < 0) {
11084 alc_free(codec);
11085 return err;
11086 }
680cd536
KK
11087 }
11088
4953550a 11089 if (board_config != ALC882_AUTO)
e9c364c0 11090 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 11091
4953550a
TI
11092 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11093 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11094 /* FIXME: setup DAC5 */
11095 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11096 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11097
11098 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11099 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11100
4953550a 11101 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 11102 int i, j;
4953550a
TI
11103 spec->num_adc_nids = 0;
11104 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 11105 const struct hda_input_mux *imux = spec->input_mux;
4953550a 11106 hda_nid_t cap;
d11f74c6 11107 hda_nid_t items[16];
4953550a
TI
11108 hda_nid_t nid = alc882_adc_nids[i];
11109 unsigned int wcap = get_wcaps(codec, nid);
11110 /* get type */
a22d543a 11111 wcap = get_wcaps_type(wcap);
4953550a
TI
11112 if (wcap != AC_WID_AUD_IN)
11113 continue;
11114 spec->private_adc_nids[spec->num_adc_nids] = nid;
11115 err = snd_hda_get_connections(codec, nid, &cap, 1);
11116 if (err < 0)
11117 continue;
d11f74c6
TI
11118 err = snd_hda_get_connections(codec, cap, items,
11119 ARRAY_SIZE(items));
11120 if (err < 0)
11121 continue;
11122 for (j = 0; j < imux->num_items; j++)
11123 if (imux->items[j].index >= err)
11124 break;
11125 if (j < imux->num_items)
11126 continue;
4953550a
TI
11127 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11128 spec->num_adc_nids++;
61b9b9b1 11129 }
4953550a
TI
11130 spec->adc_nids = spec->private_adc_nids;
11131 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
11132 }
11133
b59bdf3b 11134 set_capture_mixer(codec);
da00c244 11135
dc1eae25 11136 if (has_cdefine_beep(codec))
da00c244 11137 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 11138
b5bfbc67 11139 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 11140
2134ea4f
TI
11141 spec->vmaster_nid = 0x0c;
11142
9c7f852e 11143 codec->patch_ops = alc_patch_ops;
4953550a
TI
11144 if (board_config == ALC882_AUTO)
11145 spec->init_hook = alc882_auto_init;
bf1b0225
KY
11146
11147 alc_init_jacks(codec);
cb53c626
TI
11148#ifdef CONFIG_SND_HDA_POWER_SAVE
11149 if (!spec->loopback.amplist)
4953550a 11150 spec->loopback.amplist = alc882_loopbacks;
cb53c626 11151#endif
9c7f852e
TI
11152
11153 return 0;
11154}
11155
4953550a 11156
9c7f852e
TI
11157/*
11158 * ALC262 support
11159 */
11160
11161#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11162#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11163
11164#define alc262_dac_nids alc260_dac_nids
11165#define alc262_adc_nids alc882_adc_nids
11166#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
11167#define alc262_capsrc_nids alc882_capsrc_nids
11168#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
11169
11170#define alc262_modes alc260_modes
11171#define alc262_capture_source alc882_capture_source
11172
4e555fe5
KY
11173static hda_nid_t alc262_dmic_adc_nids[1] = {
11174 /* ADC0 */
11175 0x09
11176};
11177
11178static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11179
9c7f852e
TI
11180static struct snd_kcontrol_new alc262_base_mixer[] = {
11181 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11182 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11183 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11184 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11185 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11186 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11187 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11188 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11189 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11190 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11191 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11192 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11193 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11194 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11195 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11196 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11197 { } /* end */
11198};
11199
ce875f07
TI
11200/* update HP, line and mono-out pins according to the master switch */
11201static void alc262_hp_master_update(struct hda_codec *codec)
11202{
11203 struct alc_spec *spec = codec->spec;
11204 int val = spec->master_sw;
11205
11206 /* HP & line-out */
11207 snd_hda_codec_write_cache(codec, 0x1b, 0,
11208 AC_VERB_SET_PIN_WIDGET_CONTROL,
11209 val ? PIN_HP : 0);
11210 snd_hda_codec_write_cache(codec, 0x15, 0,
11211 AC_VERB_SET_PIN_WIDGET_CONTROL,
11212 val ? PIN_HP : 0);
11213 /* mono (speaker) depending on the HP jack sense */
11214 val = val && !spec->jack_present;
11215 snd_hda_codec_write_cache(codec, 0x16, 0,
11216 AC_VERB_SET_PIN_WIDGET_CONTROL,
11217 val ? PIN_OUT : 0);
11218}
11219
11220static void alc262_hp_bpc_automute(struct hda_codec *codec)
11221{
11222 struct alc_spec *spec = codec->spec;
864f92be
WF
11223
11224 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
11225 alc262_hp_master_update(codec);
11226}
11227
11228static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
11229{
11230 if ((res >> 26) != ALC880_HP_EVENT)
11231 return;
11232 alc262_hp_bpc_automute(codec);
11233}
11234
11235static void alc262_hp_wildwest_automute(struct hda_codec *codec)
11236{
11237 struct alc_spec *spec = codec->spec;
864f92be
WF
11238
11239 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
11240 alc262_hp_master_update(codec);
11241}
11242
11243static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
11244 unsigned int res)
11245{
11246 if ((res >> 26) != ALC880_HP_EVENT)
11247 return;
11248 alc262_hp_wildwest_automute(codec);
11249}
11250
b72519b5 11251#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
11252
11253static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
11254 struct snd_ctl_elem_value *ucontrol)
11255{
11256 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11257 struct alc_spec *spec = codec->spec;
11258 int val = !!*ucontrol->value.integer.value;
11259
11260 if (val == spec->master_sw)
11261 return 0;
11262 spec->master_sw = val;
11263 alc262_hp_master_update(codec);
11264 return 1;
11265}
11266
b72519b5
TI
11267#define ALC262_HP_MASTER_SWITCH \
11268 { \
11269 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11270 .name = "Master Playback Switch", \
11271 .info = snd_ctl_boolean_mono_info, \
11272 .get = alc262_hp_master_sw_get, \
11273 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11274 }, \
11275 { \
11276 .iface = NID_MAPPING, \
11277 .name = "Master Playback Switch", \
11278 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11279 }
11280
5b0cb1d8 11281
9c7f852e 11282static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11283 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11284 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11285 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11286 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11287 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11288 HDA_OUTPUT),
11289 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11290 HDA_OUTPUT),
9c7f852e
TI
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),
9c7f852e
TI
11294 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11295 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11296 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11297 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11298 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11299 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11300 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11301 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11302 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11303 { } /* end */
11304};
11305
cd7509a4 11306static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11307 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11308 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11309 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11310 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11311 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11312 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11313 HDA_OUTPUT),
11314 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11315 HDA_OUTPUT),
cd7509a4
KY
11316 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11317 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5f99f86a 11318 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11319 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11320 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11321 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11322 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11323 { } /* end */
11324};
11325
11326static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11327 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11328 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11329 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11330 { } /* end */
11331};
11332
66d2a9d6 11333/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11334static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11335{
11336 struct alc_spec *spec = codec->spec;
66d2a9d6 11337
a9fd4f3f 11338 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11339 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
11340}
11341
66d2a9d6 11342static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11343 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11344 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11345 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11346 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11347 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11348 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11349 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
66d2a9d6
KY
11350 { } /* end */
11351};
11352
11353static struct hda_verb alc262_hp_t5735_verbs[] = {
11354 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11355 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11356
11357 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11358 { }
11359};
11360
8c427226 11361static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11362 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11363 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11364 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11365 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11366 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11367 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11368 { } /* end */
11369};
11370
11371static struct hda_verb alc262_hp_rp5700_verbs[] = {
11372 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11373 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11374 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11375 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11376 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11377 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11378 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11379 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11380 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11381 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11382 {}
11383};
11384
11385static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11386 .num_items = 1,
11387 .items = {
11388 { "Line", 0x1 },
11389 },
11390};
11391
42171c17
TI
11392/* bind hp and internal speaker mute (with plug check) as master switch */
11393static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 11394{
42171c17
TI
11395 struct alc_spec *spec = codec->spec;
11396 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11397 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11398 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11399 unsigned int mute;
0724ea2a 11400
42171c17
TI
11401 /* HP */
11402 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11403 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11404 HDA_AMP_MUTE, mute);
11405 /* mute internal speaker per jack sense */
11406 if (spec->jack_present)
11407 mute = HDA_AMP_MUTE;
11408 if (line_nid)
11409 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11410 HDA_AMP_MUTE, mute);
11411 if (speaker_nid && speaker_nid != line_nid)
11412 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 11413 HDA_AMP_MUTE, mute);
42171c17
TI
11414}
11415
11416#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11417
11418static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11419 struct snd_ctl_elem_value *ucontrol)
11420{
11421 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11422 struct alc_spec *spec = codec->spec;
11423 int val = !!*ucontrol->value.integer.value;
11424
11425 if (val == spec->master_sw)
11426 return 0;
11427 spec->master_sw = val;
11428 alc262_hippo_master_update(codec);
11429 return 1;
11430}
11431
11432#define ALC262_HIPPO_MASTER_SWITCH \
11433 { \
11434 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11435 .name = "Master Playback Switch", \
11436 .info = snd_ctl_boolean_mono_info, \
11437 .get = alc262_hippo_master_sw_get, \
11438 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11439 }, \
11440 { \
11441 .iface = NID_MAPPING, \
11442 .name = "Master Playback Switch", \
11443 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11444 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11445 }
42171c17
TI
11446
11447static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11448 ALC262_HIPPO_MASTER_SWITCH,
11449 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11450 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11451 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11452 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11453 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11454 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11455 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11456 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11457 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11458 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11459 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11460 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11461 { } /* end */
11462};
11463
11464static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11465 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11466 ALC262_HIPPO_MASTER_SWITCH,
11467 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11468 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11469 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11470 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11471 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11472 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11473 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11474 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11475 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11476 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11477 { } /* end */
11478};
11479
11480/* mute/unmute internal speaker according to the hp jack and mute state */
11481static void alc262_hippo_automute(struct hda_codec *codec)
11482{
11483 struct alc_spec *spec = codec->spec;
11484 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 11485
864f92be 11486 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 11487 alc262_hippo_master_update(codec);
0724ea2a 11488}
5b31954e 11489
42171c17
TI
11490static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11491{
11492 if ((res >> 26) != ALC880_HP_EVENT)
11493 return;
11494 alc262_hippo_automute(codec);
11495}
11496
4f5d1706 11497static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11498{
11499 struct alc_spec *spec = codec->spec;
11500
11501 spec->autocfg.hp_pins[0] = 0x15;
11502 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11503}
11504
4f5d1706 11505static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11506{
11507 struct alc_spec *spec = codec->spec;
11508
11509 spec->autocfg.hp_pins[0] = 0x1b;
11510 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11511}
11512
11513
272a527c 11514static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11515 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11516 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11517 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11518 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11519 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11520 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11521 { } /* end */
11522};
11523
83c34218 11524static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11525 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11526 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11527 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11528 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11529 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11530 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11531 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11532 { } /* end */
11533};
272a527c 11534
ba340e82
TV
11535static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11536 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11537 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11538 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11539 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11540 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11541 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11542 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11543 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11544 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ba340e82
TV
11545 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11546 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11547 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
ba340e82
TV
11548 { } /* end */
11549};
11550
11551static struct hda_verb alc262_tyan_verbs[] = {
11552 /* Headphone automute */
11553 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11554 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11555 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11556
11557 /* P11 AUX_IN, white 4-pin connector */
11558 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11559 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11560 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11561 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11562
11563 {}
11564};
11565
11566/* unsolicited event for HP jack sensing */
4f5d1706 11567static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11568{
a9fd4f3f 11569 struct alc_spec *spec = codec->spec;
ba340e82 11570
a9fd4f3f
TI
11571 spec->autocfg.hp_pins[0] = 0x1b;
11572 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
11573}
11574
ba340e82 11575
9c7f852e
TI
11576#define alc262_capture_mixer alc882_capture_mixer
11577#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11578
11579/*
11580 * generic initialization of ADC, input mixers and output mixers
11581 */
11582static struct hda_verb alc262_init_verbs[] = {
11583 /*
11584 * Unmute ADC0-2 and set the default input to mic-in
11585 */
11586 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11587 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11588 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11589 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11590 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11591 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11592
cb53c626 11593 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11594 * mixer widget
f12ab1e0
TI
11595 * Note: PASD motherboards uses the Line In 2 as the input for
11596 * front panel mic (mic 2)
9c7f852e
TI
11597 */
11598 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11599 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11600 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11601 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11602 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11603 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11604
11605 /*
df694daa
KY
11606 * Set up output mixers (0x0c - 0x0e)
11607 */
11608 /* set vol=0 to output mixers */
11609 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11610 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11611 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11612 /* set up input amps for analog loopback */
11613 /* Amp Indices: DAC = 0, mixer = 1 */
11614 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11615 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11616 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11617 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11618 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11619 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11620
11621 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11622 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11623 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11624 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11625 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11626 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11627
11628 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11629 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11630 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11631 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11632 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11633
df694daa
KY
11634 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11635 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11636
df694daa
KY
11637 /* FIXME: use matrix-type input source selection */
11638 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11639 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11640 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11641 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11642 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11643 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11644 /* Input mixer2 */
11645 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11646 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11647 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11648 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11649 /* Input mixer3 */
11650 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11651 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11652 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11653 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11654
11655 { }
11656};
1da177e4 11657
4e555fe5
KY
11658static struct hda_verb alc262_eapd_verbs[] = {
11659 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11660 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11661 { }
11662};
11663
ccc656ce
KY
11664static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11665 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11666 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11667 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11668
11669 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11670 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11671 {}
11672};
11673
272a527c
KY
11674static struct hda_verb alc262_sony_unsol_verbs[] = {
11675 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11676 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11677 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11678
11679 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11680 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11681 {}
272a527c
KY
11682};
11683
4e555fe5
KY
11684static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11685 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11686 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11687 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11688 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11689 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11690 { } /* end */
11691};
11692
11693static struct hda_verb alc262_toshiba_s06_verbs[] = {
11694 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11695 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11696 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11697 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11698 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11699 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11700 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11701 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11702 {}
11703};
11704
4f5d1706 11705static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11706{
a9fd4f3f
TI
11707 struct alc_spec *spec = codec->spec;
11708
11709 spec->autocfg.hp_pins[0] = 0x15;
11710 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11711 spec->ext_mic.pin = 0x18;
11712 spec->ext_mic.mux_idx = 0;
11713 spec->int_mic.pin = 0x12;
11714 spec->int_mic.mux_idx = 9;
11715 spec->auto_mic = 1;
4e555fe5
KY
11716}
11717
e8f9ae2a
PT
11718/*
11719 * nec model
11720 * 0x15 = headphone
11721 * 0x16 = internal speaker
11722 * 0x18 = external mic
11723 */
11724
11725static struct snd_kcontrol_new alc262_nec_mixer[] = {
11726 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11727 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11728
11729 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11730 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11731 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e8f9ae2a
PT
11732
11733 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11734 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11735 { } /* end */
11736};
11737
11738static struct hda_verb alc262_nec_verbs[] = {
11739 /* Unmute Speaker */
11740 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11741
11742 /* Headphone */
11743 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11744 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11745
11746 /* External mic to headphone */
11747 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11748 /* External mic to speaker */
11749 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11750 {}
11751};
11752
834be88d
TI
11753/*
11754 * fujitsu model
5d9fab2d
TV
11755 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11756 * 0x1b = port replicator headphone out
834be88d
TI
11757 */
11758
11759#define ALC_HP_EVENT 0x37
11760
11761static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11762 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11763 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11764 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11765 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11766 {}
11767};
11768
0e31daf7
J
11769static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11770 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11771 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11772 {}
11773};
11774
e2595322
DC
11775static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11776 /* Front Mic pin: input vref at 50% */
11777 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11778 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11779 {}
11780};
11781
834be88d 11782static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11783 .num_items = 3,
834be88d
TI
11784 .items = {
11785 { "Mic", 0x0 },
28c4edb7 11786 { "Internal Mic", 0x1 },
834be88d
TI
11787 { "CD", 0x4 },
11788 },
11789};
11790
9c7f852e
TI
11791static struct hda_input_mux alc262_HP_capture_source = {
11792 .num_items = 5,
11793 .items = {
11794 { "Mic", 0x0 },
accbe498 11795 { "Front Mic", 0x1 },
9c7f852e
TI
11796 { "Line", 0x2 },
11797 { "CD", 0x4 },
11798 { "AUX IN", 0x6 },
11799 },
11800};
11801
accbe498 11802static struct hda_input_mux alc262_HP_D7000_capture_source = {
11803 .num_items = 4,
11804 .items = {
11805 { "Mic", 0x0 },
11806 { "Front Mic", 0x2 },
11807 { "Line", 0x1 },
11808 { "CD", 0x4 },
11809 },
11810};
11811
ebc7a406 11812/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11813static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11814{
11815 struct alc_spec *spec = codec->spec;
11816 unsigned int mute;
11817
f12ab1e0 11818 if (force || !spec->sense_updated) {
864f92be
WF
11819 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11820 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11821 spec->sense_updated = 1;
11822 }
ebc7a406
TI
11823 /* unmute internal speaker only if both HPs are unplugged and
11824 * master switch is on
11825 */
11826 if (spec->jack_present)
11827 mute = HDA_AMP_MUTE;
11828 else
834be88d 11829 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11830 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11831 HDA_AMP_MUTE, mute);
834be88d
TI
11832}
11833
11834/* unsolicited event for HP jack sensing */
11835static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11836 unsigned int res)
11837{
11838 if ((res >> 26) != ALC_HP_EVENT)
11839 return;
11840 alc262_fujitsu_automute(codec, 1);
11841}
11842
ebc7a406
TI
11843static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11844{
11845 alc262_fujitsu_automute(codec, 1);
11846}
11847
834be88d 11848/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11849static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11850 .ops = &snd_hda_bind_vol,
11851 .values = {
11852 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11853 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11854 0
11855 },
11856};
834be88d 11857
0e31daf7
J
11858/* mute/unmute internal speaker according to the hp jack and mute state */
11859static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11860{
11861 struct alc_spec *spec = codec->spec;
11862 unsigned int mute;
11863
11864 if (force || !spec->sense_updated) {
864f92be 11865 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11866 spec->sense_updated = 1;
11867 }
11868 if (spec->jack_present) {
11869 /* mute internal speaker */
11870 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11871 HDA_AMP_MUTE, HDA_AMP_MUTE);
11872 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11873 HDA_AMP_MUTE, HDA_AMP_MUTE);
11874 } else {
11875 /* unmute internal speaker if necessary */
11876 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11877 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11878 HDA_AMP_MUTE, mute);
11879 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11880 HDA_AMP_MUTE, mute);
11881 }
11882}
11883
11884/* unsolicited event for HP jack sensing */
11885static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11886 unsigned int res)
11887{
11888 if ((res >> 26) != ALC_HP_EVENT)
11889 return;
11890 alc262_lenovo_3000_automute(codec, 1);
11891}
11892
8de56b7d
TI
11893static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11894 int dir, int idx, long *valp)
11895{
11896 int i, change = 0;
11897
11898 for (i = 0; i < 2; i++, valp++)
11899 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11900 HDA_AMP_MUTE,
11901 *valp ? 0 : HDA_AMP_MUTE);
11902 return change;
11903}
11904
834be88d
TI
11905/* bind hp and internal speaker mute (with plug check) */
11906static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11907 struct snd_ctl_elem_value *ucontrol)
11908{
11909 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11910 long *valp = ucontrol->value.integer.value;
11911 int change;
11912
8de56b7d
TI
11913 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11914 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11915 if (change)
11916 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11917 return change;
11918}
11919
11920static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11921 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11922 {
11923 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11924 .name = "Master Playback Switch",
5e26dfd0 11925 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11926 .info = snd_hda_mixer_amp_switch_info,
11927 .get = snd_hda_mixer_amp_switch_get,
11928 .put = alc262_fujitsu_master_sw_put,
11929 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11930 },
5b0cb1d8
JK
11931 {
11932 .iface = NID_MAPPING,
11933 .name = "Master Playback Switch",
11934 .private_value = 0x1b,
11935 },
834be88d
TI
11936 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11937 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11938 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
834be88d
TI
11939 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11940 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11941 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11942 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11943 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11944 { } /* end */
11945};
11946
0e31daf7
J
11947/* bind hp and internal speaker mute (with plug check) */
11948static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11949 struct snd_ctl_elem_value *ucontrol)
11950{
11951 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11952 long *valp = ucontrol->value.integer.value;
11953 int change;
11954
8de56b7d 11955 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11956 if (change)
11957 alc262_lenovo_3000_automute(codec, 0);
11958 return change;
11959}
11960
11961static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11962 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11963 {
11964 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11965 .name = "Master Playback Switch",
5e26dfd0 11966 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11967 .info = snd_hda_mixer_amp_switch_info,
11968 .get = snd_hda_mixer_amp_switch_get,
11969 .put = alc262_lenovo_3000_master_sw_put,
11970 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11971 },
11972 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11973 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11974 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
0e31daf7
J
11975 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11976 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11977 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11978 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11979 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
0e31daf7
J
11980 { } /* end */
11981};
11982
9f99a638
HM
11983static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11984 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11985 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11986 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11987 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11988 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9f99a638
HM
11989 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11990 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11991 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9f99a638
HM
11992 { } /* end */
11993};
11994
304dcaac
TI
11995/* additional init verbs for Benq laptops */
11996static struct hda_verb alc262_EAPD_verbs[] = {
11997 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11998 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11999 {}
12000};
12001
83c34218
KY
12002static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
12003 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12004 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12005
12006 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12007 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
12008 {}
12009};
12010
f651b50b
TD
12011/* Samsung Q1 Ultra Vista model setup */
12012static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
12013 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
12014 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
12015 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12016 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
12017 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
12018 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
f651b50b
TD
12019 { } /* end */
12020};
12021
12022static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
12023 /* output mixer */
12024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12026 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12027 /* speaker */
12028 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12029 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12030 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12031 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12032 /* HP */
f651b50b 12033 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
12034 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12035 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12036 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12037 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12038 /* internal mic */
12039 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12040 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12041 /* ADC, choose mic */
12042 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12043 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12044 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12045 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12046 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12047 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12048 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12049 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12050 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12051 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
12052 {}
12053};
12054
f651b50b
TD
12055/* mute/unmute internal speaker according to the hp jack and mute state */
12056static void alc262_ultra_automute(struct hda_codec *codec)
12057{
12058 struct alc_spec *spec = codec->spec;
12059 unsigned int mute;
f651b50b 12060
bb9f76cd
TI
12061 mute = 0;
12062 /* auto-mute only when HP is used as HP */
12063 if (!spec->cur_mux[0]) {
864f92be 12064 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
12065 if (spec->jack_present)
12066 mute = HDA_AMP_MUTE;
f651b50b 12067 }
bb9f76cd
TI
12068 /* mute/unmute internal speaker */
12069 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12070 HDA_AMP_MUTE, mute);
12071 /* mute/unmute HP */
12072 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12073 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
12074}
12075
12076/* unsolicited event for HP jack sensing */
12077static void alc262_ultra_unsol_event(struct hda_codec *codec,
12078 unsigned int res)
12079{
12080 if ((res >> 26) != ALC880_HP_EVENT)
12081 return;
12082 alc262_ultra_automute(codec);
12083}
12084
bb9f76cd
TI
12085static struct hda_input_mux alc262_ultra_capture_source = {
12086 .num_items = 2,
12087 .items = {
12088 { "Mic", 0x1 },
12089 { "Headphone", 0x7 },
12090 },
12091};
12092
12093static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12094 struct snd_ctl_elem_value *ucontrol)
12095{
12096 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12097 struct alc_spec *spec = codec->spec;
12098 int ret;
12099
54cbc9ab 12100 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
12101 if (!ret)
12102 return 0;
12103 /* reprogram the HP pin as mic or HP according to the input source */
12104 snd_hda_codec_write_cache(codec, 0x15, 0,
12105 AC_VERB_SET_PIN_WIDGET_CONTROL,
12106 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12107 alc262_ultra_automute(codec); /* mute/unmute HP */
12108 return ret;
12109}
12110
12111static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12112 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12113 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12114 {
12115 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12116 .name = "Capture Source",
54cbc9ab
TI
12117 .info = alc_mux_enum_info,
12118 .get = alc_mux_enum_get,
bb9f76cd
TI
12119 .put = alc262_ultra_mux_enum_put,
12120 },
5b0cb1d8
JK
12121 {
12122 .iface = NID_MAPPING,
12123 .name = "Capture Source",
12124 .private_value = 0x15,
12125 },
bb9f76cd
TI
12126 { } /* end */
12127};
12128
c3fc1f50
TI
12129/* We use two mixers depending on the output pin; 0x16 is a mono output
12130 * and thus it's bound with a different mixer.
12131 * This function returns which mixer amp should be used.
12132 */
12133static int alc262_check_volbit(hda_nid_t nid)
12134{
12135 if (!nid)
12136 return 0;
12137 else if (nid == 0x16)
12138 return 2;
12139 else
12140 return 1;
12141}
12142
12143static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12144 const char *pfx, int *vbits, int idx)
c3fc1f50 12145{
c3fc1f50
TI
12146 unsigned long val;
12147 int vbit;
12148
12149 vbit = alc262_check_volbit(nid);
12150 if (!vbit)
12151 return 0;
12152 if (*vbits & vbit) /* a volume control for this mixer already there */
12153 return 0;
12154 *vbits |= vbit;
c3fc1f50
TI
12155 if (vbit == 2)
12156 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12157 else
12158 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 12159 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
12160}
12161
12162static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12163 const char *pfx, int idx)
c3fc1f50 12164{
c3fc1f50
TI
12165 unsigned long val;
12166
12167 if (!nid)
12168 return 0;
c3fc1f50
TI
12169 if (nid == 0x16)
12170 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12171 else
12172 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 12173 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
12174}
12175
df694daa 12176/* add playback controls from the parsed DAC table */
f12ab1e0
TI
12177static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12178 const struct auto_pin_cfg *cfg)
df694daa 12179{
c3fc1f50
TI
12180 const char *pfx;
12181 int vbits;
033688a5 12182 int i, err;
df694daa
KY
12183
12184 spec->multiout.num_dacs = 1; /* only use one dac */
12185 spec->multiout.dac_nids = spec->private_dac_nids;
12186 spec->multiout.dac_nids[0] = 2;
12187
bcb2f0f5
TI
12188 pfx = alc_get_line_out_pfx(cfg, true);
12189 if (!pfx)
c3fc1f50 12190 pfx = "Front";
033688a5
TI
12191 for (i = 0; i < 2; i++) {
12192 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12193 if (err < 0)
12194 return err;
12195 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12196 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12197 "Speaker", i);
12198 if (err < 0)
12199 return err;
12200 }
12201 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12202 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12203 "Headphone", i);
12204 if (err < 0)
12205 return err;
12206 }
12207 }
df694daa 12208
c3fc1f50
TI
12209 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12210 alc262_check_volbit(cfg->speaker_pins[0]) |
12211 alc262_check_volbit(cfg->hp_pins[0]);
12212 if (vbits == 1 || vbits == 2)
12213 pfx = "Master"; /* only one mixer is used */
c3fc1f50 12214 vbits = 0;
033688a5
TI
12215 for (i = 0; i < 2; i++) {
12216 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12217 &vbits, i);
12218 if (err < 0)
12219 return err;
12220 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12221 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12222 "Speaker", &vbits, i);
12223 if (err < 0)
12224 return err;
12225 }
12226 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12227 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12228 "Headphone", &vbits, i);
12229 if (err < 0)
12230 return err;
12231 }
12232 }
f12ab1e0 12233 return 0;
df694daa
KY
12234}
12235
05f5f477 12236#define alc262_auto_create_input_ctls \
eaa9b3a7 12237 alc882_auto_create_input_ctls
df694daa
KY
12238
12239/*
12240 * generic initialization of ADC, input mixers and output mixers
12241 */
12242static struct hda_verb alc262_volume_init_verbs[] = {
12243 /*
12244 * Unmute ADC0-2 and set the default input to mic-in
12245 */
12246 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12247 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12248 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12249 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12250 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12251 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12252
cb53c626 12253 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 12254 * mixer widget
f12ab1e0
TI
12255 * Note: PASD motherboards uses the Line In 2 as the input for
12256 * front panel mic (mic 2)
df694daa
KY
12257 */
12258 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12259 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12260 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12261 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12262 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12263 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
12264
12265 /*
12266 * Set up output mixers (0x0c - 0x0f)
12267 */
12268 /* set vol=0 to output mixers */
12269 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12270 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12271 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 12272
df694daa
KY
12273 /* set up input amps for analog loopback */
12274 /* Amp Indices: DAC = 0, mixer = 1 */
12275 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12276 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12277 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12278 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12279 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12280 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12281
12282 /* FIXME: use matrix-type input source selection */
12283 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12284 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12285 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12286 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12287 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12288 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12289 /* Input mixer2 */
12290 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12291 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12292 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12293 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12294 /* Input mixer3 */
12295 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12296 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12297 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12298 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12299
12300 { }
12301};
12302
9c7f852e
TI
12303static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12304 /*
12305 * Unmute ADC0-2 and set the default input to mic-in
12306 */
12307 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12308 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12309 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12310 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12311 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12312 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12313
cb53c626 12314 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12315 * mixer widget
f12ab1e0
TI
12316 * Note: PASD motherboards uses the Line In 2 as the input for
12317 * front panel mic (mic 2)
9c7f852e
TI
12318 */
12319 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12320 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12321 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12322 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12323 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12324 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12325 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12326 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12327
9c7f852e
TI
12328 /*
12329 * Set up output mixers (0x0c - 0x0e)
12330 */
12331 /* set vol=0 to output mixers */
12332 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12333 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12334 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12335
12336 /* set up input amps for analog loopback */
12337 /* Amp Indices: DAC = 0, mixer = 1 */
12338 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12339 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12340 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12341 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12342 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12343 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12344
ce875f07 12345 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12346 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12347 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12348
12349 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12350 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12351
12352 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12353 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12354
12355 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12356 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12357 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12358 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12359 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12360
0e4835c1 12361 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12362 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12363 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12364 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12365 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12366 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12367
12368
12369 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12370 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12371 /* Input mixer1: only unmute Mic */
9c7f852e 12372 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12373 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12374 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12375 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12376 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12377 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12378 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12379 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12380 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12381 /* Input mixer2 */
12382 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12383 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12384 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12385 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12386 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12387 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12388 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12389 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12390 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12391 /* Input mixer3 */
12392 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12393 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12394 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12395 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12396 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12397 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12398 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12399 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12400 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12401
ce875f07
TI
12402 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12403
9c7f852e
TI
12404 { }
12405};
12406
cd7509a4
KY
12407static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12408 /*
12409 * Unmute ADC0-2 and set the default input to mic-in
12410 */
12411 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12412 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12413 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12414 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12415 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12416 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12417
cb53c626 12418 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12419 * mixer widget
12420 * Note: PASD motherboards uses the Line In 2 as the input for front
12421 * panel mic (mic 2)
12422 */
12423 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12424 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12425 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12426 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12427 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12428 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12429 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12430 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12431 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12432 /*
12433 * Set up output mixers (0x0c - 0x0e)
12434 */
12435 /* set vol=0 to output mixers */
12436 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12437 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12438 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12439
12440 /* set up input amps for analog loopback */
12441 /* Amp Indices: DAC = 0, mixer = 1 */
12442 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12443 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12444 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12445 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12446 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12447 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12448
12449
12450 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12451 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12452 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12453 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12454 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12455 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12456 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12457
12458 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12459 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12460
12461 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12462 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12463
12464 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12465 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12466 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12467 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12468 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12469 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12470
12471 /* FIXME: use matrix-type input source selection */
12472 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12473 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12474 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12475 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12476 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12477 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12478 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12479 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12480 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12481 /* Input mixer2 */
12482 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12483 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12484 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12485 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12486 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12487 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12488 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12489 /* Input mixer3 */
12490 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12491 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12492 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12493 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12494 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12495 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12496 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12497
ce875f07
TI
12498 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12499
cd7509a4
KY
12500 { }
12501};
12502
9f99a638
HM
12503static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12504
12505 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12506 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12507 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12508
12509 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12510 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12511 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12512 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12513
12514 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12515 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12516 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12517 {}
12518};
12519
18675e42
TI
12520/*
12521 * Pin config fixes
12522 */
12523enum {
12524 PINFIX_FSC_H270,
12525};
12526
12527static const struct alc_fixup alc262_fixups[] = {
12528 [PINFIX_FSC_H270] = {
b5bfbc67
TI
12529 .type = ALC_FIXUP_PINS,
12530 .v.pins = (const struct alc_pincfg[]) {
18675e42
TI
12531 { 0x14, 0x99130110 }, /* speaker */
12532 { 0x15, 0x0221142f }, /* front HP */
12533 { 0x1b, 0x0121141f }, /* rear HP */
12534 { }
12535 }
12536 },
18675e42
TI
12537};
12538
12539static struct snd_pci_quirk alc262_fixup_tbl[] = {
12540 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12541 {}
12542};
12543
9f99a638 12544
cb53c626
TI
12545#ifdef CONFIG_SND_HDA_POWER_SAVE
12546#define alc262_loopbacks alc880_loopbacks
12547#endif
12548
def319f9 12549/* pcm configuration: identical with ALC880 */
df694daa
KY
12550#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12551#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12552#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12553#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12554
12555/*
12556 * BIOS auto configuration
12557 */
12558static int alc262_parse_auto_config(struct hda_codec *codec)
12559{
12560 struct alc_spec *spec = codec->spec;
12561 int err;
12562 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12563
f12ab1e0
TI
12564 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12565 alc262_ignore);
12566 if (err < 0)
df694daa 12567 return err;
e64f14f4 12568 if (!spec->autocfg.line_outs) {
0852d7a6 12569 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12570 spec->multiout.max_channels = 2;
12571 spec->no_analog = 1;
12572 goto dig_only;
12573 }
df694daa 12574 return 0; /* can't find valid BIOS pin config */
e64f14f4 12575 }
f12ab1e0
TI
12576 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12577 if (err < 0)
12578 return err;
05f5f477 12579 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12580 if (err < 0)
df694daa
KY
12581 return err;
12582
12583 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12584
e64f14f4 12585 dig_only:
757899ac 12586 alc_auto_parse_digital(codec);
df694daa 12587
603c4019 12588 if (spec->kctls.list)
d88897ea 12589 add_mixer(spec, spec->kctls.list);
df694daa 12590
d88897ea 12591 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12592 spec->num_mux_defs = 1;
61b9b9b1 12593 spec->input_mux = &spec->private_imux[0];
df694daa 12594
776e184e
TI
12595 err = alc_auto_add_mic_boost(codec);
12596 if (err < 0)
12597 return err;
12598
6227cdce 12599 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12600
df694daa
KY
12601 return 1;
12602}
12603
12604#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12605#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12606#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12607#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12608
12609
12610/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12611static void alc262_auto_init(struct hda_codec *codec)
df694daa 12612{
f6c7e546 12613 struct alc_spec *spec = codec->spec;
df694daa
KY
12614 alc262_auto_init_multi_out(codec);
12615 alc262_auto_init_hp_out(codec);
12616 alc262_auto_init_analog_input(codec);
f511b01c 12617 alc262_auto_init_input_src(codec);
757899ac 12618 alc_auto_init_digital(codec);
f6c7e546 12619 if (spec->unsol_event)
7fb0d78f 12620 alc_inithook(codec);
df694daa
KY
12621}
12622
12623/*
12624 * configuration and preset
12625 */
ea734963 12626static const char * const alc262_models[ALC262_MODEL_LAST] = {
f5fcc13c
TI
12627 [ALC262_BASIC] = "basic",
12628 [ALC262_HIPPO] = "hippo",
12629 [ALC262_HIPPO_1] = "hippo_1",
12630 [ALC262_FUJITSU] = "fujitsu",
12631 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12632 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12633 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12634 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12635 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12636 [ALC262_BENQ_T31] = "benq-t31",
12637 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12638 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12639 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12640 [ALC262_ULTRA] = "ultra",
0e31daf7 12641 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12642 [ALC262_NEC] = "nec",
ba340e82 12643 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12644 [ALC262_AUTO] = "auto",
12645};
12646
12647static struct snd_pci_quirk alc262_cfg_tbl[] = {
12648 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12649 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12650 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12651 ALC262_HP_BPC),
12652 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12653 ALC262_HP_BPC),
5734a07c
TI
12654 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12655 ALC262_HP_BPC),
53eff7e1
TI
12656 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12657 ALC262_HP_BPC),
cd7509a4 12658 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12659 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12660 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12661 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12662 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12663 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12664 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12665 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12666 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12667 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12668 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12669 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12670 ALC262_HP_TC_T5735),
8c427226 12671 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12672 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12673 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12674 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12675 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12676 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12677 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12678 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12679#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12680 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12681 ALC262_SONY_ASSAMD),
c5b5165c 12682#endif
36ca6e13 12683 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12684 ALC262_TOSHIBA_RX1),
80ffe869 12685 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12686 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12687 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12688 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12689 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12690 ALC262_ULTRA),
3e420e78 12691 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12692 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12693 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12694 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12695 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12696 {}
12697};
12698
12699static struct alc_config_preset alc262_presets[] = {
12700 [ALC262_BASIC] = {
12701 .mixers = { alc262_base_mixer },
12702 .init_verbs = { alc262_init_verbs },
12703 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12704 .dac_nids = alc262_dac_nids,
12705 .hp_nid = 0x03,
12706 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12707 .channel_mode = alc262_modes,
a3bcba38 12708 .input_mux = &alc262_capture_source,
df694daa 12709 },
ccc656ce 12710 [ALC262_HIPPO] = {
42171c17 12711 .mixers = { alc262_hippo_mixer },
6732bd0d 12712 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12713 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12714 .dac_nids = alc262_dac_nids,
12715 .hp_nid = 0x03,
12716 .dig_out_nid = ALC262_DIGOUT_NID,
12717 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12718 .channel_mode = alc262_modes,
12719 .input_mux = &alc262_capture_source,
12720 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12721 .setup = alc262_hippo_setup,
12722 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12723 },
12724 [ALC262_HIPPO_1] = {
12725 .mixers = { alc262_hippo1_mixer },
12726 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12727 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12728 .dac_nids = alc262_dac_nids,
12729 .hp_nid = 0x02,
12730 .dig_out_nid = ALC262_DIGOUT_NID,
12731 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12732 .channel_mode = alc262_modes,
12733 .input_mux = &alc262_capture_source,
42171c17 12734 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12735 .setup = alc262_hippo1_setup,
12736 .init_hook = alc262_hippo_automute,
ccc656ce 12737 },
834be88d
TI
12738 [ALC262_FUJITSU] = {
12739 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12740 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12741 alc262_fujitsu_unsol_verbs },
834be88d
TI
12742 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12743 .dac_nids = alc262_dac_nids,
12744 .hp_nid = 0x03,
12745 .dig_out_nid = ALC262_DIGOUT_NID,
12746 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12747 .channel_mode = alc262_modes,
12748 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12749 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12750 .init_hook = alc262_fujitsu_init_hook,
834be88d 12751 },
9c7f852e
TI
12752 [ALC262_HP_BPC] = {
12753 .mixers = { alc262_HP_BPC_mixer },
12754 .init_verbs = { alc262_HP_BPC_init_verbs },
12755 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12756 .dac_nids = alc262_dac_nids,
12757 .hp_nid = 0x03,
12758 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12759 .channel_mode = alc262_modes,
12760 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12761 .unsol_event = alc262_hp_bpc_unsol_event,
12762 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12763 },
cd7509a4
KY
12764 [ALC262_HP_BPC_D7000_WF] = {
12765 .mixers = { alc262_HP_BPC_WildWest_mixer },
12766 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12767 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12768 .dac_nids = alc262_dac_nids,
12769 .hp_nid = 0x03,
12770 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12771 .channel_mode = alc262_modes,
accbe498 12772 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12773 .unsol_event = alc262_hp_wildwest_unsol_event,
12774 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12775 },
cd7509a4
KY
12776 [ALC262_HP_BPC_D7000_WL] = {
12777 .mixers = { alc262_HP_BPC_WildWest_mixer,
12778 alc262_HP_BPC_WildWest_option_mixer },
12779 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12780 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12781 .dac_nids = alc262_dac_nids,
12782 .hp_nid = 0x03,
12783 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12784 .channel_mode = alc262_modes,
accbe498 12785 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12786 .unsol_event = alc262_hp_wildwest_unsol_event,
12787 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12788 },
66d2a9d6
KY
12789 [ALC262_HP_TC_T5735] = {
12790 .mixers = { alc262_hp_t5735_mixer },
12791 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12792 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12793 .dac_nids = alc262_dac_nids,
12794 .hp_nid = 0x03,
12795 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12796 .channel_mode = alc262_modes,
12797 .input_mux = &alc262_capture_source,
dc99be47 12798 .unsol_event = alc_sku_unsol_event,
4f5d1706 12799 .setup = alc262_hp_t5735_setup,
dc99be47 12800 .init_hook = alc_inithook,
8c427226
KY
12801 },
12802 [ALC262_HP_RP5700] = {
12803 .mixers = { alc262_hp_rp5700_mixer },
12804 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12805 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12806 .dac_nids = alc262_dac_nids,
12807 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12808 .channel_mode = alc262_modes,
12809 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12810 },
304dcaac
TI
12811 [ALC262_BENQ_ED8] = {
12812 .mixers = { alc262_base_mixer },
12813 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12814 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12815 .dac_nids = alc262_dac_nids,
12816 .hp_nid = 0x03,
12817 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12818 .channel_mode = alc262_modes,
12819 .input_mux = &alc262_capture_source,
f12ab1e0 12820 },
272a527c
KY
12821 [ALC262_SONY_ASSAMD] = {
12822 .mixers = { alc262_sony_mixer },
12823 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12824 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12825 .dac_nids = alc262_dac_nids,
12826 .hp_nid = 0x02,
12827 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12828 .channel_mode = alc262_modes,
12829 .input_mux = &alc262_capture_source,
12830 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12831 .setup = alc262_hippo_setup,
12832 .init_hook = alc262_hippo_automute,
83c34218
KY
12833 },
12834 [ALC262_BENQ_T31] = {
12835 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12836 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12837 alc_hp15_unsol_verbs },
83c34218
KY
12838 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12839 .dac_nids = alc262_dac_nids,
12840 .hp_nid = 0x03,
12841 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12842 .channel_mode = alc262_modes,
12843 .input_mux = &alc262_capture_source,
12844 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12845 .setup = alc262_hippo_setup,
12846 .init_hook = alc262_hippo_automute,
ea1fb29a 12847 },
f651b50b 12848 [ALC262_ULTRA] = {
f9e336f6
TI
12849 .mixers = { alc262_ultra_mixer },
12850 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12851 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12852 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12853 .dac_nids = alc262_dac_nids,
f651b50b
TD
12854 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12855 .channel_mode = alc262_modes,
12856 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12857 .adc_nids = alc262_adc_nids, /* ADC0 */
12858 .capsrc_nids = alc262_capsrc_nids,
12859 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12860 .unsol_event = alc262_ultra_unsol_event,
12861 .init_hook = alc262_ultra_automute,
12862 },
0e31daf7
J
12863 [ALC262_LENOVO_3000] = {
12864 .mixers = { alc262_lenovo_3000_mixer },
12865 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12866 alc262_lenovo_3000_unsol_verbs,
12867 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12868 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12869 .dac_nids = alc262_dac_nids,
12870 .hp_nid = 0x03,
12871 .dig_out_nid = ALC262_DIGOUT_NID,
12872 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12873 .channel_mode = alc262_modes,
12874 .input_mux = &alc262_fujitsu_capture_source,
12875 .unsol_event = alc262_lenovo_3000_unsol_event,
12876 },
e8f9ae2a
PT
12877 [ALC262_NEC] = {
12878 .mixers = { alc262_nec_mixer },
12879 .init_verbs = { alc262_nec_verbs },
12880 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12881 .dac_nids = alc262_dac_nids,
12882 .hp_nid = 0x03,
12883 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12884 .channel_mode = alc262_modes,
12885 .input_mux = &alc262_capture_source,
12886 },
4e555fe5
KY
12887 [ALC262_TOSHIBA_S06] = {
12888 .mixers = { alc262_toshiba_s06_mixer },
12889 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12890 alc262_eapd_verbs },
12891 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12892 .capsrc_nids = alc262_dmic_capsrc_nids,
12893 .dac_nids = alc262_dac_nids,
12894 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12895 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12896 .dig_out_nid = ALC262_DIGOUT_NID,
12897 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12898 .channel_mode = alc262_modes,
4f5d1706
TI
12899 .unsol_event = alc_sku_unsol_event,
12900 .setup = alc262_toshiba_s06_setup,
12901 .init_hook = alc_inithook,
4e555fe5 12902 },
9f99a638
HM
12903 [ALC262_TOSHIBA_RX1] = {
12904 .mixers = { alc262_toshiba_rx1_mixer },
12905 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12906 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12907 .dac_nids = alc262_dac_nids,
12908 .hp_nid = 0x03,
12909 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12910 .channel_mode = alc262_modes,
12911 .input_mux = &alc262_capture_source,
12912 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12913 .setup = alc262_hippo_setup,
12914 .init_hook = alc262_hippo_automute,
9f99a638 12915 },
ba340e82
TV
12916 [ALC262_TYAN] = {
12917 .mixers = { alc262_tyan_mixer },
12918 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12919 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12920 .dac_nids = alc262_dac_nids,
12921 .hp_nid = 0x02,
12922 .dig_out_nid = ALC262_DIGOUT_NID,
12923 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12924 .channel_mode = alc262_modes,
12925 .input_mux = &alc262_capture_source,
a9fd4f3f 12926 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12927 .setup = alc262_tyan_setup,
12928 .init_hook = alc_automute_amp,
ba340e82 12929 },
df694daa
KY
12930};
12931
12932static int patch_alc262(struct hda_codec *codec)
12933{
12934 struct alc_spec *spec;
12935 int board_config;
12936 int err;
12937
dc041e0b 12938 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12939 if (spec == NULL)
12940 return -ENOMEM;
12941
12942 codec->spec = spec;
12943#if 0
f12ab1e0
TI
12944 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12945 * under-run
12946 */
df694daa
KY
12947 {
12948 int tmp;
12949 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12950 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12951 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12952 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12953 }
12954#endif
da00c244 12955 alc_auto_parse_customize_define(codec);
df694daa 12956
2c3bf9ab
TI
12957 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12958
f5fcc13c
TI
12959 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12960 alc262_models,
12961 alc262_cfg_tbl);
cd7509a4 12962
f5fcc13c 12963 if (board_config < 0) {
9a11f1aa
TI
12964 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12965 codec->chip_name);
df694daa
KY
12966 board_config = ALC262_AUTO;
12967 }
12968
b5bfbc67
TI
12969 if (board_config == ALC262_AUTO) {
12970 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12971 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12972 }
18675e42 12973
df694daa
KY
12974 if (board_config == ALC262_AUTO) {
12975 /* automatic parse from the BIOS config */
12976 err = alc262_parse_auto_config(codec);
12977 if (err < 0) {
12978 alc_free(codec);
12979 return err;
f12ab1e0 12980 } else if (!err) {
9c7f852e
TI
12981 printk(KERN_INFO
12982 "hda_codec: Cannot set up configuration "
12983 "from BIOS. Using base mode...\n");
df694daa
KY
12984 board_config = ALC262_BASIC;
12985 }
12986 }
12987
dc1eae25 12988 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12989 err = snd_hda_attach_beep_device(codec, 0x1);
12990 if (err < 0) {
12991 alc_free(codec);
12992 return err;
12993 }
680cd536
KK
12994 }
12995
df694daa 12996 if (board_config != ALC262_AUTO)
e9c364c0 12997 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12998
df694daa
KY
12999 spec->stream_analog_playback = &alc262_pcm_analog_playback;
13000 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 13001
df694daa
KY
13002 spec->stream_digital_playback = &alc262_pcm_digital_playback;
13003 spec->stream_digital_capture = &alc262_pcm_digital_capture;
13004
f12ab1e0 13005 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
13006 int i;
13007 /* check whether the digital-mic has to be supported */
13008 for (i = 0; i < spec->input_mux->num_items; i++) {
13009 if (spec->input_mux->items[i].index >= 9)
13010 break;
13011 }
13012 if (i < spec->input_mux->num_items) {
13013 /* use only ADC0 */
13014 spec->adc_nids = alc262_dmic_adc_nids;
13015 spec->num_adc_nids = 1;
13016 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 13017 } else {
8c927b4a
TI
13018 /* all analog inputs */
13019 /* check whether NID 0x07 is valid */
13020 unsigned int wcap = get_wcaps(codec, 0x07);
13021
13022 /* get type */
a22d543a 13023 wcap = get_wcaps_type(wcap);
8c927b4a
TI
13024 if (wcap != AC_WID_AUD_IN) {
13025 spec->adc_nids = alc262_adc_nids_alt;
13026 spec->num_adc_nids =
13027 ARRAY_SIZE(alc262_adc_nids_alt);
13028 spec->capsrc_nids = alc262_capsrc_nids_alt;
13029 } else {
13030 spec->adc_nids = alc262_adc_nids;
13031 spec->num_adc_nids =
13032 ARRAY_SIZE(alc262_adc_nids);
13033 spec->capsrc_nids = alc262_capsrc_nids;
13034 }
df694daa
KY
13035 }
13036 }
e64f14f4 13037 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 13038 set_capture_mixer(codec);
dc1eae25 13039 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 13040 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 13041
b5bfbc67 13042 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18675e42 13043
2134ea4f
TI
13044 spec->vmaster_nid = 0x0c;
13045
df694daa
KY
13046 codec->patch_ops = alc_patch_ops;
13047 if (board_config == ALC262_AUTO)
ae6b813a 13048 spec->init_hook = alc262_auto_init;
bf1b0225
KY
13049
13050 alc_init_jacks(codec);
cb53c626
TI
13051#ifdef CONFIG_SND_HDA_POWER_SAVE
13052 if (!spec->loopback.amplist)
13053 spec->loopback.amplist = alc262_loopbacks;
13054#endif
ea1fb29a 13055
df694daa
KY
13056 return 0;
13057}
13058
a361d84b
KY
13059/*
13060 * ALC268 channel source setting (2 channel)
13061 */
13062#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13063#define alc268_modes alc260_modes
ea1fb29a 13064
a361d84b
KY
13065static hda_nid_t alc268_dac_nids[2] = {
13066 /* front, hp */
13067 0x02, 0x03
13068};
13069
13070static hda_nid_t alc268_adc_nids[2] = {
13071 /* ADC0-1 */
13072 0x08, 0x07
13073};
13074
13075static hda_nid_t alc268_adc_nids_alt[1] = {
13076 /* ADC0 */
13077 0x08
13078};
13079
e1406348
TI
13080static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13081
a361d84b
KY
13082static struct snd_kcontrol_new alc268_base_mixer[] = {
13083 /* output mixer control */
13084 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13085 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13086 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13087 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13088 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13089 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13090 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
a361d84b
KY
13091 { }
13092};
13093
42171c17
TI
13094static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13095 /* output mixer control */
13096 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13097 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13098 ALC262_HIPPO_MASTER_SWITCH,
5f99f86a
DH
13099 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13100 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13101 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
42171c17
TI
13102 { }
13103};
13104
aef9d318
TI
13105/* bind Beep switches of both NID 0x0f and 0x10 */
13106static struct hda_bind_ctls alc268_bind_beep_sw = {
13107 .ops = &snd_hda_bind_sw,
13108 .values = {
13109 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13110 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13111 0
13112 },
13113};
13114
13115static struct snd_kcontrol_new alc268_beep_mixer[] = {
13116 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13117 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13118 { }
13119};
13120
d1a991a6
KY
13121static struct hda_verb alc268_eapd_verbs[] = {
13122 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13123 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13124 { }
13125};
13126
d273809e 13127/* Toshiba specific */
d273809e
TI
13128static struct hda_verb alc268_toshiba_verbs[] = {
13129 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13130 { } /* end */
13131};
13132
13133/* Acer specific */
889c4395 13134/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
13135static struct hda_bind_ctls alc268_acer_bind_master_vol = {
13136 .ops = &snd_hda_bind_vol,
13137 .values = {
13138 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13139 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13140 0
13141 },
13142};
13143
889c4395
TI
13144/* mute/unmute internal speaker according to the hp jack and mute state */
13145static void alc268_acer_automute(struct hda_codec *codec, int force)
13146{
13147 struct alc_spec *spec = codec->spec;
13148 unsigned int mute;
13149
13150 if (force || !spec->sense_updated) {
864f92be 13151 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
13152 spec->sense_updated = 1;
13153 }
13154 if (spec->jack_present)
13155 mute = HDA_AMP_MUTE; /* mute internal speaker */
13156 else /* unmute internal speaker if necessary */
13157 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13158 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13159 HDA_AMP_MUTE, mute);
13160}
13161
13162
13163/* bind hp and internal speaker mute (with plug check) */
13164static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
13165 struct snd_ctl_elem_value *ucontrol)
13166{
13167 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
13168 long *valp = ucontrol->value.integer.value;
13169 int change;
13170
8de56b7d 13171 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
13172 if (change)
13173 alc268_acer_automute(codec, 0);
13174 return change;
13175}
d273809e 13176
8ef355da
KY
13177static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13178 /* output mixer control */
13179 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13180 {
13181 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13182 .name = "Master Playback Switch",
5e26dfd0 13183 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
13184 .info = snd_hda_mixer_amp_switch_info,
13185 .get = snd_hda_mixer_amp_switch_get,
13186 .put = alc268_acer_master_sw_put,
13187 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13188 },
13189 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13190 { }
13191};
13192
d273809e
TI
13193static struct snd_kcontrol_new alc268_acer_mixer[] = {
13194 /* output mixer control */
13195 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13196 {
13197 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13198 .name = "Master Playback Switch",
5e26dfd0 13199 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
13200 .info = snd_hda_mixer_amp_switch_info,
13201 .get = snd_hda_mixer_amp_switch_get,
13202 .put = alc268_acer_master_sw_put,
13203 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13204 },
5f99f86a
DH
13205 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13206 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13207 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
d273809e
TI
13208 { }
13209};
13210
c238b4f4
TI
13211static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13212 /* output mixer control */
13213 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13214 {
13215 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13216 .name = "Master Playback Switch",
5e26dfd0 13217 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
13218 .info = snd_hda_mixer_amp_switch_info,
13219 .get = snd_hda_mixer_amp_switch_get,
13220 .put = alc268_acer_master_sw_put,
13221 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13222 },
5f99f86a
DH
13223 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13224 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
c238b4f4
TI
13225 { }
13226};
13227
8ef355da
KY
13228static struct hda_verb alc268_acer_aspire_one_verbs[] = {
13229 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13230 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13231 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13232 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13233 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13234 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13235 { }
13236};
13237
d273809e 13238static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13239 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13240 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13241 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13242 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13243 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13244 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13245 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13246 { }
13247};
13248
13249/* unsolicited event for HP jack sensing */
42171c17 13250#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
13251#define alc268_toshiba_setup alc262_hippo_setup
13252#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
13253
13254static void alc268_acer_unsol_event(struct hda_codec *codec,
13255 unsigned int res)
13256{
889c4395 13257 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
13258 return;
13259 alc268_acer_automute(codec, 1);
13260}
13261
889c4395
TI
13262static void alc268_acer_init_hook(struct hda_codec *codec)
13263{
13264 alc268_acer_automute(codec, 1);
13265}
13266
8ef355da
KY
13267/* toggle speaker-output according to the hp-jack state */
13268static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
13269{
13270 unsigned int present;
13271 unsigned char bits;
13272
864f92be 13273 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13274 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 13275 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 13276 HDA_AMP_MUTE, bits);
8ef355da 13277 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 13278 HDA_AMP_MUTE, bits);
8ef355da
KY
13279}
13280
8ef355da
KY
13281static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
13282 unsigned int res)
13283{
4f5d1706
TI
13284 switch (res >> 26) {
13285 case ALC880_HP_EVENT:
8ef355da 13286 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
13287 break;
13288 case ALC880_MIC_EVENT:
13289 alc_mic_automute(codec);
13290 break;
13291 }
13292}
13293
13294static void alc268_acer_lc_setup(struct hda_codec *codec)
13295{
13296 struct alc_spec *spec = codec->spec;
13297 spec->ext_mic.pin = 0x18;
13298 spec->ext_mic.mux_idx = 0;
13299 spec->int_mic.pin = 0x12;
13300 spec->int_mic.mux_idx = 6;
13301 spec->auto_mic = 1;
8ef355da
KY
13302}
13303
13304static void alc268_acer_lc_init_hook(struct hda_codec *codec)
13305{
13306 alc268_aspire_one_speaker_automute(codec);
4f5d1706 13307 alc_mic_automute(codec);
8ef355da
KY
13308}
13309
3866f0b0
TI
13310static struct snd_kcontrol_new alc268_dell_mixer[] = {
13311 /* output mixer control */
13312 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13313 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13314 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13315 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13316 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13317 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
3866f0b0
TI
13318 { }
13319};
13320
13321static struct hda_verb alc268_dell_verbs[] = {
13322 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13323 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13324 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 13325 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
13326 { }
13327};
13328
13329/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 13330static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 13331{
a9fd4f3f 13332 struct alc_spec *spec = codec->spec;
3866f0b0 13333
a9fd4f3f
TI
13334 spec->autocfg.hp_pins[0] = 0x15;
13335 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13336 spec->ext_mic.pin = 0x18;
13337 spec->ext_mic.mux_idx = 0;
13338 spec->int_mic.pin = 0x19;
13339 spec->int_mic.mux_idx = 1;
13340 spec->auto_mic = 1;
3866f0b0
TI
13341}
13342
eb5a6621
HRK
13343static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13344 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13345 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13346 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13347 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13348 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13349 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
5f99f86a
DH
13350 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13351 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
eb5a6621
HRK
13352 { }
13353};
13354
13355static struct hda_verb alc267_quanta_il1_verbs[] = {
13356 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13357 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13358 { }
13359};
13360
4f5d1706 13361static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 13362{
a9fd4f3f 13363 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
13364 spec->autocfg.hp_pins[0] = 0x15;
13365 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13366 spec->ext_mic.pin = 0x18;
13367 spec->ext_mic.mux_idx = 0;
13368 spec->int_mic.pin = 0x19;
13369 spec->int_mic.mux_idx = 1;
13370 spec->auto_mic = 1;
eb5a6621
HRK
13371}
13372
a361d84b
KY
13373/*
13374 * generic initialization of ADC, input mixers and output mixers
13375 */
13376static struct hda_verb alc268_base_init_verbs[] = {
13377 /* Unmute DAC0-1 and set vol = 0 */
13378 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 13379 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13380
13381 /*
13382 * Set up output mixers (0x0c - 0x0e)
13383 */
13384 /* set vol=0 to output mixers */
13385 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13386 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13387
13388 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13389 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13390
13391 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13392 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13393 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13394 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13395 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13396 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13397 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13398 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13399
13400 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13401 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13402 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13403 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13404 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13405
13406 /* set PCBEEP vol = 0, mute connections */
13407 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13408 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13409 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13410
a9b3aa8a 13411 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13412
a9b3aa8a
JZ
13413 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13414 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13415 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13416 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13417
a361d84b
KY
13418 { }
13419};
13420
13421/*
13422 * generic initialization of ADC, input mixers and output mixers
13423 */
13424static struct hda_verb alc268_volume_init_verbs[] = {
13425 /* set output DAC */
4cfb91c6
TI
13426 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13427 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13428
13429 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13430 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13431 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13432 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13433 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13434
a361d84b 13435 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13436 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13437 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13438
13439 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13440 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13441
aef9d318
TI
13442 /* set PCBEEP vol = 0, mute connections */
13443 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13444 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13445 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13446
13447 { }
13448};
13449
fdbc6626
TI
13450static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13451 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13452 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13453 { } /* end */
13454};
13455
a361d84b
KY
13456static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13457 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13458 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13459 _DEFINE_CAPSRC(1),
a361d84b
KY
13460 { } /* end */
13461};
13462
13463static struct snd_kcontrol_new alc268_capture_mixer[] = {
13464 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13465 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13466 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13467 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13468 _DEFINE_CAPSRC(2),
a361d84b
KY
13469 { } /* end */
13470};
13471
13472static struct hda_input_mux alc268_capture_source = {
13473 .num_items = 4,
13474 .items = {
13475 { "Mic", 0x0 },
13476 { "Front Mic", 0x1 },
13477 { "Line", 0x2 },
13478 { "CD", 0x3 },
13479 },
13480};
13481
0ccb541c 13482static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13483 .num_items = 3,
13484 .items = {
13485 { "Mic", 0x0 },
13486 { "Internal Mic", 0x1 },
13487 { "Line", 0x2 },
13488 },
13489};
13490
13491static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13492 .num_items = 3,
13493 .items = {
13494 { "Mic", 0x0 },
13495 { "Internal Mic", 0x6 },
13496 { "Line", 0x2 },
13497 },
13498};
13499
86c53bd2
JW
13500#ifdef CONFIG_SND_DEBUG
13501static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13502 /* Volume widgets */
13503 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13504 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13505 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13506 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13507 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13508 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13509 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13510 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13511 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13512 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13513 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13514 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13515 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13516 /* The below appears problematic on some hardwares */
13517 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13518 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13519 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13520 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13521 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13522
13523 /* Modes for retasking pin widgets */
13524 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13525 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13526 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13527 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13528
13529 /* Controls for GPIO pins, assuming they are configured as outputs */
13530 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13531 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13532 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13533 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13534
13535 /* Switches to allow the digital SPDIF output pin to be enabled.
13536 * The ALC268 does not have an SPDIF input.
13537 */
13538 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13539
13540 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13541 * this output to turn on an external amplifier.
13542 */
13543 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13544 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13545
13546 { } /* end */
13547};
13548#endif
13549
a361d84b
KY
13550/* create input playback/capture controls for the given pin */
13551static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13552 const char *ctlname, int idx)
13553{
3f3b7c1a 13554 hda_nid_t dac;
a361d84b
KY
13555 int err;
13556
3f3b7c1a
TI
13557 switch (nid) {
13558 case 0x14:
13559 case 0x16:
13560 dac = 0x02;
13561 break;
13562 case 0x15:
b08b1637
TI
13563 case 0x1a: /* ALC259/269 only */
13564 case 0x1b: /* ALC259/269 only */
531d8791 13565 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13566 dac = 0x03;
13567 break;
13568 default:
c7a9434d
TI
13569 snd_printd(KERN_WARNING "hda_codec: "
13570 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13571 return 0;
13572 }
13573 if (spec->multiout.dac_nids[0] != dac &&
13574 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13575 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13576 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13577 HDA_OUTPUT));
13578 if (err < 0)
13579 return err;
3f3b7c1a
TI
13580 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13581 }
13582
3f3b7c1a 13583 if (nid != 0x16)
0afe5f89 13584 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13585 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13586 else /* mono */
0afe5f89 13587 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13588 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13589 if (err < 0)
13590 return err;
13591 return 0;
13592}
13593
13594/* add playback controls from the parsed DAC table */
13595static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13596 const struct auto_pin_cfg *cfg)
13597{
13598 hda_nid_t nid;
13599 int err;
13600
a361d84b 13601 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13602
13603 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13604 if (nid) {
13605 const char *name;
13606 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13607 name = "Speaker";
13608 else
13609 name = "Front";
13610 err = alc268_new_analog_output(spec, nid, name, 0);
13611 if (err < 0)
13612 return err;
13613 }
a361d84b
KY
13614
13615 nid = cfg->speaker_pins[0];
13616 if (nid == 0x1d) {
0afe5f89 13617 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13618 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13619 if (err < 0)
13620 return err;
7bfb9c03 13621 } else if (nid) {
3f3b7c1a
TI
13622 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13623 if (err < 0)
13624 return err;
a361d84b
KY
13625 }
13626 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13627 if (nid) {
13628 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13629 if (err < 0)
13630 return err;
13631 }
a361d84b
KY
13632
13633 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13634 if (nid == 0x16) {
0afe5f89 13635 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13636 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13637 if (err < 0)
13638 return err;
13639 }
ea1fb29a 13640 return 0;
a361d84b
KY
13641}
13642
13643/* create playback/capture controls for input pins */
05f5f477 13644static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13645 const struct auto_pin_cfg *cfg)
13646{
05f5f477 13647 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13648}
13649
e9af4f36
TI
13650static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13651 hda_nid_t nid, int pin_type)
13652{
13653 int idx;
13654
13655 alc_set_pin_output(codec, nid, pin_type);
13656 if (nid == 0x14 || nid == 0x16)
13657 idx = 0;
13658 else
13659 idx = 1;
13660 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13661}
13662
13663static void alc268_auto_init_multi_out(struct hda_codec *codec)
13664{
13665 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13666 int i;
13667
13668 for (i = 0; i < spec->autocfg.line_outs; i++) {
13669 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13670 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13671 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13672 }
13673}
13674
13675static void alc268_auto_init_hp_out(struct hda_codec *codec)
13676{
13677 struct alc_spec *spec = codec->spec;
13678 hda_nid_t pin;
e1ca7b4e 13679 int i;
e9af4f36 13680
e1ca7b4e
TI
13681 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13682 pin = spec->autocfg.hp_pins[i];
e9af4f36 13683 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13684 }
13685 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13686 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13687 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13688 }
13689 if (spec->autocfg.mono_out_pin)
13690 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13691 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36
TI
13692}
13693
a361d84b
KY
13694static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13695{
13696 struct alc_spec *spec = codec->spec;
13697 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13698 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13699 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13700 unsigned int dac_vol1, dac_vol2;
13701
e9af4f36 13702 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13703 snd_hda_codec_write(codec, speaker_nid, 0,
13704 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13705 /* mute mixer inputs from 0x1d */
a361d84b
KY
13706 snd_hda_codec_write(codec, 0x0f, 0,
13707 AC_VERB_SET_AMP_GAIN_MUTE,
13708 AMP_IN_UNMUTE(1));
13709 snd_hda_codec_write(codec, 0x10, 0,
13710 AC_VERB_SET_AMP_GAIN_MUTE,
13711 AMP_IN_UNMUTE(1));
13712 } else {
e9af4f36 13713 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13714 snd_hda_codec_write(codec, 0x0f, 0,
13715 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13716 snd_hda_codec_write(codec, 0x10, 0,
13717 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13718 }
13719
13720 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13721 if (line_nid == 0x14)
a361d84b
KY
13722 dac_vol2 = AMP_OUT_ZERO;
13723 else if (line_nid == 0x15)
13724 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13725 if (hp_nid == 0x14)
a361d84b
KY
13726 dac_vol2 = AMP_OUT_ZERO;
13727 else if (hp_nid == 0x15)
13728 dac_vol1 = AMP_OUT_ZERO;
13729 if (line_nid != 0x16 || hp_nid != 0x16 ||
13730 spec->autocfg.line_out_pins[1] != 0x16 ||
13731 spec->autocfg.line_out_pins[2] != 0x16)
13732 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13733
13734 snd_hda_codec_write(codec, 0x02, 0,
13735 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13736 snd_hda_codec_write(codec, 0x03, 0,
13737 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13738}
13739
def319f9 13740/* pcm configuration: identical with ALC880 */
a361d84b
KY
13741#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13742#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13743#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13744#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13745
13746/*
13747 * BIOS auto configuration
13748 */
13749static int alc268_parse_auto_config(struct hda_codec *codec)
13750{
13751 struct alc_spec *spec = codec->spec;
13752 int err;
13753 static hda_nid_t alc268_ignore[] = { 0 };
13754
13755 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13756 alc268_ignore);
13757 if (err < 0)
13758 return err;
7e0e44d4
TI
13759 if (!spec->autocfg.line_outs) {
13760 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13761 spec->multiout.max_channels = 2;
13762 spec->no_analog = 1;
13763 goto dig_only;
13764 }
a361d84b 13765 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13766 }
a361d84b
KY
13767 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13768 if (err < 0)
13769 return err;
05f5f477 13770 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13771 if (err < 0)
13772 return err;
13773
13774 spec->multiout.max_channels = 2;
13775
7e0e44d4 13776 dig_only:
a361d84b 13777 /* digital only support output */
757899ac 13778 alc_auto_parse_digital(codec);
603c4019 13779 if (spec->kctls.list)
d88897ea 13780 add_mixer(spec, spec->kctls.list);
a361d84b 13781
892981ff 13782 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13783 add_mixer(spec, alc268_beep_mixer);
aef9d318 13784
d88897ea 13785 add_verb(spec, alc268_volume_init_verbs);
5908589f 13786 spec->num_mux_defs = 2;
61b9b9b1 13787 spec->input_mux = &spec->private_imux[0];
a361d84b 13788
776e184e
TI
13789 err = alc_auto_add_mic_boost(codec);
13790 if (err < 0)
13791 return err;
13792
6227cdce 13793 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13794
a361d84b
KY
13795 return 1;
13796}
13797
a361d84b
KY
13798#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13799
13800/* init callback for auto-configuration model -- overriding the default init */
13801static void alc268_auto_init(struct hda_codec *codec)
13802{
f6c7e546 13803 struct alc_spec *spec = codec->spec;
a361d84b
KY
13804 alc268_auto_init_multi_out(codec);
13805 alc268_auto_init_hp_out(codec);
13806 alc268_auto_init_mono_speaker_out(codec);
13807 alc268_auto_init_analog_input(codec);
757899ac 13808 alc_auto_init_digital(codec);
f6c7e546 13809 if (spec->unsol_event)
7fb0d78f 13810 alc_inithook(codec);
a361d84b
KY
13811}
13812
13813/*
13814 * configuration and preset
13815 */
ea734963 13816static const char * const alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13817 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13818 [ALC268_3ST] = "3stack",
983f8ae4 13819 [ALC268_TOSHIBA] = "toshiba",
d273809e 13820 [ALC268_ACER] = "acer",
c238b4f4 13821 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13822 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13823 [ALC268_DELL] = "dell",
f12462c5 13824 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13825#ifdef CONFIG_SND_DEBUG
13826 [ALC268_TEST] = "test",
13827#endif
a361d84b
KY
13828 [ALC268_AUTO] = "auto",
13829};
13830
13831static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13832 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13833 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13834 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13835 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13836 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13837 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13838 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13839 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13840 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13841 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13842 /* almost compatible with toshiba but with optional digital outs;
13843 * auto-probing seems working fine
13844 */
8871e5b9 13845 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13846 ALC268_AUTO),
a361d84b 13847 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13848 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13849 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13850 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13851 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13852 {}
13853};
13854
3abf2f36
TI
13855/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13856static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13857 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13858 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13859 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13860 ALC268_TOSHIBA),
13861 {}
13862};
13863
a361d84b 13864static struct alc_config_preset alc268_presets[] = {
eb5a6621 13865 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13866 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13867 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13868 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13869 alc267_quanta_il1_verbs },
13870 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13871 .dac_nids = alc268_dac_nids,
13872 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13873 .adc_nids = alc268_adc_nids_alt,
13874 .hp_nid = 0x03,
13875 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13876 .channel_mode = alc268_modes,
4f5d1706
TI
13877 .unsol_event = alc_sku_unsol_event,
13878 .setup = alc267_quanta_il1_setup,
13879 .init_hook = alc_inithook,
eb5a6621 13880 },
a361d84b 13881 [ALC268_3ST] = {
aef9d318
TI
13882 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13883 alc268_beep_mixer },
a361d84b
KY
13884 .init_verbs = { alc268_base_init_verbs },
13885 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13886 .dac_nids = alc268_dac_nids,
13887 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13888 .adc_nids = alc268_adc_nids_alt,
e1406348 13889 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13890 .hp_nid = 0x03,
13891 .dig_out_nid = ALC268_DIGOUT_NID,
13892 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13893 .channel_mode = alc268_modes,
13894 .input_mux = &alc268_capture_source,
13895 },
d1a991a6 13896 [ALC268_TOSHIBA] = {
42171c17 13897 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13898 alc268_beep_mixer },
d273809e
TI
13899 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13900 alc268_toshiba_verbs },
d1a991a6
KY
13901 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13902 .dac_nids = alc268_dac_nids,
13903 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13904 .adc_nids = alc268_adc_nids_alt,
e1406348 13905 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13906 .hp_nid = 0x03,
13907 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13908 .channel_mode = alc268_modes,
13909 .input_mux = &alc268_capture_source,
d273809e 13910 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13911 .setup = alc268_toshiba_setup,
13912 .init_hook = alc268_toshiba_automute,
d273809e
TI
13913 },
13914 [ALC268_ACER] = {
432fd133 13915 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13916 alc268_beep_mixer },
d273809e
TI
13917 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13918 alc268_acer_verbs },
13919 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13920 .dac_nids = alc268_dac_nids,
13921 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13922 .adc_nids = alc268_adc_nids_alt,
e1406348 13923 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13924 .hp_nid = 0x02,
13925 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13926 .channel_mode = alc268_modes,
0ccb541c 13927 .input_mux = &alc268_acer_capture_source,
d273809e 13928 .unsol_event = alc268_acer_unsol_event,
889c4395 13929 .init_hook = alc268_acer_init_hook,
d1a991a6 13930 },
c238b4f4
TI
13931 [ALC268_ACER_DMIC] = {
13932 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13933 alc268_beep_mixer },
13934 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13935 alc268_acer_verbs },
13936 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13937 .dac_nids = alc268_dac_nids,
13938 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13939 .adc_nids = alc268_adc_nids_alt,
13940 .capsrc_nids = alc268_capsrc_nids,
13941 .hp_nid = 0x02,
13942 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13943 .channel_mode = alc268_modes,
13944 .input_mux = &alc268_acer_dmic_capture_source,
13945 .unsol_event = alc268_acer_unsol_event,
13946 .init_hook = alc268_acer_init_hook,
13947 },
8ef355da
KY
13948 [ALC268_ACER_ASPIRE_ONE] = {
13949 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13950 alc268_beep_mixer,
fdbc6626 13951 alc268_capture_nosrc_mixer },
8ef355da
KY
13952 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13953 alc268_acer_aspire_one_verbs },
13954 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13955 .dac_nids = alc268_dac_nids,
13956 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13957 .adc_nids = alc268_adc_nids_alt,
13958 .capsrc_nids = alc268_capsrc_nids,
13959 .hp_nid = 0x03,
13960 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13961 .channel_mode = alc268_modes,
8ef355da 13962 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13963 .setup = alc268_acer_lc_setup,
8ef355da
KY
13964 .init_hook = alc268_acer_lc_init_hook,
13965 },
3866f0b0 13966 [ALC268_DELL] = {
fdbc6626
TI
13967 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13968 alc268_capture_nosrc_mixer },
3866f0b0
TI
13969 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13970 alc268_dell_verbs },
13971 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13972 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13973 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13974 .adc_nids = alc268_adc_nids_alt,
13975 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13976 .hp_nid = 0x02,
13977 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13978 .channel_mode = alc268_modes,
a9fd4f3f 13979 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13980 .setup = alc268_dell_setup,
13981 .init_hook = alc_inithook,
3866f0b0 13982 },
f12462c5 13983 [ALC268_ZEPTO] = {
aef9d318
TI
13984 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13985 alc268_beep_mixer },
f12462c5
MT
13986 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13987 alc268_toshiba_verbs },
13988 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13989 .dac_nids = alc268_dac_nids,
13990 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13991 .adc_nids = alc268_adc_nids_alt,
e1406348 13992 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13993 .hp_nid = 0x03,
13994 .dig_out_nid = ALC268_DIGOUT_NID,
13995 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13996 .channel_mode = alc268_modes,
13997 .input_mux = &alc268_capture_source,
4f5d1706
TI
13998 .setup = alc268_toshiba_setup,
13999 .init_hook = alc268_toshiba_automute,
f12462c5 14000 },
86c53bd2
JW
14001#ifdef CONFIG_SND_DEBUG
14002 [ALC268_TEST] = {
14003 .mixers = { alc268_test_mixer, alc268_capture_mixer },
14004 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14005 alc268_volume_init_verbs },
14006 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
14007 .dac_nids = alc268_dac_nids,
14008 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14009 .adc_nids = alc268_adc_nids_alt,
e1406348 14010 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
14011 .hp_nid = 0x03,
14012 .dig_out_nid = ALC268_DIGOUT_NID,
14013 .num_channel_mode = ARRAY_SIZE(alc268_modes),
14014 .channel_mode = alc268_modes,
14015 .input_mux = &alc268_capture_source,
14016 },
14017#endif
a361d84b
KY
14018};
14019
14020static int patch_alc268(struct hda_codec *codec)
14021{
14022 struct alc_spec *spec;
14023 int board_config;
22971e3a 14024 int i, has_beep, err;
a361d84b 14025
ef86f581 14026 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
14027 if (spec == NULL)
14028 return -ENOMEM;
14029
14030 codec->spec = spec;
14031
14032 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
14033 alc268_models,
14034 alc268_cfg_tbl);
14035
3abf2f36
TI
14036 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
14037 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 14038 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 14039
a361d84b 14040 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
14041 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14042 codec->chip_name);
a361d84b
KY
14043 board_config = ALC268_AUTO;
14044 }
14045
14046 if (board_config == ALC268_AUTO) {
14047 /* automatic parse from the BIOS config */
14048 err = alc268_parse_auto_config(codec);
14049 if (err < 0) {
14050 alc_free(codec);
14051 return err;
14052 } else if (!err) {
14053 printk(KERN_INFO
14054 "hda_codec: Cannot set up configuration "
14055 "from BIOS. Using base mode...\n");
14056 board_config = ALC268_3ST;
14057 }
14058 }
14059
14060 if (board_config != ALC268_AUTO)
e9c364c0 14061 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 14062
a361d84b
KY
14063 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14064 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 14065 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 14066
a361d84b
KY
14067 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14068
22971e3a
TI
14069 has_beep = 0;
14070 for (i = 0; i < spec->num_mixers; i++) {
14071 if (spec->mixers[i] == alc268_beep_mixer) {
14072 has_beep = 1;
14073 break;
14074 }
14075 }
14076
14077 if (has_beep) {
14078 err = snd_hda_attach_beep_device(codec, 0x1);
14079 if (err < 0) {
14080 alc_free(codec);
14081 return err;
14082 }
14083 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14084 /* override the amp caps for beep generator */
14085 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
14086 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14087 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14088 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14089 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 14090 }
aef9d318 14091
7e0e44d4 14092 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
14093 /* check whether NID 0x07 is valid */
14094 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 14095 int i;
3866f0b0 14096
defb5ab2 14097 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 14098 /* get type */
a22d543a 14099 wcap = get_wcaps_type(wcap);
fdbc6626
TI
14100 if (spec->auto_mic ||
14101 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
14102 spec->adc_nids = alc268_adc_nids_alt;
14103 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
14104 if (spec->auto_mic)
14105 fixup_automic_adc(codec);
fdbc6626
TI
14106 if (spec->auto_mic || spec->input_mux->num_items == 1)
14107 add_mixer(spec, alc268_capture_nosrc_mixer);
14108 else
14109 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
14110 } else {
14111 spec->adc_nids = alc268_adc_nids;
14112 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 14113 add_mixer(spec, alc268_capture_mixer);
a361d84b 14114 }
85860c06
TI
14115 /* set default input source */
14116 for (i = 0; i < spec->num_adc_nids; i++)
14117 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
14118 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
14119 i < spec->num_mux_defs ?
14120 spec->input_mux[i].items[0].index :
85860c06 14121 spec->input_mux->items[0].index);
a361d84b 14122 }
2134ea4f
TI
14123
14124 spec->vmaster_nid = 0x02;
14125
a361d84b
KY
14126 codec->patch_ops = alc_patch_ops;
14127 if (board_config == ALC268_AUTO)
14128 spec->init_hook = alc268_auto_init;
ea1fb29a 14129
bf1b0225
KY
14130 alc_init_jacks(codec);
14131
a361d84b
KY
14132 return 0;
14133}
14134
f6a92248
KY
14135/*
14136 * ALC269 channel source setting (2 channel)
14137 */
14138#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14139
14140#define alc269_dac_nids alc260_dac_nids
14141
14142static hda_nid_t alc269_adc_nids[1] = {
14143 /* ADC1 */
f53281e6
KY
14144 0x08,
14145};
14146
e01bf509
TI
14147static hda_nid_t alc269_capsrc_nids[1] = {
14148 0x23,
14149};
14150
84898e87
KY
14151static hda_nid_t alc269vb_adc_nids[1] = {
14152 /* ADC1 */
14153 0x09,
14154};
14155
14156static hda_nid_t alc269vb_capsrc_nids[1] = {
14157 0x22,
14158};
14159
6694635d
TI
14160static hda_nid_t alc269_adc_candidates[] = {
14161 0x08, 0x09, 0x07,
14162};
e01bf509 14163
f6a92248
KY
14164#define alc269_modes alc260_modes
14165#define alc269_capture_source alc880_lg_lw_capture_source
14166
14167static struct snd_kcontrol_new alc269_base_mixer[] = {
14168 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14169 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14170 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14171 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14172 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14173 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14174 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f6a92248
KY
14175 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14176 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14177 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f6a92248
KY
14178 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14179 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14180 { } /* end */
14181};
14182
60db6b53
KY
14183static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14184 /* output mixer control */
14185 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14186 {
14187 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14188 .name = "Master Playback Switch",
5e26dfd0 14189 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
14190 .info = snd_hda_mixer_amp_switch_info,
14191 .get = snd_hda_mixer_amp_switch_get,
14192 .put = alc268_acer_master_sw_put,
14193 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14194 },
14195 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14196 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14197 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
60db6b53
KY
14198 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14199 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14200 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
60db6b53
KY
14201 { }
14202};
14203
64154835
TV
14204static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14205 /* output mixer control */
14206 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14207 {
14208 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14209 .name = "Master Playback Switch",
5e26dfd0 14210 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14211 .info = snd_hda_mixer_amp_switch_info,
14212 .get = snd_hda_mixer_amp_switch_get,
14213 .put = alc268_acer_master_sw_put,
14214 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14215 },
14216 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14217 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14218 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64154835
TV
14219 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14220 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14221 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
64154835
TV
14222 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14223 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
5f99f86a 14224 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
64154835
TV
14225 { }
14226};
14227
84898e87 14228static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14229 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14230 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14231 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14232 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14233 { } /* end */
14234};
14235
84898e87
KY
14236static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14237 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14238 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14239 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14240 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14241 { } /* end */
14242};
14243
fe3eb0a7
KY
14244static struct snd_kcontrol_new alc269_asus_mixer[] = {
14245 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14246 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14247 { } /* end */
14248};
14249
f53281e6 14250/* capture mixer elements */
84898e87
KY
14251static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14252 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14253 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a
DH
14254 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14255 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14256 { } /* end */
14257};
14258
14259static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14260 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14261 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a 14262 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
26f5df26
TI
14263 { } /* end */
14264};
14265
84898e87
KY
14266static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14267 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14268 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a
DH
14269 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14270 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14271 { } /* end */
14272};
14273
14274static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14275 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14276 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a 14277 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
84898e87
KY
14278 { } /* end */
14279};
14280
26f5df26 14281/* FSC amilo */
84898e87 14282#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14283
60db6b53
KY
14284static struct hda_verb alc269_quanta_fl1_verbs[] = {
14285 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14286 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14287 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14288 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14289 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14290 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14291 { }
14292};
f6a92248 14293
64154835
TV
14294static struct hda_verb alc269_lifebook_verbs[] = {
14295 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14296 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14297 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14298 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14299 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14300 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14301 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14302 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14303 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14304 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14305 { }
14306};
14307
60db6b53
KY
14308/* toggle speaker-output according to the hp-jack state */
14309static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14310{
14311 unsigned int present;
14312 unsigned char bits;
f6a92248 14313
864f92be 14314 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 14315 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 14316 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14317 HDA_AMP_MUTE, bits);
60db6b53 14318 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14319 HDA_AMP_MUTE, bits);
f6a92248 14320
60db6b53
KY
14321 snd_hda_codec_write(codec, 0x20, 0,
14322 AC_VERB_SET_COEF_INDEX, 0x0c);
14323 snd_hda_codec_write(codec, 0x20, 0,
14324 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 14325
60db6b53
KY
14326 snd_hda_codec_write(codec, 0x20, 0,
14327 AC_VERB_SET_COEF_INDEX, 0x0c);
14328 snd_hda_codec_write(codec, 0x20, 0,
14329 AC_VERB_SET_PROC_COEF, 0x480);
14330}
f6a92248 14331
64154835
TV
14332/* toggle speaker-output according to the hp-jacks state */
14333static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
14334{
14335 unsigned int present;
14336 unsigned char bits;
14337
14338 /* Check laptop headphone socket */
864f92be 14339 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
14340
14341 /* Check port replicator headphone socket */
864f92be 14342 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 14343
5dbd5ec6 14344 bits = present ? HDA_AMP_MUTE : 0;
64154835 14345 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14346 HDA_AMP_MUTE, bits);
64154835 14347 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14348 HDA_AMP_MUTE, bits);
64154835
TV
14349
14350 snd_hda_codec_write(codec, 0x20, 0,
14351 AC_VERB_SET_COEF_INDEX, 0x0c);
14352 snd_hda_codec_write(codec, 0x20, 0,
14353 AC_VERB_SET_PROC_COEF, 0x680);
14354
14355 snd_hda_codec_write(codec, 0x20, 0,
14356 AC_VERB_SET_COEF_INDEX, 0x0c);
14357 snd_hda_codec_write(codec, 0x20, 0,
14358 AC_VERB_SET_PROC_COEF, 0x480);
14359}
14360
64154835
TV
14361static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14362{
14363 unsigned int present_laptop;
14364 unsigned int present_dock;
14365
864f92be
WF
14366 present_laptop = snd_hda_jack_detect(codec, 0x18);
14367 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14368
14369 /* Laptop mic port overrides dock mic port, design decision */
14370 if (present_dock)
14371 snd_hda_codec_write(codec, 0x23, 0,
14372 AC_VERB_SET_CONNECT_SEL, 0x3);
14373 if (present_laptop)
14374 snd_hda_codec_write(codec, 0x23, 0,
14375 AC_VERB_SET_CONNECT_SEL, 0x0);
14376 if (!present_dock && !present_laptop)
14377 snd_hda_codec_write(codec, 0x23, 0,
14378 AC_VERB_SET_CONNECT_SEL, 0x1);
14379}
14380
60db6b53
KY
14381static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14382 unsigned int res)
14383{
4f5d1706
TI
14384 switch (res >> 26) {
14385 case ALC880_HP_EVENT:
60db6b53 14386 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14387 break;
14388 case ALC880_MIC_EVENT:
14389 alc_mic_automute(codec);
14390 break;
14391 }
60db6b53 14392}
f6a92248 14393
64154835
TV
14394static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14395 unsigned int res)
14396{
14397 if ((res >> 26) == ALC880_HP_EVENT)
14398 alc269_lifebook_speaker_automute(codec);
14399 if ((res >> 26) == ALC880_MIC_EVENT)
14400 alc269_lifebook_mic_autoswitch(codec);
14401}
14402
4f5d1706
TI
14403static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14404{
14405 struct alc_spec *spec = codec->spec;
20645d70
TI
14406 spec->autocfg.hp_pins[0] = 0x15;
14407 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14408 spec->ext_mic.pin = 0x18;
14409 spec->ext_mic.mux_idx = 0;
14410 spec->int_mic.pin = 0x19;
14411 spec->int_mic.mux_idx = 1;
14412 spec->auto_mic = 1;
14413}
14414
60db6b53
KY
14415static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14416{
14417 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14418 alc_mic_automute(codec);
60db6b53 14419}
f6a92248 14420
64154835
TV
14421static void alc269_lifebook_init_hook(struct hda_codec *codec)
14422{
14423 alc269_lifebook_speaker_automute(codec);
14424 alc269_lifebook_mic_autoswitch(codec);
14425}
14426
84898e87 14427static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14428 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14429 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14430 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14431 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14432 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14433 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14434 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14435 {}
14436};
14437
84898e87 14438static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14439 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14440 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14441 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14442 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14443 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14444 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14445 {}
14446};
14447
84898e87
KY
14448static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14449 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14450 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14451 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14452 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14453 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14454 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14455 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14456 {}
14457};
14458
14459static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14460 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14461 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14462 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14463 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14464 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14465 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14466 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14467 {}
14468};
14469
fe3eb0a7
KY
14470static struct hda_verb alc271_acer_dmic_verbs[] = {
14471 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14472 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14473 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14474 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14475 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14476 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14477 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14478 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14479 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14480 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14481 { }
14482};
14483
f53281e6
KY
14484/* toggle speaker-output according to the hp-jack state */
14485static void alc269_speaker_automute(struct hda_codec *codec)
14486{
ebb83eeb
KY
14487 struct alc_spec *spec = codec->spec;
14488 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 14489 unsigned int present;
60db6b53 14490 unsigned char bits;
f53281e6 14491
ebb83eeb 14492 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 14493 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 14494 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14495 HDA_AMP_MUTE, bits);
f53281e6 14496 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14497 HDA_AMP_MUTE, bits);
bf1b0225 14498 alc_report_jack(codec, nid);
f53281e6
KY
14499}
14500
f53281e6 14501/* unsolicited event for HP jack sensing */
84898e87 14502static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 14503 unsigned int res)
f53281e6 14504{
4f5d1706
TI
14505 switch (res >> 26) {
14506 case ALC880_HP_EVENT:
f53281e6 14507 alc269_speaker_automute(codec);
4f5d1706
TI
14508 break;
14509 case ALC880_MIC_EVENT:
14510 alc_mic_automute(codec);
14511 break;
14512 }
f53281e6
KY
14513}
14514
226b1ec8 14515static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14516{
4f5d1706 14517 struct alc_spec *spec = codec->spec;
20645d70
TI
14518 spec->autocfg.hp_pins[0] = 0x15;
14519 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14520 spec->ext_mic.pin = 0x18;
14521 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14522 spec->int_mic.pin = 0x19;
14523 spec->int_mic.mux_idx = 1;
4f5d1706 14524 spec->auto_mic = 1;
f53281e6
KY
14525}
14526
226b1ec8 14527static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14528{
14529 struct alc_spec *spec = codec->spec;
20645d70
TI
14530 spec->autocfg.hp_pins[0] = 0x15;
14531 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
14532 spec->ext_mic.pin = 0x18;
14533 spec->ext_mic.mux_idx = 0;
14534 spec->int_mic.pin = 0x12;
226b1ec8 14535 spec->int_mic.mux_idx = 5;
84898e87
KY
14536 spec->auto_mic = 1;
14537}
14538
226b1ec8 14539static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14540{
4f5d1706 14541 struct alc_spec *spec = codec->spec;
226b1ec8 14542 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14543 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14544 spec->ext_mic.pin = 0x18;
14545 spec->ext_mic.mux_idx = 0;
14546 spec->int_mic.pin = 0x19;
14547 spec->int_mic.mux_idx = 1;
14548 spec->auto_mic = 1;
f53281e6
KY
14549}
14550
226b1ec8
KY
14551static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14552{
14553 struct alc_spec *spec = codec->spec;
14554 spec->autocfg.hp_pins[0] = 0x21;
14555 spec->autocfg.speaker_pins[0] = 0x14;
14556 spec->ext_mic.pin = 0x18;
14557 spec->ext_mic.mux_idx = 0;
14558 spec->int_mic.pin = 0x12;
14559 spec->int_mic.mux_idx = 6;
14560 spec->auto_mic = 1;
14561}
14562
84898e87 14563static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
14564{
14565 alc269_speaker_automute(codec);
4f5d1706 14566 alc_mic_automute(codec);
f53281e6
KY
14567}
14568
60db6b53
KY
14569/*
14570 * generic initialization of ADC, input mixers and output mixers
14571 */
14572static struct hda_verb alc269_init_verbs[] = {
14573 /*
14574 * Unmute ADC0 and set the default input to mic-in
14575 */
84898e87 14576 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14577
14578 /*
84898e87 14579 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14580 */
14581 /* set vol=0 to output mixers */
14582 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14583 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14584
14585 /* set up input amps for analog loopback */
14586 /* Amp Indices: DAC = 0, mixer = 1 */
14587 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14588 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14589 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14590 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14591 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14592 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14593
14594 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14595 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14596 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14597 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14598 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14599 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14600 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14601
14602 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14603 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14604
84898e87
KY
14605 /* FIXME: use Mux-type input source selection */
14606 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14607 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14608 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14609
84898e87
KY
14610 /* set EAPD */
14611 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14612 { }
14613};
14614
14615static struct hda_verb alc269vb_init_verbs[] = {
14616 /*
14617 * Unmute ADC0 and set the default input to mic-in
14618 */
14619 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14620
14621 /*
14622 * Set up output mixers (0x02 - 0x03)
14623 */
14624 /* set vol=0 to output mixers */
14625 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14626 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14627
14628 /* set up input amps for analog loopback */
14629 /* Amp Indices: DAC = 0, mixer = 1 */
14630 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14631 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14632 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14633 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14634 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14635 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14636
14637 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14638 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14639 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14640 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14641 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14642 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14643 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14644
14645 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14646 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14647
14648 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14649 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14650 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14651 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14652
14653 /* set EAPD */
14654 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14655 { }
14656};
14657
9d0b71b1
TI
14658#define alc269_auto_create_multi_out_ctls \
14659 alc268_auto_create_multi_out_ctls
05f5f477
TI
14660#define alc269_auto_create_input_ctls \
14661 alc268_auto_create_input_ctls
f6a92248
KY
14662
14663#ifdef CONFIG_SND_HDA_POWER_SAVE
14664#define alc269_loopbacks alc880_loopbacks
14665#endif
14666
def319f9 14667/* pcm configuration: identical with ALC880 */
f6a92248
KY
14668#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14669#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14670#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14671#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14672
f03d3115
TI
14673static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14674 .substreams = 1,
14675 .channels_min = 2,
14676 .channels_max = 8,
14677 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14678 /* NID is set in alc_build_pcms */
14679 .ops = {
14680 .open = alc880_playback_pcm_open,
14681 .prepare = alc880_playback_pcm_prepare,
14682 .cleanup = alc880_playback_pcm_cleanup
14683 },
14684};
14685
14686static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14687 .substreams = 1,
14688 .channels_min = 2,
14689 .channels_max = 2,
14690 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14691 /* NID is set in alc_build_pcms */
14692};
14693
ad35879a
TI
14694#ifdef CONFIG_SND_HDA_POWER_SAVE
14695static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14696{
14697 switch (codec->subsystem_id) {
14698 case 0x103c1586:
14699 return 1;
14700 }
14701 return 0;
14702}
14703
14704static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14705{
14706 /* update mute-LED according to the speaker mute state */
14707 if (nid == 0x01 || nid == 0x14) {
14708 int pinval;
14709 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14710 HDA_AMP_MUTE)
14711 pinval = 0x24;
14712 else
14713 pinval = 0x20;
14714 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14715 snd_hda_codec_update_cache(codec, 0x19, 0,
14716 AC_VERB_SET_PIN_WIDGET_CONTROL,
14717 pinval);
ad35879a
TI
14718 }
14719 return alc_check_power_status(codec, nid);
14720}
14721#endif /* CONFIG_SND_HDA_POWER_SAVE */
14722
840b64c0
TI
14723static int alc275_setup_dual_adc(struct hda_codec *codec)
14724{
14725 struct alc_spec *spec = codec->spec;
14726
14727 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14728 return 0;
14729 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14730 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14731 if (spec->ext_mic.pin <= 0x12) {
14732 spec->private_adc_nids[0] = 0x08;
14733 spec->private_adc_nids[1] = 0x11;
14734 spec->private_capsrc_nids[0] = 0x23;
14735 spec->private_capsrc_nids[1] = 0x22;
14736 } else {
14737 spec->private_adc_nids[0] = 0x11;
14738 spec->private_adc_nids[1] = 0x08;
14739 spec->private_capsrc_nids[0] = 0x22;
14740 spec->private_capsrc_nids[1] = 0x23;
14741 }
14742 spec->adc_nids = spec->private_adc_nids;
14743 spec->capsrc_nids = spec->private_capsrc_nids;
14744 spec->num_adc_nids = 2;
14745 spec->dual_adc_switch = 1;
14746 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14747 spec->adc_nids[0], spec->adc_nids[1]);
14748 return 1;
14749 }
14750 return 0;
14751}
14752
d433a678
TI
14753/* different alc269-variants */
14754enum {
14755 ALC269_TYPE_NORMAL,
48c88e82 14756 ALC269_TYPE_ALC258,
d433a678 14757 ALC269_TYPE_ALC259,
48c88e82
KY
14758 ALC269_TYPE_ALC269VB,
14759 ALC269_TYPE_ALC270,
d433a678
TI
14760 ALC269_TYPE_ALC271X,
14761};
14762
f6a92248
KY
14763/*
14764 * BIOS auto configuration
14765 */
14766static int alc269_parse_auto_config(struct hda_codec *codec)
14767{
14768 struct alc_spec *spec = codec->spec;
cfb9fb55 14769 int err;
f6a92248
KY
14770 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14771
14772 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14773 alc269_ignore);
14774 if (err < 0)
14775 return err;
14776
14777 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14778 if (err < 0)
14779 return err;
f3550d1b
TI
14780 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14781 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14782 else
14783 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14784 0x22, 0);
f6a92248
KY
14785 if (err < 0)
14786 return err;
14787
14788 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14789
757899ac 14790 alc_auto_parse_digital(codec);
f6a92248 14791
603c4019 14792 if (spec->kctls.list)
d88897ea 14793 add_mixer(spec, spec->kctls.list);
f6a92248 14794
d433a678 14795 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
84898e87 14796 add_verb(spec, alc269vb_init_verbs);
6227cdce 14797 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14798 } else {
14799 add_verb(spec, alc269_init_verbs);
6227cdce 14800 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14801 }
14802
f6a92248 14803 spec->num_mux_defs = 1;
61b9b9b1 14804 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14805
14806 if (!alc275_setup_dual_adc(codec))
14807 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14808 sizeof(alc269_adc_candidates));
6694635d 14809
e01bf509 14810 /* set default input source */
840b64c0 14811 if (!spec->dual_adc_switch)
748cce43
TI
14812 select_or_unmute_capsrc(codec, spec->capsrc_nids[0],
14813 spec->input_mux->items[0].index);
f6a92248
KY
14814
14815 err = alc_auto_add_mic_boost(codec);
14816 if (err < 0)
14817 return err;
14818
7e0e44d4 14819 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14820 set_capture_mixer(codec);
f53281e6 14821
f6a92248
KY
14822 return 1;
14823}
14824
e9af4f36
TI
14825#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14826#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14827#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14828
14829
14830/* init callback for auto-configuration model -- overriding the default init */
14831static void alc269_auto_init(struct hda_codec *codec)
14832{
f6c7e546 14833 struct alc_spec *spec = codec->spec;
f6a92248
KY
14834 alc269_auto_init_multi_out(codec);
14835 alc269_auto_init_hp_out(codec);
14836 alc269_auto_init_analog_input(codec);
757899ac 14837 alc_auto_init_digital(codec);
f6c7e546 14838 if (spec->unsol_event)
7fb0d78f 14839 alc_inithook(codec);
f6a92248
KY
14840}
14841
0ec33d1f
TI
14842#ifdef SND_HDA_NEEDS_RESUME
14843static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14844{
14845 int val = alc_read_coef_idx(codec, 0x04);
14846 if (power_up)
14847 val |= 1 << 11;
14848 else
14849 val &= ~(1 << 11);
14850 alc_write_coef_idx(codec, 0x04, val);
14851}
14852
977ddd6b
KY
14853#ifdef CONFIG_SND_HDA_POWER_SAVE
14854static int alc269_suspend(struct hda_codec *codec, pm_message_t state)
14855{
14856 struct alc_spec *spec = codec->spec;
977ddd6b 14857
0ec33d1f
TI
14858 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14859 alc269_toggle_power_output(codec, 0);
977ddd6b 14860 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14861 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14862 msleep(150);
14863 }
14864
14865 alc_shutup(codec);
14866 if (spec && spec->power_hook)
14867 spec->power_hook(codec);
14868 return 0;
14869}
0ec33d1f
TI
14870#endif /* CONFIG_SND_HDA_POWER_SAVE */
14871
977ddd6b
KY
14872static int alc269_resume(struct hda_codec *codec)
14873{
977ddd6b 14874 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14875 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14876 msleep(150);
14877 }
14878
14879 codec->patch_ops.init(codec);
14880
14881 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14882 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14883 msleep(200);
14884 }
14885
0ec33d1f
TI
14886 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14887 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14888
14889 snd_hda_codec_resume_amp(codec);
14890 snd_hda_codec_resume_cache(codec);
9e5341b9 14891 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14892 return 0;
14893}
0ec33d1f 14894#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14895
1a99d4a4 14896static void alc269_fixup_hweq(struct hda_codec *codec,
b5bfbc67 14897 const struct alc_fixup *fix, int action)
1a99d4a4
KY
14898{
14899 int coef;
14900
58701120 14901 if (action != ALC_FIXUP_ACT_INIT)
9fb1ef25 14902 return;
1a99d4a4
KY
14903 coef = alc_read_coef_idx(codec, 0x1e);
14904 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14905}
14906
ff818c24
TI
14907enum {
14908 ALC269_FIXUP_SONY_VAIO,
74dc8909 14909 ALC275_FIXUP_SONY_VAIO_GPIO2,
145a902b 14910 ALC269_FIXUP_DELL_M101Z,
022c92be 14911 ALC269_FIXUP_SKU_IGNORE,
ac612407 14912 ALC269_FIXUP_ASUS_G73JW,
357f915e 14913 ALC269_FIXUP_LENOVO_EAPD,
1a99d4a4 14914 ALC275_FIXUP_SONY_HWEQ,
ff818c24
TI
14915};
14916
ff818c24
TI
14917static const struct alc_fixup alc269_fixups[] = {
14918 [ALC269_FIXUP_SONY_VAIO] = {
b5bfbc67
TI
14919 .type = ALC_FIXUP_VERBS,
14920 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
14921 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14922 {}
14923 }
ff818c24 14924 },
74dc8909 14925 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
b5bfbc67
TI
14926 .type = ALC_FIXUP_VERBS,
14927 .v.verbs = (const struct hda_verb[]) {
2785591a
KY
14928 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14929 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14930 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14931 { }
b5bfbc67
TI
14932 },
14933 .chained = true,
14934 .chain_id = ALC269_FIXUP_SONY_VAIO
2785591a 14935 },
145a902b 14936 [ALC269_FIXUP_DELL_M101Z] = {
b5bfbc67
TI
14937 .type = ALC_FIXUP_VERBS,
14938 .v.verbs = (const struct hda_verb[]) {
145a902b
DH
14939 /* Enables internal speaker */
14940 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14941 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14942 {}
14943 }
14944 },
022c92be 14945 [ALC269_FIXUP_SKU_IGNORE] = {
b5bfbc67
TI
14946 .type = ALC_FIXUP_SKU,
14947 .v.sku = ALC_FIXUP_SKU_IGNORE,
fe67b240 14948 },
ac612407 14949 [ALC269_FIXUP_ASUS_G73JW] = {
b5bfbc67
TI
14950 .type = ALC_FIXUP_PINS,
14951 .v.pins = (const struct alc_pincfg[]) {
ac612407
DH
14952 { 0x17, 0x99130111 }, /* subwoofer */
14953 { }
14954 }
14955 },
357f915e 14956 [ALC269_FIXUP_LENOVO_EAPD] = {
b5bfbc67
TI
14957 .type = ALC_FIXUP_VERBS,
14958 .v.verbs = (const struct hda_verb[]) {
357f915e
KY
14959 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14960 {}
14961 }
14962 },
1a99d4a4 14963 [ALC275_FIXUP_SONY_HWEQ] = {
b5bfbc67
TI
14964 .type = ALC_FIXUP_FUNC,
14965 .v.func = alc269_fixup_hweq,
14966 .chained = true,
14967 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
1a99d4a4 14968 }
ff818c24
TI
14969};
14970
14971static struct snd_pci_quirk alc269_fixup_tbl[] = {
74dc8909 14972 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
1a99d4a4
KY
14973 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14974 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7039c74c 14975 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14976 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
022c92be 14977 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
ded9f523
DH
14978 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14979 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14980 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14981 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
ac612407 14982 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
357f915e 14983 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
ff818c24
TI
14984 {}
14985};
14986
14987
f6a92248
KY
14988/*
14989 * configuration and preset
14990 */
ea734963 14991static const char * const alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14992 [ALC269_BASIC] = "basic",
2922c9af 14993 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14994 [ALC269_AMIC] = "laptop-amic",
14995 [ALC269_DMIC] = "laptop-dmic",
64154835 14996 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14997 [ALC269_LIFEBOOK] = "lifebook",
14998 [ALC269_AUTO] = "auto",
f6a92248
KY
14999};
15000
15001static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 15002 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 15003 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 15004 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
15005 ALC269_AMIC),
15006 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
15007 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
15008 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
15009 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
15010 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
15011 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
15012 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
15013 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
15014 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
c790ad31 15015 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
84898e87
KY
15016 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
15017 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
15018 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
15019 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
15020 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
15021 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
15022 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
15023 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
15024 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
15025 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
15026 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
15027 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
15028 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
15029 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
15030 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
15031 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
15032 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
15033 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
15034 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
15035 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
15036 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
15037 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
15038 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
15039 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
15040 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
15041 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 15042 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 15043 ALC269_DMIC),
60db6b53 15044 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
15045 ALC269_DMIC),
15046 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
15047 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 15048 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 15049 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
15050 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
15051 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
15052 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
15053 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
15054 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
15055 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
15056 {}
15057};
15058
15059static struct alc_config_preset alc269_presets[] = {
15060 [ALC269_BASIC] = {
f9e336f6 15061 .mixers = { alc269_base_mixer },
f6a92248
KY
15062 .init_verbs = { alc269_init_verbs },
15063 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15064 .dac_nids = alc269_dac_nids,
15065 .hp_nid = 0x03,
15066 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15067 .channel_mode = alc269_modes,
15068 .input_mux = &alc269_capture_source,
15069 },
60db6b53
KY
15070 [ALC269_QUANTA_FL1] = {
15071 .mixers = { alc269_quanta_fl1_mixer },
15072 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15073 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15074 .dac_nids = alc269_dac_nids,
15075 .hp_nid = 0x03,
15076 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15077 .channel_mode = alc269_modes,
15078 .input_mux = &alc269_capture_source,
15079 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 15080 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
15081 .init_hook = alc269_quanta_fl1_init_hook,
15082 },
84898e87
KY
15083 [ALC269_AMIC] = {
15084 .mixers = { alc269_laptop_mixer },
15085 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 15086 .init_verbs = { alc269_init_verbs,
84898e87 15087 alc269_laptop_amic_init_verbs },
f53281e6
KY
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_amic_setup,
15095 .init_hook = alc269_laptop_inithook,
f53281e6 15096 },
84898e87
KY
15097 [ALC269_DMIC] = {
15098 .mixers = { alc269_laptop_mixer },
15099 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 15100 .init_verbs = { alc269_init_verbs,
84898e87
KY
15101 alc269_laptop_dmic_init_verbs },
15102 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15103 .dac_nids = alc269_dac_nids,
15104 .hp_nid = 0x03,
15105 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15106 .channel_mode = alc269_modes,
15107 .unsol_event = alc269_laptop_unsol_event,
15108 .setup = alc269_laptop_dmic_setup,
15109 .init_hook = alc269_laptop_inithook,
15110 },
15111 [ALC269VB_AMIC] = {
15112 .mixers = { alc269vb_laptop_mixer },
15113 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15114 .init_verbs = { alc269vb_init_verbs,
15115 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
15116 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15117 .dac_nids = alc269_dac_nids,
15118 .hp_nid = 0x03,
15119 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15120 .channel_mode = alc269_modes,
84898e87 15121 .unsol_event = alc269_laptop_unsol_event,
226b1ec8 15122 .setup = alc269vb_laptop_amic_setup,
84898e87
KY
15123 .init_hook = alc269_laptop_inithook,
15124 },
15125 [ALC269VB_DMIC] = {
15126 .mixers = { alc269vb_laptop_mixer },
15127 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15128 .init_verbs = { alc269vb_init_verbs,
15129 alc269vb_laptop_dmic_init_verbs },
15130 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15131 .dac_nids = alc269_dac_nids,
15132 .hp_nid = 0x03,
15133 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15134 .channel_mode = alc269_modes,
15135 .unsol_event = alc269_laptop_unsol_event,
15136 .setup = alc269vb_laptop_dmic_setup,
15137 .init_hook = alc269_laptop_inithook,
f53281e6 15138 },
26f5df26 15139 [ALC269_FUJITSU] = {
45bdd1c1 15140 .mixers = { alc269_fujitsu_mixer },
84898e87 15141 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 15142 .init_verbs = { alc269_init_verbs,
84898e87 15143 alc269_laptop_dmic_init_verbs },
26f5df26
TI
15144 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15145 .dac_nids = alc269_dac_nids,
15146 .hp_nid = 0x03,
15147 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15148 .channel_mode = alc269_modes,
84898e87
KY
15149 .unsol_event = alc269_laptop_unsol_event,
15150 .setup = alc269_laptop_dmic_setup,
15151 .init_hook = alc269_laptop_inithook,
26f5df26 15152 },
64154835
TV
15153 [ALC269_LIFEBOOK] = {
15154 .mixers = { alc269_lifebook_mixer },
15155 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15156 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15157 .dac_nids = alc269_dac_nids,
15158 .hp_nid = 0x03,
15159 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15160 .channel_mode = alc269_modes,
15161 .input_mux = &alc269_capture_source,
15162 .unsol_event = alc269_lifebook_unsol_event,
15163 .init_hook = alc269_lifebook_init_hook,
15164 },
fe3eb0a7
KY
15165 [ALC271_ACER] = {
15166 .mixers = { alc269_asus_mixer },
15167 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15168 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15169 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15170 .dac_nids = alc269_dac_nids,
15171 .adc_nids = alc262_dmic_adc_nids,
15172 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15173 .capsrc_nids = alc262_dmic_capsrc_nids,
15174 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15175 .channel_mode = alc269_modes,
15176 .input_mux = &alc269_capture_source,
15177 .dig_out_nid = ALC880_DIGOUT_NID,
15178 .unsol_event = alc_sku_unsol_event,
15179 .setup = alc269vb_laptop_dmic_setup,
15180 .init_hook = alc_inithook,
15181 },
f6a92248
KY
15182};
15183
977ddd6b
KY
15184static int alc269_fill_coef(struct hda_codec *codec)
15185{
15186 int val;
15187
15188 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15189 alc_write_coef_idx(codec, 0xf, 0x960b);
15190 alc_write_coef_idx(codec, 0xe, 0x8817);
15191 }
15192
15193 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15194 alc_write_coef_idx(codec, 0xf, 0x960b);
15195 alc_write_coef_idx(codec, 0xe, 0x8814);
15196 }
15197
15198 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15199 val = alc_read_coef_idx(codec, 0x04);
15200 /* Power up output pin */
15201 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15202 }
15203
15204 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15205 val = alc_read_coef_idx(codec, 0xd);
15206 if ((val & 0x0c00) >> 10 != 0x1) {
15207 /* Capless ramp up clock control */
15208 alc_write_coef_idx(codec, 0xd, val | 1<<10);
15209 }
15210 val = alc_read_coef_idx(codec, 0x17);
15211 if ((val & 0x01c0) >> 6 != 0x4) {
15212 /* Class D power on reset */
15213 alc_write_coef_idx(codec, 0x17, val | 1<<7);
15214 }
15215 }
15216 return 0;
15217}
15218
f6a92248
KY
15219static int patch_alc269(struct hda_codec *codec)
15220{
15221 struct alc_spec *spec;
48c88e82 15222 int board_config, coef;
f6a92248
KY
15223 int err;
15224
15225 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15226 if (spec == NULL)
15227 return -ENOMEM;
15228
15229 codec->spec = spec;
15230
da00c244
KY
15231 alc_auto_parse_customize_define(codec);
15232
c793bec5
KY
15233 if (codec->vendor_id == 0x10ec0269) {
15234 coef = alc_read_coef_idx(codec, 0);
15235 if ((coef & 0x00f0) == 0x0010) {
15236 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15237 spec->cdefine.platform_type == 1) {
15238 alc_codec_rename(codec, "ALC271X");
15239 spec->codec_variant = ALC269_TYPE_ALC271X;
15240 } else if ((coef & 0xf000) == 0x1000) {
15241 spec->codec_variant = ALC269_TYPE_ALC270;
15242 } else if ((coef & 0xf000) == 0x2000) {
15243 alc_codec_rename(codec, "ALC259");
15244 spec->codec_variant = ALC269_TYPE_ALC259;
15245 } else if ((coef & 0xf000) == 0x3000) {
15246 alc_codec_rename(codec, "ALC258");
15247 spec->codec_variant = ALC269_TYPE_ALC258;
15248 } else {
15249 alc_codec_rename(codec, "ALC269VB");
15250 spec->codec_variant = ALC269_TYPE_ALC269VB;
15251 }
15252 } else
15253 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15254 alc269_fill_coef(codec);
15255 }
977ddd6b 15256
f6a92248
KY
15257 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15258 alc269_models,
15259 alc269_cfg_tbl);
15260
15261 if (board_config < 0) {
9a11f1aa
TI
15262 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15263 codec->chip_name);
f6a92248
KY
15264 board_config = ALC269_AUTO;
15265 }
15266
b5bfbc67
TI
15267 if (board_config == ALC269_AUTO) {
15268 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15269 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15270 }
ff818c24 15271
f6a92248
KY
15272 if (board_config == ALC269_AUTO) {
15273 /* automatic parse from the BIOS config */
15274 err = alc269_parse_auto_config(codec);
15275 if (err < 0) {
15276 alc_free(codec);
15277 return err;
15278 } else if (!err) {
15279 printk(KERN_INFO
15280 "hda_codec: Cannot set up configuration "
15281 "from BIOS. Using base mode...\n");
15282 board_config = ALC269_BASIC;
15283 }
15284 }
15285
dc1eae25 15286 if (has_cdefine_beep(codec)) {
8af2591d
TI
15287 err = snd_hda_attach_beep_device(codec, 0x1);
15288 if (err < 0) {
15289 alc_free(codec);
15290 return err;
15291 }
680cd536
KK
15292 }
15293
f6a92248 15294 if (board_config != ALC269_AUTO)
e9c364c0 15295 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15296
84898e87 15297 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15298 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15299 * fix the sample rate of analog I/O to 44.1kHz
15300 */
15301 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15302 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15303 } else if (spec->dual_adc_switch) {
15304 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15305 /* switch ADC dynamically */
15306 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15307 } else {
15308 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15309 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15310 }
f6a92248
KY
15311 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15312 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15313
6694635d 15314 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
1657cbd8 15315 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
6694635d
TI
15316 spec->adc_nids = alc269_adc_nids;
15317 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15318 spec->capsrc_nids = alc269_capsrc_nids;
15319 } else {
15320 spec->adc_nids = alc269vb_adc_nids;
15321 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15322 spec->capsrc_nids = alc269vb_capsrc_nids;
15323 }
84898e87
KY
15324 }
15325
f9e336f6 15326 if (!spec->cap_mixer)
b59bdf3b 15327 set_capture_mixer(codec);
dc1eae25 15328 if (has_cdefine_beep(codec))
da00c244 15329 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15330
b5bfbc67 15331 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
ff818c24 15332
100d5eb3
TI
15333 spec->vmaster_nid = 0x02;
15334
f6a92248 15335 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15336#ifdef CONFIG_SND_HDA_POWER_SAVE
15337 codec->patch_ops.suspend = alc269_suspend;
15338#endif
15339#ifdef SND_HDA_NEEDS_RESUME
15340 codec->patch_ops.resume = alc269_resume;
15341#endif
f6a92248
KY
15342 if (board_config == ALC269_AUTO)
15343 spec->init_hook = alc269_auto_init;
bf1b0225
KY
15344
15345 alc_init_jacks(codec);
f6a92248
KY
15346#ifdef CONFIG_SND_HDA_POWER_SAVE
15347 if (!spec->loopback.amplist)
15348 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15349 if (alc269_mic2_for_mute_led(codec))
15350 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15351#endif
15352
15353 return 0;
15354}
15355
df694daa
KY
15356/*
15357 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15358 */
15359
15360/*
15361 * set the path ways for 2 channel output
15362 * need to set the codec line out and mic 1 pin widgets to inputs
15363 */
15364static struct hda_verb alc861_threestack_ch2_init[] = {
15365 /* set pin widget 1Ah (line in) for input */
15366 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15367 /* set pin widget 18h (mic1/2) for input, for mic also enable
15368 * the vref
15369 */
df694daa
KY
15370 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15371
9c7f852e
TI
15372 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15373#if 0
15374 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15375 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15376#endif
df694daa
KY
15377 { } /* end */
15378};
15379/*
15380 * 6ch mode
15381 * need to set the codec line out and mic 1 pin widgets to outputs
15382 */
15383static struct hda_verb alc861_threestack_ch6_init[] = {
15384 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15385 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15386 /* set pin widget 18h (mic1) for output (CLFE)*/
15387 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15388
15389 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15390 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15391
9c7f852e
TI
15392 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15393#if 0
15394 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15395 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15396#endif
df694daa
KY
15397 { } /* end */
15398};
15399
15400static struct hda_channel_mode alc861_threestack_modes[2] = {
15401 { 2, alc861_threestack_ch2_init },
15402 { 6, alc861_threestack_ch6_init },
15403};
22309c3e
TI
15404/* Set mic1 as input and unmute the mixer */
15405static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15406 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15407 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15408 { } /* end */
15409};
15410/* Set mic1 as output and mute mixer */
15411static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15412 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15413 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15414 { } /* end */
15415};
15416
15417static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15418 { 2, alc861_uniwill_m31_ch2_init },
15419 { 4, alc861_uniwill_m31_ch4_init },
15420};
df694daa 15421
7cdbff94
MD
15422/* Set mic1 and line-in as input and unmute the mixer */
15423static struct hda_verb alc861_asus_ch2_init[] = {
15424 /* set pin widget 1Ah (line in) for input */
15425 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15426 /* set pin widget 18h (mic1/2) for input, for mic also enable
15427 * the vref
15428 */
7cdbff94
MD
15429 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15430
15431 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15432#if 0
15433 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15434 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15435#endif
15436 { } /* end */
15437};
15438/* Set mic1 nad line-in as output and mute mixer */
15439static struct hda_verb alc861_asus_ch6_init[] = {
15440 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15441 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15442 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15443 /* set pin widget 18h (mic1) for output (CLFE)*/
15444 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15445 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15446 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15447 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15448
15449 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15450#if 0
15451 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15452 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15453#endif
15454 { } /* end */
15455};
15456
15457static struct hda_channel_mode alc861_asus_modes[2] = {
15458 { 2, alc861_asus_ch2_init },
15459 { 6, alc861_asus_ch6_init },
15460};
15461
df694daa
KY
15462/* patch-ALC861 */
15463
15464static struct snd_kcontrol_new alc861_base_mixer[] = {
15465 /* output mixer control */
15466 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15467 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15468 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15469 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15470 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15471
15472 /*Input mixer control */
15473 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15474 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15475 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15476 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15477 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15478 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15479 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15480 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15481 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15482 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15483
df694daa
KY
15484 { } /* end */
15485};
15486
15487static struct snd_kcontrol_new alc861_3ST_mixer[] = {
15488 /* output mixer control */
15489 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15490 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15491 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15492 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15493 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15494
15495 /* Input mixer control */
15496 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15497 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15498 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15499 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15500 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15501 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15502 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15503 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15504 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15505 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15506
df694daa
KY
15507 {
15508 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15509 .name = "Channel Mode",
15510 .info = alc_ch_mode_info,
15511 .get = alc_ch_mode_get,
15512 .put = alc_ch_mode_put,
15513 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15514 },
15515 { } /* end */
a53d1aec
TD
15516};
15517
d1d985f0 15518static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15519 /* output mixer control */
15520 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15521 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15522 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15523
a53d1aec 15524 { } /* end */
f12ab1e0 15525};
a53d1aec 15526
22309c3e
TI
15527static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15528 /* output mixer control */
15529 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15530 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15531 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15532 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15533 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15534
15535 /* Input mixer control */
15536 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15537 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15538 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15539 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15540 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15541 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15542 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15543 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15544 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15545 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15546
22309c3e
TI
15547 {
15548 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15549 .name = "Channel Mode",
15550 .info = alc_ch_mode_info,
15551 .get = alc_ch_mode_get,
15552 .put = alc_ch_mode_put,
15553 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15554 },
15555 { } /* end */
f12ab1e0 15556};
7cdbff94
MD
15557
15558static struct snd_kcontrol_new alc861_asus_mixer[] = {
15559 /* output mixer control */
15560 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15561 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15562 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15563 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15564 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15565
15566 /* Input mixer control */
15567 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15568 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15569 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15570 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15571 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15572 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15573 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15574 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15575 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15576 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15577
7cdbff94
MD
15578 {
15579 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15580 .name = "Channel Mode",
15581 .info = alc_ch_mode_info,
15582 .get = alc_ch_mode_get,
15583 .put = alc_ch_mode_put,
15584 .private_value = ARRAY_SIZE(alc861_asus_modes),
15585 },
15586 { }
56bb0cab
TI
15587};
15588
15589/* additional mixer */
d1d985f0 15590static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15591 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15592 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15593 { }
15594};
7cdbff94 15595
df694daa
KY
15596/*
15597 * generic initialization of ADC, input mixers and output mixers
15598 */
15599static struct hda_verb alc861_base_init_verbs[] = {
15600 /*
15601 * Unmute ADC0 and set the default input to mic-in
15602 */
15603 /* port-A for surround (rear panel) */
15604 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15605 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15606 /* port-B for mic-in (rear panel) with vref */
15607 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15608 /* port-C for line-in (rear panel) */
15609 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15610 /* port-D for Front */
15611 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15612 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15613 /* port-E for HP out (front panel) */
15614 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15615 /* route front PCM to HP */
9dece1d7 15616 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15617 /* port-F for mic-in (front panel) with vref */
15618 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15619 /* port-G for CLFE (rear panel) */
15620 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15621 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15622 /* port-H for side (rear panel) */
15623 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15624 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15625 /* CD-in */
15626 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15627 /* route front mic to ADC1*/
15628 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15629 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15630
df694daa
KY
15631 /* Unmute DAC0~3 & spdif out*/
15632 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15633 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15634 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15635 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15636 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15637
df694daa
KY
15638 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15639 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15640 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15641 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15642 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15643
df694daa
KY
15644 /* Unmute Stereo Mixer 15 */
15645 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15646 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15647 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15648 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15649
15650 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15651 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15652 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15653 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15654 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15655 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15656 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15657 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15658 /* hp used DAC 3 (Front) */
15659 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15660 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15661
15662 { }
15663};
15664
15665static struct hda_verb alc861_threestack_init_verbs[] = {
15666 /*
15667 * Unmute ADC0 and set the default input to mic-in
15668 */
15669 /* port-A for surround (rear panel) */
15670 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15671 /* port-B for mic-in (rear panel) with vref */
15672 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15673 /* port-C for line-in (rear panel) */
15674 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15675 /* port-D for Front */
15676 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15677 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15678 /* port-E for HP out (front panel) */
15679 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15680 /* route front PCM to HP */
9dece1d7 15681 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15682 /* port-F for mic-in (front panel) with vref */
15683 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15684 /* port-G for CLFE (rear panel) */
15685 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15686 /* port-H for side (rear panel) */
15687 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15688 /* CD-in */
15689 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15690 /* route front mic to ADC1*/
15691 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15692 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15693 /* Unmute DAC0~3 & spdif out*/
15694 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15695 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15696 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15697 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15698 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15699
df694daa
KY
15700 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15701 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15702 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15703 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15704 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15705
df694daa
KY
15706 /* Unmute Stereo Mixer 15 */
15707 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15708 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15709 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15710 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15711
15712 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15713 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15714 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15715 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15716 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15717 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15718 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15719 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15720 /* hp used DAC 3 (Front) */
15721 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15722 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15723 { }
15724};
22309c3e
TI
15725
15726static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15727 /*
15728 * Unmute ADC0 and set the default input to mic-in
15729 */
15730 /* port-A for surround (rear panel) */
15731 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15732 /* port-B for mic-in (rear panel) with vref */
15733 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15734 /* port-C for line-in (rear panel) */
15735 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15736 /* port-D for Front */
15737 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15738 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15739 /* port-E for HP out (front panel) */
f12ab1e0
TI
15740 /* this has to be set to VREF80 */
15741 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15742 /* route front PCM to HP */
9dece1d7 15743 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15744 /* port-F for mic-in (front panel) with vref */
15745 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15746 /* port-G for CLFE (rear panel) */
15747 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15748 /* port-H for side (rear panel) */
15749 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15750 /* CD-in */
15751 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15752 /* route front mic to ADC1*/
15753 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15754 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15755 /* Unmute DAC0~3 & spdif out*/
15756 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15757 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15758 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15759 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15760 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15761
22309c3e
TI
15762 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15763 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15764 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15765 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15766 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15767
22309c3e
TI
15768 /* Unmute Stereo Mixer 15 */
15769 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15770 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15771 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15772 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15773
15774 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15775 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15776 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15777 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15778 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15779 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15780 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15781 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15782 /* hp used DAC 3 (Front) */
15783 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15784 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15785 { }
15786};
15787
7cdbff94
MD
15788static struct hda_verb alc861_asus_init_verbs[] = {
15789 /*
15790 * Unmute ADC0 and set the default input to mic-in
15791 */
f12ab1e0
TI
15792 /* port-A for surround (rear panel)
15793 * according to codec#0 this is the HP jack
15794 */
7cdbff94
MD
15795 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15796 /* route front PCM to HP */
15797 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15798 /* port-B for mic-in (rear panel) with vref */
15799 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15800 /* port-C for line-in (rear panel) */
15801 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15802 /* port-D for Front */
15803 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15804 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15805 /* port-E for HP out (front panel) */
f12ab1e0
TI
15806 /* this has to be set to VREF80 */
15807 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15808 /* route front PCM to HP */
9dece1d7 15809 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15810 /* port-F for mic-in (front panel) with vref */
15811 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15812 /* port-G for CLFE (rear panel) */
15813 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15814 /* port-H for side (rear panel) */
15815 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15816 /* CD-in */
15817 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15818 /* route front mic to ADC1*/
15819 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15820 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15821 /* Unmute DAC0~3 & spdif out*/
15822 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15823 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15824 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15825 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15826 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15827 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15828 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15829 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15830 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15831 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15832
7cdbff94
MD
15833 /* Unmute Stereo Mixer 15 */
15834 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15835 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15836 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15837 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15838
15839 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15840 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15841 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15842 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15843 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15844 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15845 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15846 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15847 /* hp used DAC 3 (Front) */
15848 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15849 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15850 { }
15851};
15852
56bb0cab
TI
15853/* additional init verbs for ASUS laptops */
15854static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15855 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15856 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15857 { }
15858};
7cdbff94 15859
df694daa
KY
15860/*
15861 * generic initialization of ADC, input mixers and output mixers
15862 */
15863static struct hda_verb alc861_auto_init_verbs[] = {
15864 /*
15865 * Unmute ADC0 and set the default input to mic-in
15866 */
f12ab1e0 15867 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15868 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15869
df694daa
KY
15870 /* Unmute DAC0~3 & spdif out*/
15871 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15872 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15873 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15874 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15875 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15876
df694daa
KY
15877 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15878 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15879 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15880 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15881 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15882
df694daa
KY
15883 /* Unmute Stereo Mixer 15 */
15884 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15885 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15886 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15887 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15888
1c20930a
TI
15889 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15890 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15891 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15892 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15893 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15894 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15895 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15896 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15897
15898 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15899 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15900 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15901 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15902 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15903 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15904 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15905 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15906
f12ab1e0 15907 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15908
15909 { }
15910};
15911
a53d1aec
TD
15912static struct hda_verb alc861_toshiba_init_verbs[] = {
15913 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15914
a53d1aec
TD
15915 { }
15916};
15917
15918/* toggle speaker-output according to the hp-jack state */
15919static void alc861_toshiba_automute(struct hda_codec *codec)
15920{
864f92be 15921 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15922
47fd830a
TI
15923 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15924 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15925 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15926 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15927}
15928
15929static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15930 unsigned int res)
15931{
a53d1aec
TD
15932 if ((res >> 26) == ALC880_HP_EVENT)
15933 alc861_toshiba_automute(codec);
15934}
15935
def319f9 15936/* pcm configuration: identical with ALC880 */
df694daa
KY
15937#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15938#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15939#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15940#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15941
15942
15943#define ALC861_DIGOUT_NID 0x07
15944
15945static struct hda_channel_mode alc861_8ch_modes[1] = {
15946 { 8, NULL }
15947};
15948
15949static hda_nid_t alc861_dac_nids[4] = {
15950 /* front, surround, clfe, side */
15951 0x03, 0x06, 0x05, 0x04
15952};
15953
9c7f852e
TI
15954static hda_nid_t alc660_dac_nids[3] = {
15955 /* front, clfe, surround */
15956 0x03, 0x05, 0x06
15957};
15958
df694daa
KY
15959static hda_nid_t alc861_adc_nids[1] = {
15960 /* ADC0-2 */
15961 0x08,
15962};
15963
15964static struct hda_input_mux alc861_capture_source = {
15965 .num_items = 5,
15966 .items = {
15967 { "Mic", 0x0 },
15968 { "Front Mic", 0x3 },
15969 { "Line", 0x1 },
15970 { "CD", 0x4 },
15971 { "Mixer", 0x5 },
15972 },
15973};
15974
1c20930a
TI
15975static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15976{
15977 struct alc_spec *spec = codec->spec;
15978 hda_nid_t mix, srcs[5];
15979 int i, j, num;
15980
15981 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15982 return 0;
15983 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15984 if (num < 0)
15985 return 0;
15986 for (i = 0; i < num; i++) {
15987 unsigned int type;
a22d543a 15988 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15989 if (type != AC_WID_AUD_OUT)
15990 continue;
15991 for (j = 0; j < spec->multiout.num_dacs; j++)
15992 if (spec->multiout.dac_nids[j] == srcs[i])
15993 break;
15994 if (j >= spec->multiout.num_dacs)
15995 return srcs[i];
15996 }
15997 return 0;
15998}
15999
df694daa 16000/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 16001static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 16002 const struct auto_pin_cfg *cfg)
df694daa 16003{
1c20930a 16004 struct alc_spec *spec = codec->spec;
df694daa 16005 int i;
1c20930a 16006 hda_nid_t nid, dac;
df694daa
KY
16007
16008 spec->multiout.dac_nids = spec->private_dac_nids;
16009 for (i = 0; i < cfg->line_outs; i++) {
16010 nid = cfg->line_out_pins[i];
1c20930a
TI
16011 dac = alc861_look_for_dac(codec, nid);
16012 if (!dac)
16013 continue;
16014 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 16015 }
df694daa
KY
16016 return 0;
16017}
16018
bcb2f0f5
TI
16019static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
16020 hda_nid_t nid, int idx, unsigned int chs)
1c20930a 16021{
bcb2f0f5 16022 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
1c20930a
TI
16023 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
16024}
16025
bcb2f0f5
TI
16026#define alc861_create_out_sw(codec, pfx, nid, chs) \
16027 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
16028
df694daa 16029/* add playback controls from the parsed DAC table */
1c20930a 16030static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
16031 const struct auto_pin_cfg *cfg)
16032{
1c20930a 16033 struct alc_spec *spec = codec->spec;
ea734963 16034 static const char * const chname[4] = {
f12ab1e0
TI
16035 "Front", "Surround", NULL /*CLFE*/, "Side"
16036 };
bcb2f0f5 16037 const char *pfx = alc_get_line_out_pfx(cfg, true);
df694daa 16038 hda_nid_t nid;
1c20930a
TI
16039 int i, err;
16040
df694daa
KY
16041 for (i = 0; i < cfg->line_outs; i++) {
16042 nid = spec->multiout.dac_nids[i];
f12ab1e0 16043 if (!nid)
df694daa 16044 continue;
bcb2f0f5 16045 if (!pfx && i == 2) {
df694daa 16046 /* Center/LFE */
1c20930a 16047 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 16048 if (err < 0)
df694daa 16049 return err;
1c20930a 16050 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 16051 if (err < 0)
df694daa
KY
16052 return err;
16053 } else {
bcb2f0f5
TI
16054 const char *name = pfx;
16055 if (!name)
16056 name = chname[i];
16057 err = __alc861_create_out_sw(codec, name, nid, i, 3);
f12ab1e0 16058 if (err < 0)
df694daa
KY
16059 return err;
16060 }
16061 }
16062 return 0;
16063}
16064
1c20930a 16065static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 16066{
1c20930a 16067 struct alc_spec *spec = codec->spec;
df694daa
KY
16068 int err;
16069 hda_nid_t nid;
16070
f12ab1e0 16071 if (!pin)
df694daa
KY
16072 return 0;
16073
16074 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
16075 nid = alc861_look_for_dac(codec, pin);
16076 if (nid) {
16077 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16078 if (err < 0)
16079 return err;
16080 spec->multiout.hp_nid = nid;
16081 }
df694daa
KY
16082 }
16083 return 0;
16084}
16085
16086/* create playback/capture controls for input pins */
05f5f477 16087static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 16088 const struct auto_pin_cfg *cfg)
df694daa 16089{
05f5f477 16090 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
16091}
16092
f12ab1e0
TI
16093static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16094 hda_nid_t nid,
1c20930a 16095 int pin_type, hda_nid_t dac)
df694daa 16096{
1c20930a
TI
16097 hda_nid_t mix, srcs[5];
16098 int i, num;
16099
564c5bea
JL
16100 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16101 pin_type);
1c20930a 16102 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 16103 AMP_OUT_UNMUTE);
1c20930a
TI
16104 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16105 return;
16106 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16107 if (num < 0)
16108 return;
16109 for (i = 0; i < num; i++) {
16110 unsigned int mute;
16111 if (srcs[i] == dac || srcs[i] == 0x15)
16112 mute = AMP_IN_UNMUTE(i);
16113 else
16114 mute = AMP_IN_MUTE(i);
16115 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16116 mute);
16117 }
df694daa
KY
16118}
16119
16120static void alc861_auto_init_multi_out(struct hda_codec *codec)
16121{
16122 struct alc_spec *spec = codec->spec;
16123 int i;
16124
16125 for (i = 0; i < spec->autocfg.line_outs; i++) {
16126 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16127 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 16128 if (nid)
baba8ee9 16129 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 16130 spec->multiout.dac_nids[i]);
df694daa
KY
16131 }
16132}
16133
16134static void alc861_auto_init_hp_out(struct hda_codec *codec)
16135{
16136 struct alc_spec *spec = codec->spec;
df694daa 16137
15870f05
TI
16138 if (spec->autocfg.hp_outs)
16139 alc861_auto_set_output_and_unmute(codec,
16140 spec->autocfg.hp_pins[0],
16141 PIN_HP,
1c20930a 16142 spec->multiout.hp_nid);
15870f05
TI
16143 if (spec->autocfg.speaker_outs)
16144 alc861_auto_set_output_and_unmute(codec,
16145 spec->autocfg.speaker_pins[0],
16146 PIN_OUT,
1c20930a 16147 spec->multiout.dac_nids[0]);
df694daa
KY
16148}
16149
16150static void alc861_auto_init_analog_input(struct hda_codec *codec)
16151{
16152 struct alc_spec *spec = codec->spec;
66ceeb6b 16153 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
16154 int i;
16155
66ceeb6b
TI
16156 for (i = 0; i < cfg->num_inputs; i++) {
16157 hda_nid_t nid = cfg->inputs[i].pin;
23f0c048 16158 if (nid >= 0x0c && nid <= 0x11)
30ea098f 16159 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
df694daa
KY
16160 }
16161}
16162
16163/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
16164/* return 1 if successful, 0 if the proper config is not found,
16165 * or a negative error code
16166 */
df694daa
KY
16167static int alc861_parse_auto_config(struct hda_codec *codec)
16168{
16169 struct alc_spec *spec = codec->spec;
16170 int err;
16171 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16172
f12ab1e0
TI
16173 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16174 alc861_ignore);
16175 if (err < 0)
df694daa 16176 return err;
f12ab1e0 16177 if (!spec->autocfg.line_outs)
df694daa
KY
16178 return 0; /* can't find valid BIOS pin config */
16179
1c20930a 16180 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
16181 if (err < 0)
16182 return err;
1c20930a 16183 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
16184 if (err < 0)
16185 return err;
1c20930a 16186 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
16187 if (err < 0)
16188 return err;
05f5f477 16189 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16190 if (err < 0)
df694daa
KY
16191 return err;
16192
16193 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16194
757899ac 16195 alc_auto_parse_digital(codec);
df694daa 16196
603c4019 16197 if (spec->kctls.list)
d88897ea 16198 add_mixer(spec, spec->kctls.list);
df694daa 16199
d88897ea 16200 add_verb(spec, alc861_auto_init_verbs);
df694daa 16201
a1e8d2da 16202 spec->num_mux_defs = 1;
61b9b9b1 16203 spec->input_mux = &spec->private_imux[0];
df694daa
KY
16204
16205 spec->adc_nids = alc861_adc_nids;
16206 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 16207 set_capture_mixer(codec);
df694daa 16208
6227cdce 16209 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 16210
df694daa
KY
16211 return 1;
16212}
16213
ae6b813a
TI
16214/* additional initialization for auto-configuration model */
16215static void alc861_auto_init(struct hda_codec *codec)
df694daa 16216{
f6c7e546 16217 struct alc_spec *spec = codec->spec;
df694daa
KY
16218 alc861_auto_init_multi_out(codec);
16219 alc861_auto_init_hp_out(codec);
16220 alc861_auto_init_analog_input(codec);
757899ac 16221 alc_auto_init_digital(codec);
f6c7e546 16222 if (spec->unsol_event)
7fb0d78f 16223 alc_inithook(codec);
df694daa
KY
16224}
16225
cb53c626
TI
16226#ifdef CONFIG_SND_HDA_POWER_SAVE
16227static struct hda_amp_list alc861_loopbacks[] = {
16228 { 0x15, HDA_INPUT, 0 },
16229 { 0x15, HDA_INPUT, 1 },
16230 { 0x15, HDA_INPUT, 2 },
16231 { 0x15, HDA_INPUT, 3 },
16232 { } /* end */
16233};
16234#endif
16235
df694daa
KY
16236
16237/*
16238 * configuration and preset
16239 */
ea734963 16240static const char * const alc861_models[ALC861_MODEL_LAST] = {
f5fcc13c
TI
16241 [ALC861_3ST] = "3stack",
16242 [ALC660_3ST] = "3stack-660",
16243 [ALC861_3ST_DIG] = "3stack-dig",
16244 [ALC861_6ST_DIG] = "6stack-dig",
16245 [ALC861_UNIWILL_M31] = "uniwill-m31",
16246 [ALC861_TOSHIBA] = "toshiba",
16247 [ALC861_ASUS] = "asus",
16248 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16249 [ALC861_AUTO] = "auto",
16250};
16251
16252static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 16253 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
16254 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16255 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16256 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 16257 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 16258 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16259 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16260 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16261 * Any other models that need this preset?
16262 */
16263 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16264 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16265 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16266 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16267 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16268 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16269 /* FIXME: the below seems conflict */
16270 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16271 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16272 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16273 {}
16274};
16275
16276static struct alc_config_preset alc861_presets[] = {
16277 [ALC861_3ST] = {
16278 .mixers = { alc861_3ST_mixer },
16279 .init_verbs = { alc861_threestack_init_verbs },
16280 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16281 .dac_nids = alc861_dac_nids,
16282 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16283 .channel_mode = alc861_threestack_modes,
4e195a7b 16284 .need_dac_fix = 1,
df694daa
KY
16285 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16286 .adc_nids = alc861_adc_nids,
16287 .input_mux = &alc861_capture_source,
16288 },
16289 [ALC861_3ST_DIG] = {
16290 .mixers = { alc861_base_mixer },
16291 .init_verbs = { alc861_threestack_init_verbs },
16292 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16293 .dac_nids = alc861_dac_nids,
16294 .dig_out_nid = ALC861_DIGOUT_NID,
16295 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16296 .channel_mode = alc861_threestack_modes,
4e195a7b 16297 .need_dac_fix = 1,
df694daa
KY
16298 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16299 .adc_nids = alc861_adc_nids,
16300 .input_mux = &alc861_capture_source,
16301 },
16302 [ALC861_6ST_DIG] = {
16303 .mixers = { alc861_base_mixer },
16304 .init_verbs = { alc861_base_init_verbs },
16305 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16306 .dac_nids = alc861_dac_nids,
16307 .dig_out_nid = ALC861_DIGOUT_NID,
16308 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16309 .channel_mode = alc861_8ch_modes,
16310 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16311 .adc_nids = alc861_adc_nids,
16312 .input_mux = &alc861_capture_source,
16313 },
9c7f852e
TI
16314 [ALC660_3ST] = {
16315 .mixers = { alc861_3ST_mixer },
16316 .init_verbs = { alc861_threestack_init_verbs },
16317 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16318 .dac_nids = alc660_dac_nids,
16319 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16320 .channel_mode = alc861_threestack_modes,
4e195a7b 16321 .need_dac_fix = 1,
9c7f852e
TI
16322 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16323 .adc_nids = alc861_adc_nids,
16324 .input_mux = &alc861_capture_source,
16325 },
22309c3e
TI
16326 [ALC861_UNIWILL_M31] = {
16327 .mixers = { alc861_uniwill_m31_mixer },
16328 .init_verbs = { alc861_uniwill_m31_init_verbs },
16329 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16330 .dac_nids = alc861_dac_nids,
16331 .dig_out_nid = ALC861_DIGOUT_NID,
16332 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16333 .channel_mode = alc861_uniwill_m31_modes,
16334 .need_dac_fix = 1,
16335 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16336 .adc_nids = alc861_adc_nids,
16337 .input_mux = &alc861_capture_source,
16338 },
a53d1aec
TD
16339 [ALC861_TOSHIBA] = {
16340 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16341 .init_verbs = { alc861_base_init_verbs,
16342 alc861_toshiba_init_verbs },
a53d1aec
TD
16343 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16344 .dac_nids = alc861_dac_nids,
16345 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16346 .channel_mode = alc883_3ST_2ch_modes,
16347 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16348 .adc_nids = alc861_adc_nids,
16349 .input_mux = &alc861_capture_source,
16350 .unsol_event = alc861_toshiba_unsol_event,
16351 .init_hook = alc861_toshiba_automute,
16352 },
7cdbff94
MD
16353 [ALC861_ASUS] = {
16354 .mixers = { alc861_asus_mixer },
16355 .init_verbs = { alc861_asus_init_verbs },
16356 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16357 .dac_nids = alc861_dac_nids,
16358 .dig_out_nid = ALC861_DIGOUT_NID,
16359 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16360 .channel_mode = alc861_asus_modes,
16361 .need_dac_fix = 1,
16362 .hp_nid = 0x06,
16363 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16364 .adc_nids = alc861_adc_nids,
16365 .input_mux = &alc861_capture_source,
16366 },
56bb0cab
TI
16367 [ALC861_ASUS_LAPTOP] = {
16368 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16369 .init_verbs = { alc861_asus_init_verbs,
16370 alc861_asus_laptop_init_verbs },
16371 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16372 .dac_nids = alc861_dac_nids,
16373 .dig_out_nid = ALC861_DIGOUT_NID,
16374 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16375 .channel_mode = alc883_3ST_2ch_modes,
16376 .need_dac_fix = 1,
16377 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16378 .adc_nids = alc861_adc_nids,
16379 .input_mux = &alc861_capture_source,
16380 },
16381};
df694daa 16382
cfc9b06f
TI
16383/* Pin config fixes */
16384enum {
16385 PINFIX_FSC_AMILO_PI1505,
16386};
16387
cfc9b06f
TI
16388static const struct alc_fixup alc861_fixups[] = {
16389 [PINFIX_FSC_AMILO_PI1505] = {
b5bfbc67
TI
16390 .type = ALC_FIXUP_PINS,
16391 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
16392 { 0x0b, 0x0221101f }, /* HP */
16393 { 0x0f, 0x90170310 }, /* speaker */
16394 { }
16395 }
cfc9b06f
TI
16396 },
16397};
16398
16399static struct snd_pci_quirk alc861_fixup_tbl[] = {
16400 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16401 {}
16402};
df694daa
KY
16403
16404static int patch_alc861(struct hda_codec *codec)
16405{
16406 struct alc_spec *spec;
16407 int board_config;
16408 int err;
16409
dc041e0b 16410 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16411 if (spec == NULL)
16412 return -ENOMEM;
16413
f12ab1e0 16414 codec->spec = spec;
df694daa 16415
f5fcc13c
TI
16416 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16417 alc861_models,
16418 alc861_cfg_tbl);
9c7f852e 16419
f5fcc13c 16420 if (board_config < 0) {
9a11f1aa
TI
16421 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16422 codec->chip_name);
df694daa
KY
16423 board_config = ALC861_AUTO;
16424 }
16425
b5bfbc67
TI
16426 if (board_config == ALC861_AUTO) {
16427 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16428 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16429 }
cfc9b06f 16430
df694daa
KY
16431 if (board_config == ALC861_AUTO) {
16432 /* automatic parse from the BIOS config */
16433 err = alc861_parse_auto_config(codec);
16434 if (err < 0) {
16435 alc_free(codec);
16436 return err;
f12ab1e0 16437 } else if (!err) {
9c7f852e
TI
16438 printk(KERN_INFO
16439 "hda_codec: Cannot set up configuration "
16440 "from BIOS. Using base mode...\n");
df694daa
KY
16441 board_config = ALC861_3ST_DIG;
16442 }
16443 }
16444
680cd536
KK
16445 err = snd_hda_attach_beep_device(codec, 0x23);
16446 if (err < 0) {
16447 alc_free(codec);
16448 return err;
16449 }
16450
df694daa 16451 if (board_config != ALC861_AUTO)
e9c364c0 16452 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16453
df694daa
KY
16454 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16455 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16456
df694daa
KY
16457 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16458 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16459
c7a8eb10
TI
16460 if (!spec->cap_mixer)
16461 set_capture_mixer(codec);
45bdd1c1
TI
16462 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16463
2134ea4f
TI
16464 spec->vmaster_nid = 0x03;
16465
b5bfbc67 16466 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 16467
df694daa 16468 codec->patch_ops = alc_patch_ops;
c97259df 16469 if (board_config == ALC861_AUTO) {
ae6b813a 16470 spec->init_hook = alc861_auto_init;
c97259df
DC
16471#ifdef CONFIG_SND_HDA_POWER_SAVE
16472 spec->power_hook = alc_power_eapd;
16473#endif
16474 }
cb53c626
TI
16475#ifdef CONFIG_SND_HDA_POWER_SAVE
16476 if (!spec->loopback.amplist)
16477 spec->loopback.amplist = alc861_loopbacks;
16478#endif
ea1fb29a 16479
1da177e4
LT
16480 return 0;
16481}
16482
f32610ed
JS
16483/*
16484 * ALC861-VD support
16485 *
16486 * Based on ALC882
16487 *
16488 * In addition, an independent DAC
16489 */
16490#define ALC861VD_DIGOUT_NID 0x06
16491
16492static hda_nid_t alc861vd_dac_nids[4] = {
16493 /* front, surr, clfe, side surr */
16494 0x02, 0x03, 0x04, 0x05
16495};
16496
16497/* dac_nids for ALC660vd are in a different order - according to
16498 * Realtek's driver.
def319f9 16499 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16500 * of ALC660vd codecs, but for now there is only 3stack mixer
16501 * - and it is the same as in 861vd.
16502 * adc_nids in ALC660vd are (is) the same as in 861vd
16503 */
16504static hda_nid_t alc660vd_dac_nids[3] = {
16505 /* front, rear, clfe, rear_surr */
16506 0x02, 0x04, 0x03
16507};
16508
16509static hda_nid_t alc861vd_adc_nids[1] = {
16510 /* ADC0 */
16511 0x09,
16512};
16513
e1406348
TI
16514static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16515
f32610ed
JS
16516/* input MUX */
16517/* FIXME: should be a matrix-type input source selection */
16518static struct hda_input_mux alc861vd_capture_source = {
16519 .num_items = 4,
16520 .items = {
16521 { "Mic", 0x0 },
16522 { "Front Mic", 0x1 },
16523 { "Line", 0x2 },
16524 { "CD", 0x4 },
16525 },
16526};
16527
272a527c 16528static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16529 .num_items = 2,
272a527c 16530 .items = {
8607f7c4 16531 { "Mic", 0x0 },
28c4edb7 16532 { "Internal Mic", 0x1 },
272a527c
KY
16533 },
16534};
16535
d1a991a6
KY
16536static struct hda_input_mux alc861vd_hp_capture_source = {
16537 .num_items = 2,
16538 .items = {
16539 { "Front Mic", 0x0 },
16540 { "ATAPI Mic", 0x1 },
16541 },
16542};
16543
f32610ed
JS
16544/*
16545 * 2ch mode
16546 */
16547static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16548 { 2, NULL }
16549};
16550
16551/*
16552 * 6ch mode
16553 */
16554static struct hda_verb alc861vd_6stack_ch6_init[] = {
16555 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16556 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16557 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16558 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16559 { } /* end */
16560};
16561
16562/*
16563 * 8ch mode
16564 */
16565static struct hda_verb alc861vd_6stack_ch8_init[] = {
16566 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16567 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16568 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16569 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16570 { } /* end */
16571};
16572
16573static struct hda_channel_mode alc861vd_6stack_modes[2] = {
16574 { 6, alc861vd_6stack_ch6_init },
16575 { 8, alc861vd_6stack_ch8_init },
16576};
16577
16578static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16579 {
16580 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16581 .name = "Channel Mode",
16582 .info = alc_ch_mode_info,
16583 .get = alc_ch_mode_get,
16584 .put = alc_ch_mode_put,
16585 },
16586 { } /* end */
16587};
16588
f32610ed
JS
16589/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16590 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16591 */
16592static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16593 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16594 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16595
16596 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16597 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16598
16599 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16600 HDA_OUTPUT),
16601 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16602 HDA_OUTPUT),
16603 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16604 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16605
16606 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16607 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16608
16609 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16610
5f99f86a 16611 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16612 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16613 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16614
5f99f86a 16615 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16616 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16617 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16618
16619 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16620 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16621
16622 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16623 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16624
f32610ed
JS
16625 { } /* end */
16626};
16627
16628static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16629 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16630 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16631
16632 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16633
5f99f86a 16634 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16635 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16636 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16637
5f99f86a 16638 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16639 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16640 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16641
16642 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16643 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16644
16645 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16646 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16647
f32610ed
JS
16648 { } /* end */
16649};
16650
bdd148a3
KY
16651static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16652 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16653 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16654 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16655
16656 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16657
5f99f86a 16658 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3
KY
16659 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16660 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16661
5f99f86a 16662 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
bdd148a3
KY
16663 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16664 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16665
16666 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16667 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16668
16669 { } /* end */
16670};
16671
b419f346 16672/* Pin assignment: Speaker=0x14, HP = 0x15,
8607f7c4 16673 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
16674 */
16675static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16676 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16677 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16678 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16679 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
5f99f86a 16680 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8607f7c4
DH
16681 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16682 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 16683 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
16684 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16685 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16686 { } /* end */
16687};
16688
d1a991a6
KY
16689/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16690 * Front Mic=0x18, ATAPI Mic = 0x19,
16691 */
16692static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16693 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16694 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16695 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16696 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16697 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16698 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16699 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16700 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16701
d1a991a6
KY
16702 { } /* end */
16703};
16704
f32610ed
JS
16705/*
16706 * generic initialization of ADC, input mixers and output mixers
16707 */
16708static struct hda_verb alc861vd_volume_init_verbs[] = {
16709 /*
16710 * Unmute ADC0 and set the default input to mic-in
16711 */
16712 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16713 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16714
16715 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16716 * the analog-loopback mixer widget
16717 */
16718 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16719 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16720 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16721 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16722 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16723 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16724
16725 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16726 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16727 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16728 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16729 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16730
16731 /*
16732 * Set up output mixers (0x02 - 0x05)
16733 */
16734 /* set vol=0 to output mixers */
16735 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16736 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16737 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16738 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16739
16740 /* set up input amps for analog loopback */
16741 /* Amp Indices: DAC = 0, mixer = 1 */
16742 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16743 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16744 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16745 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16746 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16747 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16748 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16749 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16750
16751 { }
16752};
16753
16754/*
16755 * 3-stack pin configuration:
16756 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16757 */
16758static struct hda_verb alc861vd_3stack_init_verbs[] = {
16759 /*
16760 * Set pin mode and muting
16761 */
16762 /* set front pin widgets 0x14 for output */
16763 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16764 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16765 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16766
16767 /* Mic (rear) pin: input vref at 80% */
16768 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16769 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16770 /* Front Mic pin: input vref at 80% */
16771 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16772 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16773 /* Line In pin: input */
16774 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16775 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16776 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16777 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16778 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16779 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16780 /* CD pin widget for input */
16781 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16782
16783 { }
16784};
16785
16786/*
16787 * 6-stack pin configuration:
16788 */
16789static struct hda_verb alc861vd_6stack_init_verbs[] = {
16790 /*
16791 * Set pin mode and muting
16792 */
16793 /* set front pin widgets 0x14 for output */
16794 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16795 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16796 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16797
16798 /* Rear Pin: output 1 (0x0d) */
16799 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16800 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16801 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16802 /* CLFE Pin: output 2 (0x0e) */
16803 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16804 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16805 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16806 /* Side Pin: output 3 (0x0f) */
16807 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16808 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16809 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16810
16811 /* Mic (rear) pin: input vref at 80% */
16812 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16813 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16814 /* Front Mic pin: input vref at 80% */
16815 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16816 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16817 /* Line In pin: input */
16818 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16819 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16820 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16821 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16822 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16823 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16824 /* CD pin widget for input */
16825 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16826
16827 { }
16828};
16829
bdd148a3
KY
16830static struct hda_verb alc861vd_eapd_verbs[] = {
16831 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16832 { }
16833};
16834
f9423e7a
KY
16835static struct hda_verb alc660vd_eapd_verbs[] = {
16836 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16837 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16838 { }
16839};
16840
bdd148a3
KY
16841static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16842 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16843 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16844 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16845 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16846 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16847 {}
16848};
16849
4f5d1706 16850static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16851{
a9fd4f3f 16852 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16853 spec->autocfg.hp_pins[0] = 0x1b;
16854 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
16855}
16856
16857static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16858{
a9fd4f3f 16859 alc_automute_amp(codec);
eeb43387 16860 alc88x_simple_mic_automute(codec);
bdd148a3
KY
16861}
16862
16863static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16864 unsigned int res)
16865{
16866 switch (res >> 26) {
bdd148a3 16867 case ALC880_MIC_EVENT:
eeb43387 16868 alc88x_simple_mic_automute(codec);
bdd148a3 16869 break;
a9fd4f3f
TI
16870 default:
16871 alc_automute_amp_unsol_event(codec, res);
16872 break;
bdd148a3
KY
16873 }
16874}
16875
272a527c
KY
16876static struct hda_verb alc861vd_dallas_verbs[] = {
16877 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16878 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16879 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16880 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16881
16882 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16883 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16884 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16885 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16886 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16887 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16888 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16889 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16890
272a527c
KY
16891 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16892 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16893 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16894 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16895 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16896 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16897 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16898 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16899
16900 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16901 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16902 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16903 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16904 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16905 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16906 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16907 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16908
16909 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16910 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16911 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16912 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16913
16914 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16915 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16916 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16917
16918 { } /* end */
16919};
16920
16921/* toggle speaker-output according to the hp-jack state */
4f5d1706 16922static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16923{
a9fd4f3f 16924 struct alc_spec *spec = codec->spec;
272a527c 16925
a9fd4f3f
TI
16926 spec->autocfg.hp_pins[0] = 0x15;
16927 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
16928}
16929
cb53c626
TI
16930#ifdef CONFIG_SND_HDA_POWER_SAVE
16931#define alc861vd_loopbacks alc880_loopbacks
16932#endif
16933
def319f9 16934/* pcm configuration: identical with ALC880 */
f32610ed
JS
16935#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16936#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16937#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16938#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16939
16940/*
16941 * configuration and preset
16942 */
ea734963 16943static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
f32610ed 16944 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16945 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16946 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16947 [ALC861VD_3ST] = "3stack",
16948 [ALC861VD_3ST_DIG] = "3stack-digout",
16949 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16950 [ALC861VD_LENOVO] = "lenovo",
272a527c 16951 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16952 [ALC861VD_HP] = "hp",
f32610ed
JS
16953 [ALC861VD_AUTO] = "auto",
16954};
16955
16956static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16957 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16958 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16959 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16960 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16961 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16962 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16963 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16964 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16965 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16966 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16967 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16968 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16969 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16970 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16971 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16972 {}
16973};
16974
16975static struct alc_config_preset alc861vd_presets[] = {
16976 [ALC660VD_3ST] = {
16977 .mixers = { alc861vd_3st_mixer },
16978 .init_verbs = { alc861vd_volume_init_verbs,
16979 alc861vd_3stack_init_verbs },
16980 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16981 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16982 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16983 .channel_mode = alc861vd_3stack_2ch_modes,
16984 .input_mux = &alc861vd_capture_source,
16985 },
6963f84c
MC
16986 [ALC660VD_3ST_DIG] = {
16987 .mixers = { alc861vd_3st_mixer },
16988 .init_verbs = { alc861vd_volume_init_verbs,
16989 alc861vd_3stack_init_verbs },
16990 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16991 .dac_nids = alc660vd_dac_nids,
16992 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16993 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16994 .channel_mode = alc861vd_3stack_2ch_modes,
16995 .input_mux = &alc861vd_capture_source,
16996 },
f32610ed
JS
16997 [ALC861VD_3ST] = {
16998 .mixers = { alc861vd_3st_mixer },
16999 .init_verbs = { alc861vd_volume_init_verbs,
17000 alc861vd_3stack_init_verbs },
17001 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17002 .dac_nids = alc861vd_dac_nids,
17003 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17004 .channel_mode = alc861vd_3stack_2ch_modes,
17005 .input_mux = &alc861vd_capture_source,
17006 },
17007 [ALC861VD_3ST_DIG] = {
17008 .mixers = { alc861vd_3st_mixer },
17009 .init_verbs = { alc861vd_volume_init_verbs,
17010 alc861vd_3stack_init_verbs },
17011 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17012 .dac_nids = alc861vd_dac_nids,
17013 .dig_out_nid = ALC861VD_DIGOUT_NID,
17014 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17015 .channel_mode = alc861vd_3stack_2ch_modes,
17016 .input_mux = &alc861vd_capture_source,
17017 },
17018 [ALC861VD_6ST_DIG] = {
17019 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
17020 .init_verbs = { alc861vd_volume_init_verbs,
17021 alc861vd_6stack_init_verbs },
17022 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17023 .dac_nids = alc861vd_dac_nids,
17024 .dig_out_nid = ALC861VD_DIGOUT_NID,
17025 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
17026 .channel_mode = alc861vd_6stack_modes,
17027 .input_mux = &alc861vd_capture_source,
17028 },
bdd148a3
KY
17029 [ALC861VD_LENOVO] = {
17030 .mixers = { alc861vd_lenovo_mixer },
17031 .init_verbs = { alc861vd_volume_init_verbs,
17032 alc861vd_3stack_init_verbs,
17033 alc861vd_eapd_verbs,
17034 alc861vd_lenovo_unsol_verbs },
17035 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17036 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
17037 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17038 .channel_mode = alc861vd_3stack_2ch_modes,
17039 .input_mux = &alc861vd_capture_source,
17040 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 17041 .setup = alc861vd_lenovo_setup,
a9fd4f3f 17042 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 17043 },
272a527c
KY
17044 [ALC861VD_DALLAS] = {
17045 .mixers = { alc861vd_dallas_mixer },
17046 .init_verbs = { alc861vd_dallas_verbs },
17047 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17048 .dac_nids = alc861vd_dac_nids,
272a527c
KY
17049 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17050 .channel_mode = alc861vd_3stack_2ch_modes,
17051 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 17052 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
17053 .setup = alc861vd_dallas_setup,
17054 .init_hook = alc_automute_amp,
d1a991a6
KY
17055 },
17056 [ALC861VD_HP] = {
17057 .mixers = { alc861vd_hp_mixer },
17058 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17059 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17060 .dac_nids = alc861vd_dac_nids,
d1a991a6 17061 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
17062 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17063 .channel_mode = alc861vd_3stack_2ch_modes,
17064 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 17065 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
17066 .setup = alc861vd_dallas_setup,
17067 .init_hook = alc_automute_amp,
ea1fb29a 17068 },
13c94744
TI
17069 [ALC660VD_ASUS_V1S] = {
17070 .mixers = { alc861vd_lenovo_mixer },
17071 .init_verbs = { alc861vd_volume_init_verbs,
17072 alc861vd_3stack_init_verbs,
17073 alc861vd_eapd_verbs,
17074 alc861vd_lenovo_unsol_verbs },
17075 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17076 .dac_nids = alc660vd_dac_nids,
17077 .dig_out_nid = ALC861VD_DIGOUT_NID,
17078 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17079 .channel_mode = alc861vd_3stack_2ch_modes,
17080 .input_mux = &alc861vd_capture_source,
17081 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 17082 .setup = alc861vd_lenovo_setup,
a9fd4f3f 17083 .init_hook = alc861vd_lenovo_init_hook,
13c94744 17084 },
f32610ed
JS
17085};
17086
17087/*
17088 * BIOS auto configuration
17089 */
05f5f477
TI
17090static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17091 const struct auto_pin_cfg *cfg)
17092{
7167594a 17093 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
05f5f477
TI
17094}
17095
17096
f32610ed
JS
17097static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17098 hda_nid_t nid, int pin_type, int dac_idx)
17099{
f6c7e546 17100 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
17101}
17102
17103static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17104{
17105 struct alc_spec *spec = codec->spec;
17106 int i;
17107
17108 for (i = 0; i <= HDA_SIDE; i++) {
17109 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 17110 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
17111 if (nid)
17112 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 17113 pin_type, i);
f32610ed
JS
17114 }
17115}
17116
17117
17118static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17119{
17120 struct alc_spec *spec = codec->spec;
17121 hda_nid_t pin;
17122
17123 pin = spec->autocfg.hp_pins[0];
def319f9 17124 if (pin) /* connect to front and use dac 0 */
f32610ed 17125 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
17126 pin = spec->autocfg.speaker_pins[0];
17127 if (pin)
17128 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
17129}
17130
f32610ed
JS
17131#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17132
17133static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17134{
17135 struct alc_spec *spec = codec->spec;
66ceeb6b 17136 struct auto_pin_cfg *cfg = &spec->autocfg;
f32610ed
JS
17137 int i;
17138
66ceeb6b
TI
17139 for (i = 0; i < cfg->num_inputs; i++) {
17140 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 17141 if (alc_is_input_pin(codec, nid)) {
30ea098f 17142 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
17143 if (nid != ALC861VD_PIN_CD_NID &&
17144 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
17145 snd_hda_codec_write(codec, nid, 0,
17146 AC_VERB_SET_AMP_GAIN_MUTE,
17147 AMP_OUT_MUTE);
17148 }
17149 }
17150}
17151
f511b01c
TI
17152#define alc861vd_auto_init_input_src alc882_auto_init_input_src
17153
f32610ed
JS
17154#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17155#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17156
17157/* add playback controls from the parsed DAC table */
569ed348 17158/* Based on ALC880 version. But ALC861VD has separate,
f32610ed
JS
17159 * different NIDs for mute/unmute switch and volume control */
17160static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17161 const struct auto_pin_cfg *cfg)
17162{
ea734963
TI
17163 static const char * const chname[4] = {
17164 "Front", "Surround", "CLFE", "Side"
17165 };
bcb2f0f5 17166 const char *pfx = alc_get_line_out_pfx(cfg, true);
f32610ed
JS
17167 hda_nid_t nid_v, nid_s;
17168 int i, err;
17169
17170 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 17171 if (!spec->multiout.dac_nids[i])
f32610ed
JS
17172 continue;
17173 nid_v = alc861vd_idx_to_mixer_vol(
17174 alc880_dac_to_idx(
17175 spec->multiout.dac_nids[i]));
17176 nid_s = alc861vd_idx_to_mixer_switch(
17177 alc880_dac_to_idx(
17178 spec->multiout.dac_nids[i]));
17179
bcb2f0f5 17180 if (!pfx && i == 2) {
f32610ed 17181 /* Center/LFE */
0afe5f89
TI
17182 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17183 "Center",
f12ab1e0
TI
17184 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17185 HDA_OUTPUT));
17186 if (err < 0)
f32610ed 17187 return err;
0afe5f89
TI
17188 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17189 "LFE",
f12ab1e0
TI
17190 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17191 HDA_OUTPUT));
17192 if (err < 0)
f32610ed 17193 return err;
0afe5f89
TI
17194 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17195 "Center",
f12ab1e0
TI
17196 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17197 HDA_INPUT));
17198 if (err < 0)
f32610ed 17199 return err;
0afe5f89
TI
17200 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17201 "LFE",
f12ab1e0
TI
17202 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17203 HDA_INPUT));
17204 if (err < 0)
f32610ed
JS
17205 return err;
17206 } else {
bcb2f0f5
TI
17207 const char *name = pfx;
17208 if (!name)
17209 name = chname[i];
17210 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17211 name, i,
f12ab1e0
TI
17212 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17213 HDA_OUTPUT));
17214 if (err < 0)
f32610ed 17215 return err;
bcb2f0f5
TI
17216 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17217 name, i,
bdd148a3 17218 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
17219 HDA_INPUT));
17220 if (err < 0)
f32610ed
JS
17221 return err;
17222 }
17223 }
17224 return 0;
17225}
17226
17227/* add playback controls for speaker and HP outputs */
17228/* Based on ALC880 version. But ALC861VD has separate,
17229 * different NIDs for mute/unmute switch and volume control */
17230static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17231 hda_nid_t pin, const char *pfx)
17232{
17233 hda_nid_t nid_v, nid_s;
17234 int err;
f32610ed 17235
f12ab1e0 17236 if (!pin)
f32610ed
JS
17237 return 0;
17238
17239 if (alc880_is_fixed_pin(pin)) {
17240 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17241 /* specify the DAC as the extra output */
f12ab1e0 17242 if (!spec->multiout.hp_nid)
f32610ed
JS
17243 spec->multiout.hp_nid = nid_v;
17244 else
17245 spec->multiout.extra_out_nid[0] = nid_v;
17246 /* control HP volume/switch on the output mixer amp */
17247 nid_v = alc861vd_idx_to_mixer_vol(
17248 alc880_fixed_pin_idx(pin));
17249 nid_s = alc861vd_idx_to_mixer_switch(
17250 alc880_fixed_pin_idx(pin));
17251
0afe5f89 17252 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17253 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17254 if (err < 0)
f32610ed 17255 return err;
0afe5f89 17256 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17257 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17258 if (err < 0)
f32610ed
JS
17259 return err;
17260 } else if (alc880_is_multi_pin(pin)) {
17261 /* set manual connection */
17262 /* we have only a switch on HP-out PIN */
0afe5f89 17263 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17264 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17265 if (err < 0)
f32610ed
JS
17266 return err;
17267 }
17268 return 0;
17269}
17270
17271/* parse the BIOS configuration and set up the alc_spec
17272 * return 1 if successful, 0 if the proper config is not found,
17273 * or a negative error code
17274 * Based on ALC880 version - had to change it to override
17275 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17276static int alc861vd_parse_auto_config(struct hda_codec *codec)
17277{
17278 struct alc_spec *spec = codec->spec;
17279 int err;
17280 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17281
f12ab1e0
TI
17282 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17283 alc861vd_ignore);
17284 if (err < 0)
f32610ed 17285 return err;
f12ab1e0 17286 if (!spec->autocfg.line_outs)
f32610ed
JS
17287 return 0; /* can't find valid BIOS pin config */
17288
f12ab1e0
TI
17289 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17290 if (err < 0)
17291 return err;
17292 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17293 if (err < 0)
17294 return err;
17295 err = alc861vd_auto_create_extra_out(spec,
17296 spec->autocfg.speaker_pins[0],
17297 "Speaker");
17298 if (err < 0)
17299 return err;
17300 err = alc861vd_auto_create_extra_out(spec,
17301 spec->autocfg.hp_pins[0],
17302 "Headphone");
17303 if (err < 0)
17304 return err;
05f5f477 17305 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17306 if (err < 0)
f32610ed
JS
17307 return err;
17308
17309 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17310
757899ac 17311 alc_auto_parse_digital(codec);
f32610ed 17312
603c4019 17313 if (spec->kctls.list)
d88897ea 17314 add_mixer(spec, spec->kctls.list);
f32610ed 17315
d88897ea 17316 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
17317
17318 spec->num_mux_defs = 1;
61b9b9b1 17319 spec->input_mux = &spec->private_imux[0];
f32610ed 17320
776e184e
TI
17321 err = alc_auto_add_mic_boost(codec);
17322 if (err < 0)
17323 return err;
17324
6227cdce 17325 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17326
f32610ed
JS
17327 return 1;
17328}
17329
17330/* additional initialization for auto-configuration model */
17331static void alc861vd_auto_init(struct hda_codec *codec)
17332{
f6c7e546 17333 struct alc_spec *spec = codec->spec;
f32610ed
JS
17334 alc861vd_auto_init_multi_out(codec);
17335 alc861vd_auto_init_hp_out(codec);
17336 alc861vd_auto_init_analog_input(codec);
f511b01c 17337 alc861vd_auto_init_input_src(codec);
757899ac 17338 alc_auto_init_digital(codec);
f6c7e546 17339 if (spec->unsol_event)
7fb0d78f 17340 alc_inithook(codec);
f32610ed
JS
17341}
17342
f8f25ba3
TI
17343enum {
17344 ALC660VD_FIX_ASUS_GPIO1
17345};
17346
17347/* reset GPIO1 */
f8f25ba3
TI
17348static const struct alc_fixup alc861vd_fixups[] = {
17349 [ALC660VD_FIX_ASUS_GPIO1] = {
b5bfbc67
TI
17350 .type = ALC_FIXUP_VERBS,
17351 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
17352 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17353 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17354 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17355 { }
17356 }
f8f25ba3
TI
17357 },
17358};
17359
17360static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17361 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17362 {}
17363};
17364
f32610ed
JS
17365static int patch_alc861vd(struct hda_codec *codec)
17366{
17367 struct alc_spec *spec;
17368 int err, board_config;
17369
17370 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17371 if (spec == NULL)
17372 return -ENOMEM;
17373
17374 codec->spec = spec;
17375
17376 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17377 alc861vd_models,
17378 alc861vd_cfg_tbl);
17379
17380 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17381 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17382 codec->chip_name);
f32610ed
JS
17383 board_config = ALC861VD_AUTO;
17384 }
17385
b5bfbc67
TI
17386 if (board_config == ALC861VD_AUTO) {
17387 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17388 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17389 }
f8f25ba3 17390
f32610ed
JS
17391 if (board_config == ALC861VD_AUTO) {
17392 /* automatic parse from the BIOS config */
17393 err = alc861vd_parse_auto_config(codec);
17394 if (err < 0) {
17395 alc_free(codec);
17396 return err;
f12ab1e0 17397 } else if (!err) {
f32610ed
JS
17398 printk(KERN_INFO
17399 "hda_codec: Cannot set up configuration "
17400 "from BIOS. Using base mode...\n");
17401 board_config = ALC861VD_3ST;
17402 }
17403 }
17404
680cd536
KK
17405 err = snd_hda_attach_beep_device(codec, 0x23);
17406 if (err < 0) {
17407 alc_free(codec);
17408 return err;
17409 }
17410
f32610ed 17411 if (board_config != ALC861VD_AUTO)
e9c364c0 17412 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17413
2f893286 17414 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17415 /* always turn on EAPD */
d88897ea 17416 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17417 }
17418
f32610ed
JS
17419 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17420 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17421
f32610ed
JS
17422 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17423 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17424
dd704698
TI
17425 if (!spec->adc_nids) {
17426 spec->adc_nids = alc861vd_adc_nids;
17427 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17428 }
17429 if (!spec->capsrc_nids)
17430 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17431
b59bdf3b 17432 set_capture_mixer(codec);
45bdd1c1 17433 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17434
2134ea4f
TI
17435 spec->vmaster_nid = 0x02;
17436
b5bfbc67 17437 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 17438
f32610ed
JS
17439 codec->patch_ops = alc_patch_ops;
17440
17441 if (board_config == ALC861VD_AUTO)
17442 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
17443#ifdef CONFIG_SND_HDA_POWER_SAVE
17444 if (!spec->loopback.amplist)
17445 spec->loopback.amplist = alc861vd_loopbacks;
17446#endif
f32610ed
JS
17447
17448 return 0;
17449}
17450
bc9f98a9
KY
17451/*
17452 * ALC662 support
17453 *
17454 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17455 * configuration. Each pin widget can choose any input DACs and a mixer.
17456 * Each ADC is connected from a mixer of all inputs. This makes possible
17457 * 6-channel independent captures.
17458 *
17459 * In addition, an independent DAC for the multi-playback (not used in this
17460 * driver yet).
17461 */
17462#define ALC662_DIGOUT_NID 0x06
17463#define ALC662_DIGIN_NID 0x0a
17464
17465static hda_nid_t alc662_dac_nids[4] = {
17466 /* front, rear, clfe, rear_surr */
17467 0x02, 0x03, 0x04
17468};
17469
622e84cd
KY
17470static hda_nid_t alc272_dac_nids[2] = {
17471 0x02, 0x03
17472};
17473
b59bdf3b 17474static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17475 /* ADC1-2 */
b59bdf3b 17476 0x09, 0x08
bc9f98a9 17477};
e1406348 17478
622e84cd
KY
17479static hda_nid_t alc272_adc_nids[1] = {
17480 /* ADC1-2 */
17481 0x08,
17482};
17483
b59bdf3b 17484static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
17485static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17486
e1406348 17487
bc9f98a9
KY
17488/* input MUX */
17489/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
17490static struct hda_input_mux alc662_capture_source = {
17491 .num_items = 4,
17492 .items = {
17493 { "Mic", 0x0 },
17494 { "Front Mic", 0x1 },
17495 { "Line", 0x2 },
17496 { "CD", 0x4 },
17497 },
17498};
17499
17500static struct hda_input_mux alc662_lenovo_101e_capture_source = {
17501 .num_items = 2,
17502 .items = {
17503 { "Mic", 0x1 },
17504 { "Line", 0x2 },
17505 },
17506};
291702f0 17507
6dda9f4a
KY
17508static struct hda_input_mux alc663_capture_source = {
17509 .num_items = 3,
17510 .items = {
17511 { "Mic", 0x0 },
17512 { "Front Mic", 0x1 },
17513 { "Line", 0x2 },
17514 },
17515};
17516
4f5d1706 17517#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
17518static struct hda_input_mux alc272_nc10_capture_source = {
17519 .num_items = 16,
17520 .items = {
17521 { "Autoselect Mic", 0x0 },
17522 { "Internal Mic", 0x1 },
17523 { "In-0x02", 0x2 },
17524 { "In-0x03", 0x3 },
17525 { "In-0x04", 0x4 },
17526 { "In-0x05", 0x5 },
17527 { "In-0x06", 0x6 },
17528 { "In-0x07", 0x7 },
17529 { "In-0x08", 0x8 },
17530 { "In-0x09", 0x9 },
17531 { "In-0x0a", 0x0a },
17532 { "In-0x0b", 0x0b },
17533 { "In-0x0c", 0x0c },
17534 { "In-0x0d", 0x0d },
17535 { "In-0x0e", 0x0e },
17536 { "In-0x0f", 0x0f },
17537 },
17538};
17539#endif
17540
bc9f98a9
KY
17541/*
17542 * 2ch mode
17543 */
17544static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17545 { 2, NULL }
17546};
17547
17548/*
17549 * 2ch mode
17550 */
17551static struct hda_verb alc662_3ST_ch2_init[] = {
17552 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17553 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17554 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17555 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17556 { } /* end */
17557};
17558
17559/*
17560 * 6ch mode
17561 */
17562static struct hda_verb alc662_3ST_ch6_init[] = {
17563 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17564 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17565 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17566 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17567 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17568 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17569 { } /* end */
17570};
17571
17572static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17573 { 2, alc662_3ST_ch2_init },
17574 { 6, alc662_3ST_ch6_init },
17575};
17576
17577/*
17578 * 2ch mode
17579 */
17580static struct hda_verb alc662_sixstack_ch6_init[] = {
17581 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17582 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17583 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17584 { } /* end */
17585};
17586
17587/*
17588 * 6ch mode
17589 */
17590static struct hda_verb alc662_sixstack_ch8_init[] = {
17591 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17592 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17593 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17594 { } /* end */
17595};
17596
17597static struct hda_channel_mode alc662_5stack_modes[2] = {
17598 { 2, alc662_sixstack_ch6_init },
17599 { 6, alc662_sixstack_ch8_init },
17600};
17601
17602/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17603 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17604 */
17605
17606static struct snd_kcontrol_new alc662_base_mixer[] = {
17607 /* output mixer control */
17608 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17609 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17610 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17611 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17612 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17613 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17614 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17615 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17616 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17617
17618 /*Input mixer control */
17619 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17620 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17621 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17622 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17623 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17624 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17625 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17626 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17627 { } /* end */
17628};
17629
17630static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17631 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17632 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17633 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17634 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17635 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17636 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17637 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17638 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17639 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17640 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17641 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17642 { } /* end */
17643};
17644
17645static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17646 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17647 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17648 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17649 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17650 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17651 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17652 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17653 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17654 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17655 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17656 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17657 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17658 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17659 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17660 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17661 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17662 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17663 { } /* end */
17664};
17665
17666static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17667 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17668 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17669 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17670 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17671 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17672 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17673 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17674 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17675 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17676 { } /* end */
17677};
17678
291702f0 17679static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17680 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17681 ALC262_HIPPO_MASTER_SWITCH,
291702f0 17682
5f99f86a 17683 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17684 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17685 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
291702f0 17686
5f99f86a 17687 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17688 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17689 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
291702f0
KY
17690 { } /* end */
17691};
17692
8c427226 17693static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17694 ALC262_HIPPO_MASTER_SWITCH,
17695 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17696 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17697 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17698 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17699 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17700 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17701 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17702 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17703 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17704 { } /* end */
17705};
17706
f1d4e28b
KY
17707static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17708 .ops = &snd_hda_bind_vol,
17709 .values = {
17710 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17711 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17712 0
17713 },
17714};
17715
17716static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17717 .ops = &snd_hda_bind_sw,
17718 .values = {
17719 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17720 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17721 0
17722 },
17723};
17724
6dda9f4a 17725static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17726 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17727 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17728 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17729 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17730 { } /* end */
17731};
17732
17733static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17734 .ops = &snd_hda_bind_sw,
17735 .values = {
17736 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17737 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17738 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17739 0
17740 },
17741};
17742
17743static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17744 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17745 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17746 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17747 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17748 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17749 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17750
17751 { } /* end */
17752};
17753
17754static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17755 .ops = &snd_hda_bind_sw,
17756 .values = {
17757 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17758 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17759 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17760 0
17761 },
17762};
17763
17764static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17765 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17766 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17767 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17768 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17769 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17770 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17771 { } /* end */
17772};
17773
17774static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17775 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17776 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17777 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17778 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17779 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17780 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17781 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17782 { } /* end */
17783};
17784
17785static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17786 .ops = &snd_hda_bind_vol,
17787 .values = {
17788 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17789 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17790 0
17791 },
17792};
17793
17794static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17795 .ops = &snd_hda_bind_sw,
17796 .values = {
17797 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17798 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17799 0
17800 },
17801};
17802
17803static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17804 HDA_BIND_VOL("Master Playback Volume",
17805 &alc663_asus_two_bind_master_vol),
17806 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17807 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17808 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17809 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17810 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17811 { } /* end */
17812};
17813
17814static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17815 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17816 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17817 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17818 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17819 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17820 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17821 { } /* end */
17822};
17823
17824static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17825 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17826 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17827 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17828 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17829 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17830
17831 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17832 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17833 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17834 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17835 { } /* end */
17836};
17837
17838static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17839 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17840 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17841 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17842
17843 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17844 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17845 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17846 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17847 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17848 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17849 { } /* end */
17850};
17851
ebb83eeb
KY
17852static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17853 .ops = &snd_hda_bind_sw,
17854 .values = {
17855 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17856 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17857 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17858 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17859 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17860 0
17861 },
17862};
17863
17864static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17865 .ops = &snd_hda_bind_sw,
17866 .values = {
17867 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17868 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17869 0
17870 },
17871};
17872
17873static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17874 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17875 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17876 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17877 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17878 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17879 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17880 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17881 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17882 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17883 { } /* end */
17884};
17885
17886static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17887 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17888 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17889 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17890 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17891 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17892 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17893 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17894 { } /* end */
17895};
17896
17897
bc9f98a9
KY
17898static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17899 {
17900 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17901 .name = "Channel Mode",
17902 .info = alc_ch_mode_info,
17903 .get = alc_ch_mode_get,
17904 .put = alc_ch_mode_put,
17905 },
17906 { } /* end */
17907};
17908
17909static struct hda_verb alc662_init_verbs[] = {
17910 /* ADC: mute amp left and right */
17911 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17912 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17913
b60dd394
KY
17914 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17915 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17916 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17917 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17918 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17919 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17920
17921 /* Front Pin: output 0 (0x0c) */
17922 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17923 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17924
17925 /* Rear Pin: output 1 (0x0d) */
17926 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17927 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17928
17929 /* CLFE Pin: output 2 (0x0e) */
17930 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17931 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17932
17933 /* Mic (rear) pin: input vref at 80% */
17934 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17935 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17936 /* Front Mic pin: input vref at 80% */
17937 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17938 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17939 /* Line In pin: input */
17940 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17941 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17942 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17943 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17944 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17945 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17946 /* CD pin widget for input */
17947 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17948
17949 /* FIXME: use matrix-type input source selection */
17950 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17951 /* Input mixer */
17952 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17953 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
17954
17955 /* always trun on EAPD */
17956 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17957 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17958
bc9f98a9
KY
17959 { }
17960};
17961
cec27c89
KY
17962static struct hda_verb alc663_init_verbs[] = {
17963 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17964 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17965 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17966 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17967 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17968 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17969 { }
17970};
17971
17972static struct hda_verb alc272_init_verbs[] = {
17973 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17974 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17975 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17976 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17977 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17978 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17979 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17980 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17981 { }
17982};
17983
bc9f98a9
KY
17984static struct hda_verb alc662_sue_init_verbs[] = {
17985 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17986 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17987 {}
17988};
17989
17990static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17991 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17992 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17993 {}
bc9f98a9
KY
17994};
17995
8c427226
KY
17996/* Set Unsolicited Event*/
17997static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17998 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17999 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18000 {}
18001};
18002
6dda9f4a 18003static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
18004 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18005 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
18006 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18007 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
18008 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18009 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18010 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18011 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18012 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18013 {}
18014};
18015
18016static struct hda_verb alc663_21jd_amic_init_verbs[] = {
18017 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18018 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18019 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18020 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18021 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18022 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18023 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18024 {}
18025};
18026
18027static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
18028 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18029 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18030 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18031 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18032 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18033 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18034 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18035 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18036 {}
18037};
6dda9f4a 18038
f1d4e28b
KY
18039static struct hda_verb alc663_15jd_amic_init_verbs[] = {
18040 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18041 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18042 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18043 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18044 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18045 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18046 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18047 {}
18048};
6dda9f4a 18049
f1d4e28b
KY
18050static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
18051 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18052 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18053 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18054 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18055 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18056 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18057 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18058 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18059 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
18060 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18061 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
18062 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18063 {}
18064};
18065
18066static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
18067 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18068 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18069 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18070 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18071 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18072 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18073 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18074 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18075 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18076 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18077 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18078 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
18079 {}
18080};
18081
18082static struct hda_verb alc663_g71v_init_verbs[] = {
18083 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18084 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18085 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18086
18087 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18088 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18089 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18090
18091 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18092 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18093 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18094 {}
18095};
18096
18097static struct hda_verb alc663_g50v_init_verbs[] = {
18098 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18099 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18100 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18101
18102 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18103 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18104 {}
18105};
18106
f1d4e28b
KY
18107static struct hda_verb alc662_ecs_init_verbs[] = {
18108 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18109 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18110 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18111 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18112 {}
18113};
18114
622e84cd
KY
18115static struct hda_verb alc272_dell_zm1_init_verbs[] = {
18116 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18117 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18118 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18119 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18120 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18121 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18122 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18123 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18124 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18125 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18126 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18127 {}
18128};
18129
18130static struct hda_verb alc272_dell_init_verbs[] = {
18131 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18132 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18133 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18134 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18135 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18136 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18137 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18138 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18139 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18140 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18141 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18142 {}
18143};
18144
ebb83eeb
KY
18145static struct hda_verb alc663_mode7_init_verbs[] = {
18146 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18147 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18148 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18149 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18150 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18151 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18152 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18153 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18154 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18155 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18156 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18157 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18158 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18159 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18160 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18161 {}
18162};
18163
18164static struct hda_verb alc663_mode8_init_verbs[] = {
18165 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18166 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18167 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18168 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18169 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18170 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18171 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18172 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18173 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18174 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18175 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18176 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18177 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18178 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18179 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18180 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18181 {}
18182};
18183
f1d4e28b
KY
18184static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18185 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18186 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18187 { } /* end */
18188};
18189
622e84cd
KY
18190static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18191 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18192 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18193 { } /* end */
18194};
18195
bc9f98a9
KY
18196static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
18197{
18198 unsigned int present;
f12ab1e0 18199 unsigned char bits;
bc9f98a9 18200
864f92be 18201 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 18202 bits = present ? HDA_AMP_MUTE : 0;
864f92be 18203
47fd830a
TI
18204 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18205 HDA_AMP_MUTE, bits);
bc9f98a9
KY
18206}
18207
18208static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
18209{
18210 unsigned int present;
f12ab1e0 18211 unsigned char bits;
bc9f98a9 18212
864f92be 18213 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 18214 bits = present ? HDA_AMP_MUTE : 0;
864f92be 18215
47fd830a
TI
18216 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18217 HDA_AMP_MUTE, bits);
18218 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18219 HDA_AMP_MUTE, bits);
bc9f98a9
KY
18220}
18221
18222static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
18223 unsigned int res)
18224{
18225 if ((res >> 26) == ALC880_HP_EVENT)
18226 alc662_lenovo_101e_all_automute(codec);
18227 if ((res >> 26) == ALC880_FRONT_EVENT)
18228 alc662_lenovo_101e_ispeaker_automute(codec);
18229}
18230
291702f0
KY
18231/* unsolicited event for HP jack sensing */
18232static void alc662_eeepc_unsol_event(struct hda_codec *codec,
18233 unsigned int res)
18234{
291702f0 18235 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 18236 alc_mic_automute(codec);
42171c17
TI
18237 else
18238 alc262_hippo_unsol_event(codec, res);
291702f0
KY
18239}
18240
4f5d1706
TI
18241static void alc662_eeepc_setup(struct hda_codec *codec)
18242{
18243 struct alc_spec *spec = codec->spec;
18244
18245 alc262_hippo1_setup(codec);
18246 spec->ext_mic.pin = 0x18;
18247 spec->ext_mic.mux_idx = 0;
18248 spec->int_mic.pin = 0x19;
18249 spec->int_mic.mux_idx = 1;
18250 spec->auto_mic = 1;
18251}
18252
291702f0
KY
18253static void alc662_eeepc_inithook(struct hda_codec *codec)
18254{
4f5d1706
TI
18255 alc262_hippo_automute(codec);
18256 alc_mic_automute(codec);
291702f0
KY
18257}
18258
4f5d1706 18259static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18260{
42171c17
TI
18261 struct alc_spec *spec = codec->spec;
18262
18263 spec->autocfg.hp_pins[0] = 0x14;
18264 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
18265}
18266
4f5d1706
TI
18267#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
18268
6dda9f4a
KY
18269static void alc663_m51va_speaker_automute(struct hda_codec *codec)
18270{
18271 unsigned int present;
18272 unsigned char bits;
18273
864f92be 18274 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 18275 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 18276 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18277 HDA_AMP_MUTE, bits);
f1d4e28b 18278 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18279 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18280}
18281
18282static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
18283{
18284 unsigned int present;
18285 unsigned char bits;
18286
864f92be 18287 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
18288 bits = present ? HDA_AMP_MUTE : 0;
18289 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18290 HDA_AMP_MUTE, bits);
f1d4e28b 18291 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18292 HDA_AMP_MUTE, bits);
f1d4e28b 18293 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18294 HDA_AMP_MUTE, bits);
f1d4e28b 18295 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18296 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18297}
18298
18299static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
18300{
18301 unsigned int present;
18302 unsigned char bits;
18303
864f92be 18304 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18305 bits = present ? HDA_AMP_MUTE : 0;
18306 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18307 HDA_AMP_MUTE, bits);
f1d4e28b 18308 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18309 HDA_AMP_MUTE, bits);
f1d4e28b 18310 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18311 HDA_AMP_MUTE, bits);
f1d4e28b 18312 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18313 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18314}
18315
18316static void alc662_f5z_speaker_automute(struct hda_codec *codec)
18317{
18318 unsigned int present;
18319 unsigned char bits;
18320
864f92be 18321 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
18322 bits = present ? 0 : PIN_OUT;
18323 snd_hda_codec_write(codec, 0x14, 0,
18324 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
18325}
18326
18327static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
18328{
18329 unsigned int present1, present2;
18330
864f92be
WF
18331 present1 = snd_hda_jack_detect(codec, 0x21);
18332 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18333
18334 if (present1 || present2) {
18335 snd_hda_codec_write_cache(codec, 0x14, 0,
18336 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18337 } else {
18338 snd_hda_codec_write_cache(codec, 0x14, 0,
18339 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18340 }
18341}
18342
18343static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
18344{
18345 unsigned int present1, present2;
18346
864f92be
WF
18347 present1 = snd_hda_jack_detect(codec, 0x1b);
18348 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18349
18350 if (present1 || present2) {
18351 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18352 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 18353 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18354 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
18355 } else {
18356 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18357 HDA_AMP_MUTE, 0);
f1d4e28b 18358 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18359 HDA_AMP_MUTE, 0);
f1d4e28b 18360 }
6dda9f4a
KY
18361}
18362
ebb83eeb
KY
18363static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
18364{
18365 unsigned int present1, present2;
18366
18367 present1 = snd_hda_codec_read(codec, 0x1b, 0,
18368 AC_VERB_GET_PIN_SENSE, 0)
18369 & AC_PINSENSE_PRESENCE;
18370 present2 = snd_hda_codec_read(codec, 0x21, 0,
18371 AC_VERB_GET_PIN_SENSE, 0)
18372 & AC_PINSENSE_PRESENCE;
18373
18374 if (present1 || present2) {
18375 snd_hda_codec_write_cache(codec, 0x14, 0,
18376 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18377 snd_hda_codec_write_cache(codec, 0x17, 0,
18378 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18379 } else {
18380 snd_hda_codec_write_cache(codec, 0x14, 0,
18381 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18382 snd_hda_codec_write_cache(codec, 0x17, 0,
18383 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18384 }
18385}
18386
18387static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
18388{
18389 unsigned int present1, present2;
18390
18391 present1 = snd_hda_codec_read(codec, 0x21, 0,
18392 AC_VERB_GET_PIN_SENSE, 0)
18393 & AC_PINSENSE_PRESENCE;
18394 present2 = snd_hda_codec_read(codec, 0x15, 0,
18395 AC_VERB_GET_PIN_SENSE, 0)
18396 & AC_PINSENSE_PRESENCE;
18397
18398 if (present1 || present2) {
18399 snd_hda_codec_write_cache(codec, 0x14, 0,
18400 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18401 snd_hda_codec_write_cache(codec, 0x17, 0,
18402 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18403 } else {
18404 snd_hda_codec_write_cache(codec, 0x14, 0,
18405 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18406 snd_hda_codec_write_cache(codec, 0x17, 0,
18407 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18408 }
18409}
18410
6dda9f4a
KY
18411static void alc663_m51va_unsol_event(struct hda_codec *codec,
18412 unsigned int res)
18413{
18414 switch (res >> 26) {
18415 case ALC880_HP_EVENT:
18416 alc663_m51va_speaker_automute(codec);
18417 break;
18418 case ALC880_MIC_EVENT:
4f5d1706 18419 alc_mic_automute(codec);
6dda9f4a
KY
18420 break;
18421 }
18422}
18423
4f5d1706
TI
18424static void alc663_m51va_setup(struct hda_codec *codec)
18425{
18426 struct alc_spec *spec = codec->spec;
18427 spec->ext_mic.pin = 0x18;
18428 spec->ext_mic.mux_idx = 0;
18429 spec->int_mic.pin = 0x12;
ebb83eeb 18430 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18431 spec->auto_mic = 1;
18432}
18433
6dda9f4a
KY
18434static void alc663_m51va_inithook(struct hda_codec *codec)
18435{
18436 alc663_m51va_speaker_automute(codec);
4f5d1706 18437 alc_mic_automute(codec);
6dda9f4a
KY
18438}
18439
f1d4e28b 18440/* ***************** Mode1 ******************************/
4f5d1706 18441#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
18442
18443static void alc663_mode1_setup(struct hda_codec *codec)
18444{
18445 struct alc_spec *spec = codec->spec;
18446 spec->ext_mic.pin = 0x18;
18447 spec->ext_mic.mux_idx = 0;
18448 spec->int_mic.pin = 0x19;
18449 spec->int_mic.mux_idx = 1;
18450 spec->auto_mic = 1;
18451}
18452
4f5d1706 18453#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 18454
f1d4e28b
KY
18455/* ***************** Mode2 ******************************/
18456static void alc662_mode2_unsol_event(struct hda_codec *codec,
18457 unsigned int res)
18458{
18459 switch (res >> 26) {
18460 case ALC880_HP_EVENT:
18461 alc662_f5z_speaker_automute(codec);
18462 break;
18463 case ALC880_MIC_EVENT:
4f5d1706 18464 alc_mic_automute(codec);
f1d4e28b
KY
18465 break;
18466 }
18467}
18468
ebb83eeb 18469#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 18470
f1d4e28b
KY
18471static void alc662_mode2_inithook(struct hda_codec *codec)
18472{
18473 alc662_f5z_speaker_automute(codec);
4f5d1706 18474 alc_mic_automute(codec);
f1d4e28b
KY
18475}
18476/* ***************** Mode3 ******************************/
18477static void alc663_mode3_unsol_event(struct hda_codec *codec,
18478 unsigned int res)
18479{
18480 switch (res >> 26) {
18481 case ALC880_HP_EVENT:
18482 alc663_two_hp_m1_speaker_automute(codec);
18483 break;
18484 case ALC880_MIC_EVENT:
4f5d1706 18485 alc_mic_automute(codec);
f1d4e28b
KY
18486 break;
18487 }
18488}
18489
ebb83eeb 18490#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 18491
f1d4e28b
KY
18492static void alc663_mode3_inithook(struct hda_codec *codec)
18493{
18494 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 18495 alc_mic_automute(codec);
f1d4e28b
KY
18496}
18497/* ***************** Mode4 ******************************/
18498static void alc663_mode4_unsol_event(struct hda_codec *codec,
18499 unsigned int res)
18500{
18501 switch (res >> 26) {
18502 case ALC880_HP_EVENT:
18503 alc663_21jd_two_speaker_automute(codec);
18504 break;
18505 case ALC880_MIC_EVENT:
4f5d1706 18506 alc_mic_automute(codec);
f1d4e28b
KY
18507 break;
18508 }
18509}
18510
ebb83eeb 18511#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 18512
f1d4e28b
KY
18513static void alc663_mode4_inithook(struct hda_codec *codec)
18514{
18515 alc663_21jd_two_speaker_automute(codec);
4f5d1706 18516 alc_mic_automute(codec);
f1d4e28b
KY
18517}
18518/* ***************** Mode5 ******************************/
18519static void alc663_mode5_unsol_event(struct hda_codec *codec,
18520 unsigned int res)
18521{
18522 switch (res >> 26) {
18523 case ALC880_HP_EVENT:
18524 alc663_15jd_two_speaker_automute(codec);
18525 break;
18526 case ALC880_MIC_EVENT:
4f5d1706 18527 alc_mic_automute(codec);
f1d4e28b
KY
18528 break;
18529 }
18530}
18531
ebb83eeb 18532#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 18533
f1d4e28b
KY
18534static void alc663_mode5_inithook(struct hda_codec *codec)
18535{
18536 alc663_15jd_two_speaker_automute(codec);
4f5d1706 18537 alc_mic_automute(codec);
f1d4e28b
KY
18538}
18539/* ***************** Mode6 ******************************/
18540static void alc663_mode6_unsol_event(struct hda_codec *codec,
18541 unsigned int res)
18542{
18543 switch (res >> 26) {
18544 case ALC880_HP_EVENT:
18545 alc663_two_hp_m2_speaker_automute(codec);
18546 break;
18547 case ALC880_MIC_EVENT:
4f5d1706 18548 alc_mic_automute(codec);
f1d4e28b
KY
18549 break;
18550 }
18551}
18552
ebb83eeb 18553#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 18554
f1d4e28b
KY
18555static void alc663_mode6_inithook(struct hda_codec *codec)
18556{
18557 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 18558 alc_mic_automute(codec);
f1d4e28b
KY
18559}
18560
ebb83eeb
KY
18561/* ***************** Mode7 ******************************/
18562static void alc663_mode7_unsol_event(struct hda_codec *codec,
18563 unsigned int res)
18564{
18565 switch (res >> 26) {
18566 case ALC880_HP_EVENT:
18567 alc663_two_hp_m7_speaker_automute(codec);
18568 break;
18569 case ALC880_MIC_EVENT:
18570 alc_mic_automute(codec);
18571 break;
18572 }
18573}
18574
18575#define alc663_mode7_setup alc663_mode1_setup
18576
18577static void alc663_mode7_inithook(struct hda_codec *codec)
18578{
18579 alc663_two_hp_m7_speaker_automute(codec);
18580 alc_mic_automute(codec);
18581}
18582
18583/* ***************** Mode8 ******************************/
18584static void alc663_mode8_unsol_event(struct hda_codec *codec,
18585 unsigned int res)
18586{
18587 switch (res >> 26) {
18588 case ALC880_HP_EVENT:
18589 alc663_two_hp_m8_speaker_automute(codec);
18590 break;
18591 case ALC880_MIC_EVENT:
18592 alc_mic_automute(codec);
18593 break;
18594 }
18595}
18596
18597#define alc663_mode8_setup alc663_m51va_setup
18598
18599static void alc663_mode8_inithook(struct hda_codec *codec)
18600{
18601 alc663_two_hp_m8_speaker_automute(codec);
18602 alc_mic_automute(codec);
18603}
18604
6dda9f4a
KY
18605static void alc663_g71v_hp_automute(struct hda_codec *codec)
18606{
18607 unsigned int present;
18608 unsigned char bits;
18609
864f92be 18610 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
18611 bits = present ? HDA_AMP_MUTE : 0;
18612 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18613 HDA_AMP_MUTE, bits);
18614 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18615 HDA_AMP_MUTE, bits);
18616}
18617
18618static void alc663_g71v_front_automute(struct hda_codec *codec)
18619{
18620 unsigned int present;
18621 unsigned char bits;
18622
864f92be 18623 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
18624 bits = present ? HDA_AMP_MUTE : 0;
18625 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18626 HDA_AMP_MUTE, bits);
18627}
18628
18629static void alc663_g71v_unsol_event(struct hda_codec *codec,
18630 unsigned int res)
18631{
18632 switch (res >> 26) {
18633 case ALC880_HP_EVENT:
18634 alc663_g71v_hp_automute(codec);
18635 break;
18636 case ALC880_FRONT_EVENT:
18637 alc663_g71v_front_automute(codec);
18638 break;
18639 case ALC880_MIC_EVENT:
4f5d1706 18640 alc_mic_automute(codec);
6dda9f4a
KY
18641 break;
18642 }
18643}
18644
4f5d1706
TI
18645#define alc663_g71v_setup alc663_m51va_setup
18646
6dda9f4a
KY
18647static void alc663_g71v_inithook(struct hda_codec *codec)
18648{
18649 alc663_g71v_front_automute(codec);
18650 alc663_g71v_hp_automute(codec);
4f5d1706 18651 alc_mic_automute(codec);
6dda9f4a
KY
18652}
18653
18654static void alc663_g50v_unsol_event(struct hda_codec *codec,
18655 unsigned int res)
18656{
18657 switch (res >> 26) {
18658 case ALC880_HP_EVENT:
18659 alc663_m51va_speaker_automute(codec);
18660 break;
18661 case ALC880_MIC_EVENT:
4f5d1706 18662 alc_mic_automute(codec);
6dda9f4a
KY
18663 break;
18664 }
18665}
18666
4f5d1706
TI
18667#define alc663_g50v_setup alc663_m51va_setup
18668
6dda9f4a
KY
18669static void alc663_g50v_inithook(struct hda_codec *codec)
18670{
18671 alc663_m51va_speaker_automute(codec);
4f5d1706 18672 alc_mic_automute(codec);
6dda9f4a
KY
18673}
18674
f1d4e28b
KY
18675static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18676 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18677 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b 18678
5f99f86a 18679 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
18680 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18681 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b 18682
5f99f86a 18683 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
18684 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18685 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
f1d4e28b
KY
18686 { } /* end */
18687};
18688
9541ba1d
CP
18689static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18690 /* Master Playback automatically created from Speaker and Headphone */
18691 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18692 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18693 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18694 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18695
8607f7c4
DH
18696 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18697 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 18698 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9541ba1d 18699
28c4edb7
DH
18700 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18701 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 18702 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9541ba1d
CP
18703 { } /* end */
18704};
18705
cb53c626
TI
18706#ifdef CONFIG_SND_HDA_POWER_SAVE
18707#define alc662_loopbacks alc880_loopbacks
18708#endif
18709
bc9f98a9 18710
def319f9 18711/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18712#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18713#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18714#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18715#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18716
18717/*
18718 * configuration and preset
18719 */
ea734963 18720static const char * const alc662_models[ALC662_MODEL_LAST] = {
bc9f98a9
KY
18721 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18722 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18723 [ALC662_3ST_6ch] = "3stack-6ch",
18724 [ALC662_5ST_DIG] = "6stack-dig",
18725 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18726 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18727 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18728 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18729 [ALC663_ASUS_M51VA] = "m51va",
18730 [ALC663_ASUS_G71V] = "g71v",
18731 [ALC663_ASUS_H13] = "h13",
18732 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18733 [ALC663_ASUS_MODE1] = "asus-mode1",
18734 [ALC662_ASUS_MODE2] = "asus-mode2",
18735 [ALC663_ASUS_MODE3] = "asus-mode3",
18736 [ALC663_ASUS_MODE4] = "asus-mode4",
18737 [ALC663_ASUS_MODE5] = "asus-mode5",
18738 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18739 [ALC663_ASUS_MODE7] = "asus-mode7",
18740 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18741 [ALC272_DELL] = "dell",
18742 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18743 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18744 [ALC662_AUTO] = "auto",
18745};
18746
18747static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18748 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18749 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18750 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18751 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18752 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18753 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18754 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18755 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18756 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18757 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18758 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18759 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18760 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18761 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18762 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18763 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18764 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18765 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18766 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18767 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18768 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18769 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18770 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18771 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18772 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18773 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18774 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18775 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18776 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18777 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18778 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18779 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18780 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18781 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18782 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18783 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18784 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18785 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18786 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18787 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18788 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18789 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18790 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18791 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18792 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18793 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18794 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18795 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18796 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18797 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18798 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18799 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18800 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18801 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18802 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18803 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18804 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18805 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18806 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18807 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18808 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18809 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18810 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18811 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18812 ALC662_3ST_6ch_DIG),
4dee8baa 18813 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18814 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
18815 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18816 ALC662_3ST_6ch_DIG),
6227cdce 18817 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18818 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18819 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18820 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18821 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18822 ALC662_3ST_6ch_DIG),
dea0a509
TI
18823 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18824 ALC663_ASUS_H13),
965b76d2 18825 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
bc9f98a9
KY
18826 {}
18827};
18828
18829static struct alc_config_preset alc662_presets[] = {
18830 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18831 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
18832 .init_verbs = { alc662_init_verbs },
18833 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18834 .dac_nids = alc662_dac_nids,
18835 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18836 .dig_in_nid = ALC662_DIGIN_NID,
18837 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18838 .channel_mode = alc662_3ST_2ch_modes,
18839 .input_mux = &alc662_capture_source,
18840 },
18841 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18842 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18843 .init_verbs = { alc662_init_verbs },
18844 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18845 .dac_nids = alc662_dac_nids,
18846 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18847 .dig_in_nid = ALC662_DIGIN_NID,
18848 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18849 .channel_mode = alc662_3ST_6ch_modes,
18850 .need_dac_fix = 1,
18851 .input_mux = &alc662_capture_source,
f12ab1e0 18852 },
bc9f98a9 18853 [ALC662_3ST_6ch] = {
f9e336f6 18854 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18855 .init_verbs = { alc662_init_verbs },
18856 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18857 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18858 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18859 .channel_mode = alc662_3ST_6ch_modes,
18860 .need_dac_fix = 1,
18861 .input_mux = &alc662_capture_source,
f12ab1e0 18862 },
bc9f98a9 18863 [ALC662_5ST_DIG] = {
f9e336f6 18864 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18865 .init_verbs = { alc662_init_verbs },
18866 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18867 .dac_nids = alc662_dac_nids,
18868 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18869 .dig_in_nid = ALC662_DIGIN_NID,
18870 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18871 .channel_mode = alc662_5stack_modes,
18872 .input_mux = &alc662_capture_source,
18873 },
18874 [ALC662_LENOVO_101E] = {
f9e336f6 18875 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
18876 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18877 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18878 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18879 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18880 .channel_mode = alc662_3ST_2ch_modes,
18881 .input_mux = &alc662_lenovo_101e_capture_source,
18882 .unsol_event = alc662_lenovo_101e_unsol_event,
18883 .init_hook = alc662_lenovo_101e_all_automute,
18884 },
291702f0 18885 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18886 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
18887 .init_verbs = { alc662_init_verbs,
18888 alc662_eeepc_sue_init_verbs },
18889 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18890 .dac_nids = alc662_dac_nids,
291702f0
KY
18891 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18892 .channel_mode = alc662_3ST_2ch_modes,
291702f0 18893 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18894 .setup = alc662_eeepc_setup,
291702f0
KY
18895 .init_hook = alc662_eeepc_inithook,
18896 },
8c427226 18897 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18898 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18899 alc662_chmode_mixer },
18900 .init_verbs = { alc662_init_verbs,
18901 alc662_eeepc_ep20_sue_init_verbs },
18902 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18903 .dac_nids = alc662_dac_nids,
8c427226
KY
18904 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18905 .channel_mode = alc662_3ST_6ch_modes,
18906 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 18907 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18908 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
18909 .init_hook = alc662_eeepc_ep20_inithook,
18910 },
f1d4e28b 18911 [ALC662_ECS] = {
f9e336f6 18912 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
18913 .init_verbs = { alc662_init_verbs,
18914 alc662_ecs_init_verbs },
18915 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18916 .dac_nids = alc662_dac_nids,
18917 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18918 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18919 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18920 .setup = alc662_eeepc_setup,
f1d4e28b
KY
18921 .init_hook = alc662_eeepc_inithook,
18922 },
6dda9f4a 18923 [ALC663_ASUS_M51VA] = {
f9e336f6 18924 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18925 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18926 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18927 .dac_nids = alc662_dac_nids,
18928 .dig_out_nid = ALC662_DIGOUT_NID,
18929 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18930 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18931 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18932 .setup = alc663_m51va_setup,
6dda9f4a
KY
18933 .init_hook = alc663_m51va_inithook,
18934 },
18935 [ALC663_ASUS_G71V] = {
f9e336f6 18936 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
18937 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18938 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18939 .dac_nids = alc662_dac_nids,
18940 .dig_out_nid = ALC662_DIGOUT_NID,
18941 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18942 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18943 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 18944 .setup = alc663_g71v_setup,
6dda9f4a
KY
18945 .init_hook = alc663_g71v_inithook,
18946 },
18947 [ALC663_ASUS_H13] = {
f9e336f6 18948 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18949 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18950 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18951 .dac_nids = alc662_dac_nids,
18952 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18953 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
18954 .unsol_event = alc663_m51va_unsol_event,
18955 .init_hook = alc663_m51va_inithook,
18956 },
18957 [ALC663_ASUS_G50V] = {
f9e336f6 18958 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
18959 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18960 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18961 .dac_nids = alc662_dac_nids,
18962 .dig_out_nid = ALC662_DIGOUT_NID,
18963 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18964 .channel_mode = alc662_3ST_6ch_modes,
18965 .input_mux = &alc663_capture_source,
18966 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 18967 .setup = alc663_g50v_setup,
6dda9f4a
KY
18968 .init_hook = alc663_g50v_inithook,
18969 },
f1d4e28b 18970 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18971 .mixers = { alc663_m51va_mixer },
18972 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18973 .init_verbs = { alc662_init_verbs,
18974 alc663_21jd_amic_init_verbs },
18975 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18976 .hp_nid = 0x03,
18977 .dac_nids = alc662_dac_nids,
18978 .dig_out_nid = ALC662_DIGOUT_NID,
18979 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18980 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18981 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18982 .setup = alc663_mode1_setup,
f1d4e28b
KY
18983 .init_hook = alc663_mode1_inithook,
18984 },
18985 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18986 .mixers = { alc662_1bjd_mixer },
18987 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18988 .init_verbs = { alc662_init_verbs,
18989 alc662_1bjd_amic_init_verbs },
18990 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18991 .dac_nids = alc662_dac_nids,
18992 .dig_out_nid = ALC662_DIGOUT_NID,
18993 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18994 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18995 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18996 .setup = alc662_mode2_setup,
f1d4e28b
KY
18997 .init_hook = alc662_mode2_inithook,
18998 },
18999 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
19000 .mixers = { alc663_two_hp_m1_mixer },
19001 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
19002 .init_verbs = { alc662_init_verbs,
19003 alc663_two_hp_amic_m1_init_verbs },
19004 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19005 .hp_nid = 0x03,
19006 .dac_nids = alc662_dac_nids,
19007 .dig_out_nid = ALC662_DIGOUT_NID,
19008 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19009 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 19010 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 19011 .setup = alc663_mode3_setup,
f1d4e28b
KY
19012 .init_hook = alc663_mode3_inithook,
19013 },
19014 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
19015 .mixers = { alc663_asus_21jd_clfe_mixer },
19016 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
19017 .init_verbs = { alc662_init_verbs,
19018 alc663_21jd_amic_init_verbs},
19019 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19020 .hp_nid = 0x03,
19021 .dac_nids = alc662_dac_nids,
19022 .dig_out_nid = ALC662_DIGOUT_NID,
19023 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19024 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 19025 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 19026 .setup = alc663_mode4_setup,
f1d4e28b
KY
19027 .init_hook = alc663_mode4_inithook,
19028 },
19029 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
19030 .mixers = { alc663_asus_15jd_clfe_mixer },
19031 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
19032 .init_verbs = { alc662_init_verbs,
19033 alc663_15jd_amic_init_verbs },
19034 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19035 .hp_nid = 0x03,
19036 .dac_nids = alc662_dac_nids,
19037 .dig_out_nid = ALC662_DIGOUT_NID,
19038 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19039 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 19040 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 19041 .setup = alc663_mode5_setup,
f1d4e28b
KY
19042 .init_hook = alc663_mode5_inithook,
19043 },
19044 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
19045 .mixers = { alc663_two_hp_m2_mixer },
19046 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
19047 .init_verbs = { alc662_init_verbs,
19048 alc663_two_hp_amic_m2_init_verbs },
19049 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19050 .hp_nid = 0x03,
19051 .dac_nids = alc662_dac_nids,
19052 .dig_out_nid = ALC662_DIGOUT_NID,
19053 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19054 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 19055 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 19056 .setup = alc663_mode6_setup,
f1d4e28b
KY
19057 .init_hook = alc663_mode6_inithook,
19058 },
ebb83eeb
KY
19059 [ALC663_ASUS_MODE7] = {
19060 .mixers = { alc663_mode7_mixer },
19061 .cap_mixer = alc662_auto_capture_mixer,
19062 .init_verbs = { alc662_init_verbs,
19063 alc663_mode7_init_verbs },
19064 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19065 .hp_nid = 0x03,
19066 .dac_nids = alc662_dac_nids,
19067 .dig_out_nid = ALC662_DIGOUT_NID,
19068 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19069 .channel_mode = alc662_3ST_2ch_modes,
19070 .unsol_event = alc663_mode7_unsol_event,
19071 .setup = alc663_mode7_setup,
19072 .init_hook = alc663_mode7_inithook,
19073 },
19074 [ALC663_ASUS_MODE8] = {
19075 .mixers = { alc663_mode8_mixer },
19076 .cap_mixer = alc662_auto_capture_mixer,
19077 .init_verbs = { alc662_init_verbs,
19078 alc663_mode8_init_verbs },
19079 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19080 .hp_nid = 0x03,
19081 .dac_nids = alc662_dac_nids,
19082 .dig_out_nid = ALC662_DIGOUT_NID,
19083 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19084 .channel_mode = alc662_3ST_2ch_modes,
19085 .unsol_event = alc663_mode8_unsol_event,
19086 .setup = alc663_mode8_setup,
19087 .init_hook = alc663_mode8_inithook,
19088 },
622e84cd
KY
19089 [ALC272_DELL] = {
19090 .mixers = { alc663_m51va_mixer },
19091 .cap_mixer = alc272_auto_capture_mixer,
19092 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
19093 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19094 .dac_nids = alc662_dac_nids,
19095 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19096 .adc_nids = alc272_adc_nids,
19097 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
19098 .capsrc_nids = alc272_capsrc_nids,
19099 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 19100 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 19101 .setup = alc663_m51va_setup,
622e84cd
KY
19102 .init_hook = alc663_m51va_inithook,
19103 },
19104 [ALC272_DELL_ZM1] = {
19105 .mixers = { alc663_m51va_mixer },
19106 .cap_mixer = alc662_auto_capture_mixer,
19107 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
19108 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19109 .dac_nids = alc662_dac_nids,
19110 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19111 .adc_nids = alc662_adc_nids,
b59bdf3b 19112 .num_adc_nids = 1,
622e84cd
KY
19113 .capsrc_nids = alc662_capsrc_nids,
19114 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 19115 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 19116 .setup = alc663_m51va_setup,
622e84cd
KY
19117 .init_hook = alc663_m51va_inithook,
19118 },
9541ba1d
CP
19119 [ALC272_SAMSUNG_NC10] = {
19120 .mixers = { alc272_nc10_mixer },
19121 .init_verbs = { alc662_init_verbs,
19122 alc663_21jd_amic_init_verbs },
19123 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19124 .dac_nids = alc272_dac_nids,
19125 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19126 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 19127 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 19128 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 19129 .setup = alc663_mode4_setup,
9541ba1d
CP
19130 .init_hook = alc663_mode4_inithook,
19131 },
bc9f98a9
KY
19132};
19133
19134
19135/*
19136 * BIOS auto configuration
19137 */
19138
7085ec12
TI
19139/* convert from MIX nid to DAC */
19140static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
19141{
19142 if (nid == 0x0f)
19143 return 0x02;
19144 else if (nid >= 0x0c && nid <= 0x0e)
19145 return nid - 0x0c + 0x02;
cc1c452e
DH
19146 else if (nid == 0x26) /* ALC887-VD has this DAC too */
19147 return 0x25;
7085ec12
TI
19148 else
19149 return 0;
19150}
19151
19152/* get MIX nid connected to the given pin targeted to DAC */
19153static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
19154 hda_nid_t dac)
19155{
cc1c452e 19156 hda_nid_t mix[5];
7085ec12
TI
19157 int i, num;
19158
19159 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
19160 for (i = 0; i < num; i++) {
19161 if (alc662_mix_to_dac(mix[i]) == dac)
19162 return mix[i];
19163 }
19164 return 0;
19165}
19166
19167/* look for an empty DAC slot */
19168static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
19169{
19170 struct alc_spec *spec = codec->spec;
19171 hda_nid_t srcs[5];
19172 int i, j, num;
19173
19174 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
19175 if (num < 0)
19176 return 0;
19177 for (i = 0; i < num; i++) {
19178 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
19179 if (!nid)
19180 continue;
19181 for (j = 0; j < spec->multiout.num_dacs; j++)
19182 if (spec->multiout.dac_nids[j] == nid)
19183 break;
19184 if (j >= spec->multiout.num_dacs)
19185 return nid;
19186 }
19187 return 0;
19188}
19189
19190/* fill in the dac_nids table from the parsed pin configuration */
19191static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19192 const struct auto_pin_cfg *cfg)
19193{
19194 struct alc_spec *spec = codec->spec;
19195 int i;
19196 hda_nid_t dac;
19197
19198 spec->multiout.dac_nids = spec->private_dac_nids;
19199 for (i = 0; i < cfg->line_outs; i++) {
19200 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
19201 if (!dac)
19202 continue;
19203 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19204 }
19205 return 0;
19206}
19207
bcb2f0f5
TI
19208static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
19209 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19210{
bcb2f0f5 19211 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
7085ec12
TI
19212 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
19213}
19214
bcb2f0f5
TI
19215static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19216 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19217{
bcb2f0f5 19218 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
7085ec12
TI
19219 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19220}
19221
bcb2f0f5
TI
19222#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19223 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19224#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19225 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
7085ec12
TI
19226#define alc662_add_stereo_vol(spec, pfx, nid) \
19227 alc662_add_vol_ctl(spec, pfx, nid, 3)
19228#define alc662_add_stereo_sw(spec, pfx, nid) \
19229 alc662_add_sw_ctl(spec, pfx, nid, 3)
19230
bc9f98a9 19231/* add playback controls from the parsed DAC table */
7085ec12 19232static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
19233 const struct auto_pin_cfg *cfg)
19234{
7085ec12 19235 struct alc_spec *spec = codec->spec;
ea734963 19236 static const char * const chname[4] = {
bc9f98a9
KY
19237 "Front", "Surround", NULL /*CLFE*/, "Side"
19238 };
bcb2f0f5 19239 const char *pfx = alc_get_line_out_pfx(cfg, true);
7085ec12 19240 hda_nid_t nid, mix;
bc9f98a9
KY
19241 int i, err;
19242
19243 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
19244 nid = spec->multiout.dac_nids[i];
19245 if (!nid)
19246 continue;
19247 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
19248 if (!mix)
bc9f98a9 19249 continue;
bcb2f0f5 19250 if (!pfx && i == 2) {
bc9f98a9 19251 /* Center/LFE */
7085ec12 19252 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
19253 if (err < 0)
19254 return err;
7085ec12 19255 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
19256 if (err < 0)
19257 return err;
7085ec12 19258 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
19259 if (err < 0)
19260 return err;
7085ec12 19261 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
19262 if (err < 0)
19263 return err;
19264 } else {
bcb2f0f5
TI
19265 const char *name = pfx;
19266 if (!name)
19267 name = chname[i];
19268 err = __alc662_add_vol_ctl(spec, name, nid, i, 3);
bc9f98a9
KY
19269 if (err < 0)
19270 return err;
bcb2f0f5 19271 err = __alc662_add_sw_ctl(spec, name, mix, i, 3);
bc9f98a9
KY
19272 if (err < 0)
19273 return err;
19274 }
19275 }
19276 return 0;
19277}
19278
19279/* add playback controls for speaker and HP outputs */
7085ec12
TI
19280/* return DAC nid if any new DAC is assigned */
19281static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
19282 const char *pfx)
19283{
7085ec12
TI
19284 struct alc_spec *spec = codec->spec;
19285 hda_nid_t nid, mix;
bc9f98a9 19286 int err;
bc9f98a9
KY
19287
19288 if (!pin)
19289 return 0;
7085ec12
TI
19290 nid = alc662_look_for_dac(codec, pin);
19291 if (!nid) {
7085ec12
TI
19292 /* the corresponding DAC is already occupied */
19293 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19294 return 0; /* no way */
19295 /* create a switch only */
0afe5f89 19296 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 19297 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
19298 }
19299
7085ec12
TI
19300 mix = alc662_dac_to_mix(codec, pin, nid);
19301 if (!mix)
19302 return 0;
19303 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19304 if (err < 0)
19305 return err;
19306 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19307 if (err < 0)
19308 return err;
19309 return nid;
bc9f98a9
KY
19310}
19311
19312/* create playback/capture controls for input pins */
05f5f477 19313#define alc662_auto_create_input_ctls \
4b7348a1 19314 alc882_auto_create_input_ctls
bc9f98a9
KY
19315
19316static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19317 hda_nid_t nid, int pin_type,
7085ec12 19318 hda_nid_t dac)
bc9f98a9 19319{
7085ec12 19320 int i, num;
ce503f38 19321 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 19322
f6c7e546 19323 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 19324 /* need the manual connection? */
7085ec12
TI
19325 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19326 if (num <= 1)
19327 return;
19328 for (i = 0; i < num; i++) {
19329 if (alc662_mix_to_dac(srcs[i]) != dac)
19330 continue;
19331 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
19332 return;
bc9f98a9
KY
19333 }
19334}
19335
19336static void alc662_auto_init_multi_out(struct hda_codec *codec)
19337{
19338 struct alc_spec *spec = codec->spec;
7085ec12 19339 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
19340 int i;
19341
19342 for (i = 0; i <= HDA_SIDE; i++) {
19343 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19344 if (nid)
baba8ee9 19345 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 19346 spec->multiout.dac_nids[i]);
bc9f98a9
KY
19347 }
19348}
19349
19350static void alc662_auto_init_hp_out(struct hda_codec *codec)
19351{
19352 struct alc_spec *spec = codec->spec;
19353 hda_nid_t pin;
19354
19355 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
19356 if (pin)
19357 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19358 spec->multiout.hp_nid);
f6c7e546
TI
19359 pin = spec->autocfg.speaker_pins[0];
19360 if (pin)
7085ec12
TI
19361 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19362 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
19363}
19364
bc9f98a9
KY
19365#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19366
19367static void alc662_auto_init_analog_input(struct hda_codec *codec)
19368{
19369 struct alc_spec *spec = codec->spec;
66ceeb6b 19370 struct auto_pin_cfg *cfg = &spec->autocfg;
bc9f98a9
KY
19371 int i;
19372
66ceeb6b
TI
19373 for (i = 0; i < cfg->num_inputs; i++) {
19374 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 19375 if (alc_is_input_pin(codec, nid)) {
30ea098f 19376 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
52ca15b7 19377 if (nid != ALC662_PIN_CD_NID &&
e82c025b 19378 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
19379 snd_hda_codec_write(codec, nid, 0,
19380 AC_VERB_SET_AMP_GAIN_MUTE,
19381 AMP_OUT_MUTE);
19382 }
19383 }
19384}
19385
f511b01c
TI
19386#define alc662_auto_init_input_src alc882_auto_init_input_src
19387
bc9f98a9
KY
19388static int alc662_parse_auto_config(struct hda_codec *codec)
19389{
19390 struct alc_spec *spec = codec->spec;
19391 int err;
19392 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19393
19394 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19395 alc662_ignore);
19396 if (err < 0)
19397 return err;
19398 if (!spec->autocfg.line_outs)
19399 return 0; /* can't find valid BIOS pin config */
19400
7085ec12 19401 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
19402 if (err < 0)
19403 return err;
7085ec12 19404 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19405 if (err < 0)
19406 return err;
7085ec12 19407 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
19408 spec->autocfg.speaker_pins[0],
19409 "Speaker");
19410 if (err < 0)
19411 return err;
7085ec12
TI
19412 if (err)
19413 spec->multiout.extra_out_nid[0] = err;
19414 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
19415 "Headphone");
19416 if (err < 0)
19417 return err;
7085ec12
TI
19418 if (err)
19419 spec->multiout.hp_nid = err;
05f5f477 19420 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19421 if (err < 0)
bc9f98a9
KY
19422 return err;
19423
19424 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19425
757899ac 19426 alc_auto_parse_digital(codec);
bc9f98a9 19427
603c4019 19428 if (spec->kctls.list)
d88897ea 19429 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19430
19431 spec->num_mux_defs = 1;
61b9b9b1 19432 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19433
cec27c89
KY
19434 add_verb(spec, alc662_init_verbs);
19435 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
d1eb57f4 19436 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
cec27c89
KY
19437 add_verb(spec, alc663_init_verbs);
19438
19439 if (codec->vendor_id == 0x10ec0272)
19440 add_verb(spec, alc272_init_verbs);
ee979a14
TI
19441
19442 err = alc_auto_add_mic_boost(codec);
19443 if (err < 0)
19444 return err;
19445
6227cdce
KY
19446 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19447 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19448 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19449 else
19450 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19451
8c87286f 19452 return 1;
bc9f98a9
KY
19453}
19454
19455/* additional initialization for auto-configuration model */
19456static void alc662_auto_init(struct hda_codec *codec)
19457{
f6c7e546 19458 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19459 alc662_auto_init_multi_out(codec);
19460 alc662_auto_init_hp_out(codec);
19461 alc662_auto_init_analog_input(codec);
f511b01c 19462 alc662_auto_init_input_src(codec);
757899ac 19463 alc_auto_init_digital(codec);
f6c7e546 19464 if (spec->unsol_event)
7fb0d78f 19465 alc_inithook(codec);
bc9f98a9
KY
19466}
19467
6be7948f 19468static void alc272_fixup_mario(struct hda_codec *codec,
b5bfbc67 19469 const struct alc_fixup *fix, int action)
6fc398cb 19470{
b5bfbc67 19471 if (action != ALC_FIXUP_ACT_PROBE)
6fc398cb 19472 return;
6be7948f
TB
19473 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19474 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19475 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19476 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19477 (0 << AC_AMPCAP_MUTE_SHIFT)))
19478 printk(KERN_WARNING
19479 "hda_codec: failed to override amp caps for NID 0x2\n");
19480}
19481
6cb3b707 19482enum {
2df03514 19483 ALC662_FIXUP_ASPIRE,
6cb3b707 19484 ALC662_FIXUP_IDEAPAD,
6be7948f 19485 ALC272_FIXUP_MARIO,
d2ebd479 19486 ALC662_FIXUP_CZC_P10T,
6cb3b707
DH
19487};
19488
19489static const struct alc_fixup alc662_fixups[] = {
2df03514 19490 [ALC662_FIXUP_ASPIRE] = {
b5bfbc67
TI
19491 .type = ALC_FIXUP_PINS,
19492 .v.pins = (const struct alc_pincfg[]) {
2df03514
DC
19493 { 0x15, 0x99130112 }, /* subwoofer */
19494 { }
19495 }
19496 },
6cb3b707 19497 [ALC662_FIXUP_IDEAPAD] = {
b5bfbc67
TI
19498 .type = ALC_FIXUP_PINS,
19499 .v.pins = (const struct alc_pincfg[]) {
6cb3b707
DH
19500 { 0x17, 0x99130112 }, /* subwoofer */
19501 { }
19502 }
19503 },
6be7948f 19504 [ALC272_FIXUP_MARIO] = {
b5bfbc67
TI
19505 .type = ALC_FIXUP_FUNC,
19506 .v.func = alc272_fixup_mario,
d2ebd479
AA
19507 },
19508 [ALC662_FIXUP_CZC_P10T] = {
19509 .type = ALC_FIXUP_VERBS,
19510 .v.verbs = (const struct hda_verb[]) {
19511 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19512 {}
19513 }
19514 },
6cb3b707
DH
19515};
19516
19517static struct snd_pci_quirk alc662_fixup_tbl[] = {
a6c47a85 19518 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
2df03514 19519 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
a0e90acc 19520 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
d4118588 19521 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707 19522 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
d2ebd479 19523 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6cb3b707
DH
19524 {}
19525};
19526
6be7948f
TB
19527static const struct alc_model_fixup alc662_fixup_models[] = {
19528 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19529 {}
19530};
6cb3b707
DH
19531
19532
bc9f98a9
KY
19533static int patch_alc662(struct hda_codec *codec)
19534{
19535 struct alc_spec *spec;
19536 int err, board_config;
693194f3 19537 int coef;
bc9f98a9
KY
19538
19539 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19540 if (!spec)
19541 return -ENOMEM;
19542
19543 codec->spec = spec;
19544
da00c244
KY
19545 alc_auto_parse_customize_define(codec);
19546
2c3bf9ab
TI
19547 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19548
693194f3
KY
19549 coef = alc_read_coef_idx(codec, 0);
19550 if (coef == 0x8020 || coef == 0x8011)
c027ddcd 19551 alc_codec_rename(codec, "ALC661");
693194f3
KY
19552 else if (coef & (1 << 14) &&
19553 codec->bus->pci->subsystem_vendor == 0x1025 &&
19554 spec->cdefine.platform_type == 1)
c027ddcd 19555 alc_codec_rename(codec, "ALC272X");
693194f3
KY
19556 else if (coef == 0x4011)
19557 alc_codec_rename(codec, "ALC656");
274693f3 19558
bc9f98a9
KY
19559 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19560 alc662_models,
19561 alc662_cfg_tbl);
19562 if (board_config < 0) {
9a11f1aa
TI
19563 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19564 codec->chip_name);
bc9f98a9
KY
19565 board_config = ALC662_AUTO;
19566 }
19567
19568 if (board_config == ALC662_AUTO) {
b5bfbc67
TI
19569 alc_pick_fixup(codec, alc662_fixup_models,
19570 alc662_fixup_tbl, alc662_fixups);
19571 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
bc9f98a9
KY
19572 /* automatic parse from the BIOS config */
19573 err = alc662_parse_auto_config(codec);
19574 if (err < 0) {
19575 alc_free(codec);
19576 return err;
8c87286f 19577 } else if (!err) {
bc9f98a9
KY
19578 printk(KERN_INFO
19579 "hda_codec: Cannot set up configuration "
19580 "from BIOS. Using base mode...\n");
19581 board_config = ALC662_3ST_2ch_DIG;
19582 }
19583 }
19584
dc1eae25 19585 if (has_cdefine_beep(codec)) {
8af2591d
TI
19586 err = snd_hda_attach_beep_device(codec, 0x1);
19587 if (err < 0) {
19588 alc_free(codec);
19589 return err;
19590 }
680cd536
KK
19591 }
19592
bc9f98a9 19593 if (board_config != ALC662_AUTO)
e9c364c0 19594 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19595
bc9f98a9
KY
19596 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19597 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19598
bc9f98a9
KY
19599 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19600 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19601
dd704698
TI
19602 if (!spec->adc_nids) {
19603 spec->adc_nids = alc662_adc_nids;
19604 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19605 }
19606 if (!spec->capsrc_nids)
19607 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19608
f9e336f6 19609 if (!spec->cap_mixer)
b59bdf3b 19610 set_capture_mixer(codec);
cec27c89 19611
dc1eae25 19612 if (has_cdefine_beep(codec)) {
da00c244
KY
19613 switch (codec->vendor_id) {
19614 case 0x10ec0662:
19615 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19616 break;
19617 case 0x10ec0272:
19618 case 0x10ec0663:
19619 case 0x10ec0665:
19620 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19621 break;
19622 case 0x10ec0273:
19623 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19624 break;
19625 }
cec27c89 19626 }
2134ea4f
TI
19627 spec->vmaster_nid = 0x02;
19628
b5bfbc67
TI
19629 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19630
bc9f98a9 19631 codec->patch_ops = alc_patch_ops;
b5bfbc67 19632 if (board_config == ALC662_AUTO)
bc9f98a9 19633 spec->init_hook = alc662_auto_init;
6cb3b707 19634
bf1b0225
KY
19635 alc_init_jacks(codec);
19636
cb53c626
TI
19637#ifdef CONFIG_SND_HDA_POWER_SAVE
19638 if (!spec->loopback.amplist)
19639 spec->loopback.amplist = alc662_loopbacks;
19640#endif
bc9f98a9
KY
19641
19642 return 0;
19643}
19644
274693f3
KY
19645static int patch_alc888(struct hda_codec *codec)
19646{
19647 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19648 kfree(codec->chip_name);
01e0f137
KY
19649 if (codec->vendor_id == 0x10ec0887)
19650 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19651 else
19652 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19653 if (!codec->chip_name) {
19654 alc_free(codec);
274693f3 19655 return -ENOMEM;
ac2c92e0
TI
19656 }
19657 return patch_alc662(codec);
274693f3 19658 }
ac2c92e0 19659 return patch_alc882(codec);
274693f3
KY
19660}
19661
d1eb57f4
KY
19662/*
19663 * ALC680 support
19664 */
c69aefab 19665#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19666#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19667#define alc680_modes alc260_modes
19668
19669static hda_nid_t alc680_dac_nids[3] = {
19670 /* Lout1, Lout2, hp */
19671 0x02, 0x03, 0x04
19672};
19673
19674static hda_nid_t alc680_adc_nids[3] = {
19675 /* ADC0-2 */
19676 /* DMIC, MIC, Line-in*/
19677 0x07, 0x08, 0x09
19678};
19679
c69aefab
KY
19680/*
19681 * Analog capture ADC cgange
19682 */
66ceeb6b
TI
19683static void alc680_rec_autoswitch(struct hda_codec *codec)
19684{
19685 struct alc_spec *spec = codec->spec;
19686 struct auto_pin_cfg *cfg = &spec->autocfg;
19687 int pin_found = 0;
19688 int type_found = AUTO_PIN_LAST;
19689 hda_nid_t nid;
19690 int i;
19691
19692 for (i = 0; i < cfg->num_inputs; i++) {
19693 nid = cfg->inputs[i].pin;
19694 if (!(snd_hda_query_pin_caps(codec, nid) &
19695 AC_PINCAP_PRES_DETECT))
19696 continue;
19697 if (snd_hda_jack_detect(codec, nid)) {
19698 if (cfg->inputs[i].type < type_found) {
19699 type_found = cfg->inputs[i].type;
19700 pin_found = nid;
19701 }
19702 }
19703 }
19704
19705 nid = 0x07;
19706 if (pin_found)
19707 snd_hda_get_connections(codec, pin_found, &nid, 1);
19708
19709 if (nid != spec->cur_adc)
19710 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19711 spec->cur_adc = nid;
19712 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19713 spec->cur_adc_format);
19714}
19715
c69aefab
KY
19716static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19717 struct hda_codec *codec,
19718 unsigned int stream_tag,
19719 unsigned int format,
19720 struct snd_pcm_substream *substream)
19721{
19722 struct alc_spec *spec = codec->spec;
c69aefab 19723
66ceeb6b 19724 spec->cur_adc = 0x07;
c69aefab
KY
19725 spec->cur_adc_stream_tag = stream_tag;
19726 spec->cur_adc_format = format;
19727
66ceeb6b 19728 alc680_rec_autoswitch(codec);
c69aefab
KY
19729 return 0;
19730}
19731
19732static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19733 struct hda_codec *codec,
19734 struct snd_pcm_substream *substream)
19735{
19736 snd_hda_codec_cleanup_stream(codec, 0x07);
19737 snd_hda_codec_cleanup_stream(codec, 0x08);
19738 snd_hda_codec_cleanup_stream(codec, 0x09);
19739 return 0;
19740}
19741
19742static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19743 .substreams = 1, /* can be overridden */
19744 .channels_min = 2,
19745 .channels_max = 2,
19746 /* NID is set in alc_build_pcms */
19747 .ops = {
19748 .prepare = alc680_capture_pcm_prepare,
19749 .cleanup = alc680_capture_pcm_cleanup
19750 },
19751};
19752
d1eb57f4
KY
19753static struct snd_kcontrol_new alc680_base_mixer[] = {
19754 /* output mixer control */
19755 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19756 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19757 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19758 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5f99f86a
DH
19759 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19760 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19761 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19762 { }
19763};
19764
c69aefab
KY
19765static struct hda_bind_ctls alc680_bind_cap_vol = {
19766 .ops = &snd_hda_bind_vol,
19767 .values = {
19768 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19769 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19770 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19771 0
19772 },
19773};
19774
19775static struct hda_bind_ctls alc680_bind_cap_switch = {
19776 .ops = &snd_hda_bind_sw,
19777 .values = {
19778 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19779 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19780 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19781 0
19782 },
19783};
19784
19785static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19786 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19787 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19788 { } /* end */
19789};
19790
19791/*
19792 * generic initialization of ADC, input mixers and output mixers
19793 */
19794static struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19795 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19796 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19797 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19798
c69aefab
KY
19799 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19800 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19802 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19803 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19804 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19805
19806 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19807 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19808 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19809 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19810 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19811
19812 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19813 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19814 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19815
d1eb57f4
KY
19816 { }
19817};
19818
c69aefab
KY
19819/* toggle speaker-output according to the hp-jack state */
19820static void alc680_base_setup(struct hda_codec *codec)
19821{
19822 struct alc_spec *spec = codec->spec;
19823
19824 spec->autocfg.hp_pins[0] = 0x16;
19825 spec->autocfg.speaker_pins[0] = 0x14;
19826 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19827 spec->autocfg.num_inputs = 2;
19828 spec->autocfg.inputs[0].pin = 0x18;
19829 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19830 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19831 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
c69aefab
KY
19832}
19833
19834static void alc680_unsol_event(struct hda_codec *codec,
19835 unsigned int res)
19836{
19837 if ((res >> 26) == ALC880_HP_EVENT)
19838 alc_automute_amp(codec);
19839 if ((res >> 26) == ALC880_MIC_EVENT)
19840 alc680_rec_autoswitch(codec);
19841}
19842
19843static void alc680_inithook(struct hda_codec *codec)
19844{
19845 alc_automute_amp(codec);
19846 alc680_rec_autoswitch(codec);
19847}
19848
d1eb57f4
KY
19849/* create input playback/capture controls for the given pin */
19850static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19851 const char *ctlname, int idx)
19852{
19853 hda_nid_t dac;
19854 int err;
19855
19856 switch (nid) {
19857 case 0x14:
19858 dac = 0x02;
19859 break;
19860 case 0x15:
19861 dac = 0x03;
19862 break;
19863 case 0x16:
19864 dac = 0x04;
19865 break;
19866 default:
19867 return 0;
19868 }
19869 if (spec->multiout.dac_nids[0] != dac &&
19870 spec->multiout.dac_nids[1] != dac) {
19871 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19872 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19873 HDA_OUTPUT));
19874 if (err < 0)
19875 return err;
19876
19877 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19878 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19879
19880 if (err < 0)
19881 return err;
19882 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19883 }
19884
19885 return 0;
19886}
19887
19888/* add playback controls from the parsed DAC table */
19889static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19890 const struct auto_pin_cfg *cfg)
19891{
19892 hda_nid_t nid;
19893 int err;
19894
19895 spec->multiout.dac_nids = spec->private_dac_nids;
19896
19897 nid = cfg->line_out_pins[0];
19898 if (nid) {
19899 const char *name;
19900 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19901 name = "Speaker";
19902 else
19903 name = "Front";
19904 err = alc680_new_analog_output(spec, nid, name, 0);
19905 if (err < 0)
19906 return err;
19907 }
19908
19909 nid = cfg->speaker_pins[0];
19910 if (nid) {
19911 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19912 if (err < 0)
19913 return err;
19914 }
19915 nid = cfg->hp_pins[0];
19916 if (nid) {
19917 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19918 if (err < 0)
19919 return err;
19920 }
19921
19922 return 0;
19923}
19924
19925static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19926 hda_nid_t nid, int pin_type)
19927{
19928 alc_set_pin_output(codec, nid, pin_type);
19929}
19930
19931static void alc680_auto_init_multi_out(struct hda_codec *codec)
19932{
19933 struct alc_spec *spec = codec->spec;
19934 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19935 if (nid) {
19936 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19937 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19938 }
19939}
19940
19941static void alc680_auto_init_hp_out(struct hda_codec *codec)
19942{
19943 struct alc_spec *spec = codec->spec;
19944 hda_nid_t pin;
19945
19946 pin = spec->autocfg.hp_pins[0];
19947 if (pin)
19948 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19949 pin = spec->autocfg.speaker_pins[0];
19950 if (pin)
19951 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19952}
19953
19954/* pcm configuration: identical with ALC880 */
19955#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19956#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19957#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19958#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19959#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19960
19961/*
19962 * BIOS auto configuration
19963 */
19964static int alc680_parse_auto_config(struct hda_codec *codec)
19965{
19966 struct alc_spec *spec = codec->spec;
19967 int err;
19968 static hda_nid_t alc680_ignore[] = { 0 };
19969
19970 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19971 alc680_ignore);
19972 if (err < 0)
19973 return err;
c69aefab 19974
d1eb57f4
KY
19975 if (!spec->autocfg.line_outs) {
19976 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19977 spec->multiout.max_channels = 2;
19978 spec->no_analog = 1;
19979 goto dig_only;
19980 }
19981 return 0; /* can't find valid BIOS pin config */
19982 }
19983 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19984 if (err < 0)
19985 return err;
19986
19987 spec->multiout.max_channels = 2;
19988
19989 dig_only:
19990 /* digital only support output */
757899ac 19991 alc_auto_parse_digital(codec);
d1eb57f4
KY
19992 if (spec->kctls.list)
19993 add_mixer(spec, spec->kctls.list);
19994
19995 add_verb(spec, alc680_init_verbs);
d1eb57f4
KY
19996
19997 err = alc_auto_add_mic_boost(codec);
19998 if (err < 0)
19999 return err;
20000
20001 return 1;
20002}
20003
20004#define alc680_auto_init_analog_input alc882_auto_init_analog_input
20005
20006/* init callback for auto-configuration model -- overriding the default init */
20007static void alc680_auto_init(struct hda_codec *codec)
20008{
20009 struct alc_spec *spec = codec->spec;
20010 alc680_auto_init_multi_out(codec);
20011 alc680_auto_init_hp_out(codec);
20012 alc680_auto_init_analog_input(codec);
757899ac 20013 alc_auto_init_digital(codec);
d1eb57f4
KY
20014 if (spec->unsol_event)
20015 alc_inithook(codec);
20016}
20017
20018/*
20019 * configuration and preset
20020 */
ea734963 20021static const char * const alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
20022 [ALC680_BASE] = "base",
20023 [ALC680_AUTO] = "auto",
d1eb57f4
KY
20024};
20025
20026static struct snd_pci_quirk alc680_cfg_tbl[] = {
20027 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
20028 {}
20029};
20030
20031static struct alc_config_preset alc680_presets[] = {
20032 [ALC680_BASE] = {
20033 .mixers = { alc680_base_mixer },
c69aefab 20034 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
20035 .init_verbs = { alc680_init_verbs },
20036 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
20037 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
20038 .dig_out_nid = ALC680_DIGOUT_NID,
20039 .num_channel_mode = ARRAY_SIZE(alc680_modes),
20040 .channel_mode = alc680_modes,
c69aefab
KY
20041 .unsol_event = alc680_unsol_event,
20042 .setup = alc680_base_setup,
20043 .init_hook = alc680_inithook,
20044
d1eb57f4
KY
20045 },
20046};
20047
20048static int patch_alc680(struct hda_codec *codec)
20049{
20050 struct alc_spec *spec;
20051 int board_config;
20052 int err;
20053
20054 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
20055 if (spec == NULL)
20056 return -ENOMEM;
20057
20058 codec->spec = spec;
20059
20060 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
20061 alc680_models,
20062 alc680_cfg_tbl);
20063
20064 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
20065 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
20066 codec->chip_name);
20067 board_config = ALC680_AUTO;
20068 }
20069
20070 if (board_config == ALC680_AUTO) {
20071 /* automatic parse from the BIOS config */
20072 err = alc680_parse_auto_config(codec);
20073 if (err < 0) {
20074 alc_free(codec);
20075 return err;
20076 } else if (!err) {
20077 printk(KERN_INFO
20078 "hda_codec: Cannot set up configuration "
20079 "from BIOS. Using base mode...\n");
20080 board_config = ALC680_BASE;
20081 }
20082 }
20083
20084 if (board_config != ALC680_AUTO)
20085 setup_preset(codec, &alc680_presets[board_config]);
20086
20087 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 20088 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 20089 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 20090 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
20091
20092 if (!spec->adc_nids) {
20093 spec->adc_nids = alc680_adc_nids;
20094 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20095 }
20096
20097 if (!spec->cap_mixer)
20098 set_capture_mixer(codec);
20099
20100 spec->vmaster_nid = 0x02;
20101
20102 codec->patch_ops = alc_patch_ops;
20103 if (board_config == ALC680_AUTO)
20104 spec->init_hook = alc680_auto_init;
20105
20106 return 0;
20107}
20108
1da177e4
LT
20109/*
20110 * patch entries
20111 */
1289e9e8 20112static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 20113 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 20114 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 20115 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 20116 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 20117 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 20118 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 20119 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 20120 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 20121 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 20122 .patch = patch_alc861 },
f32610ed
JS
20123 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20124 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20125 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 20126 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 20127 .patch = patch_alc882 },
bc9f98a9
KY
20128 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20129 .patch = patch_alc662 },
6dda9f4a 20130 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 20131 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 20132 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 20133 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 20134 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 20135 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 20136 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 20137 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 20138 .patch = patch_alc882 },
cb308f97 20139 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 20140 .patch = patch_alc882 },
df694daa 20141 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
01e0f137 20142 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
4442608d 20143 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 20144 .patch = patch_alc882 },
274693f3 20145 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 20146 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 20147 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
20148 {} /* terminator */
20149};
1289e9e8
TI
20150
20151MODULE_ALIAS("snd-hda-codec-id:10ec*");
20152
20153MODULE_LICENSE("GPL");
20154MODULE_DESCRIPTION("Realtek HD-audio codec");
20155
20156static struct hda_codec_preset_list realtek_list = {
20157 .preset = snd_hda_preset_realtek,
20158 .owner = THIS_MODULE,
20159};
20160
20161static int __init patch_realtek_init(void)
20162{
20163 return snd_hda_add_codec_preset(&realtek_list);
20164}
20165
20166static void __exit patch_realtek_exit(void)
20167{
20168 snd_hda_delete_codec_preset(&realtek_list);
20169}
20170
20171module_init(patch_realtek_init)
20172module_exit(patch_realtek_exit)
This page took 2.715215 seconds and 5 git commands to generate.