]> bbs.cooldavid.org Git - net-next-2.6.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Fix capture widget for ALC269vb and co
[net-next-2.6.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
9ad0e496 31#include <sound/jack.h>
1da177e4
LT
32#include "hda_codec.h"
33#include "hda_local.h"
680cd536 34#include "hda_beep.h"
1da177e4 35
ccc656ce
KY
36#define ALC880_FRONT_EVENT 0x01
37#define ALC880_DCVOL_EVENT 0x02
38#define ALC880_HP_EVENT 0x04
39#define ALC880_MIC_EVENT 0x08
1da177e4
LT
40
41/* ALC880 board config type */
42enum {
1da177e4
LT
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
dfc0ff62 48 ALC880_Z71V,
b6482d48 49 ALC880_6ST,
16ded525
TI
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
df694daa 55 ALC880_ASUS_DIG2,
2cf9f0fc 56 ALC880_FUJITSU,
16ded525 57 ALC880_UNIWILL_DIG,
ccc656ce
KY
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
df694daa
KY
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
ae6b813a 62 ALC880_LG,
d681518a 63 ALC880_LG_LW,
df99cd33 64 ALC880_MEDION_RIM,
e9edcee0
TI
65#ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67#endif
df694daa 68 ALC880_AUTO,
16ded525
TI
69 ALC880_MODEL_LAST /* last tag */
70};
71
72/* ALC260 models */
73enum {
74 ALC260_BASIC,
75 ALC260_HP,
3f878308 76 ALC260_HP_DC7600,
df694daa
KY
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
0bfc90e9 79 ALC260_ACER,
bc9f98a9
KY
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
cc959489 82 ALC260_FAVORIT100,
7cf51e48
JW
83#ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85#endif
df694daa 86 ALC260_AUTO,
16ded525 87 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
88};
89
df694daa
KY
90/* ALC262 models */
91enum {
92 ALC262_BASIC,
ccc656ce
KY
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
834be88d 95 ALC262_FUJITSU,
9c7f852e 96 ALC262_HP_BPC,
cd7509a4
KY
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
66d2a9d6 99 ALC262_HP_TC_T5735,
8c427226 100 ALC262_HP_RP5700,
304dcaac 101 ALC262_BENQ_ED8,
272a527c 102 ALC262_SONY_ASSAMD,
83c34218 103 ALC262_BENQ_T31,
f651b50b 104 ALC262_ULTRA,
0e31daf7 105 ALC262_LENOVO_3000,
e8f9ae2a 106 ALC262_NEC,
4e555fe5 107 ALC262_TOSHIBA_S06,
9f99a638 108 ALC262_TOSHIBA_RX1,
ba340e82 109 ALC262_TYAN,
df694daa
KY
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
112};
113
a361d84b
KY
114/* ALC268 models */
115enum {
eb5a6621 116 ALC267_QUANTA_IL1,
a361d84b 117 ALC268_3ST,
d1a991a6 118 ALC268_TOSHIBA,
d273809e 119 ALC268_ACER,
c238b4f4 120 ALC268_ACER_DMIC,
8ef355da 121 ALC268_ACER_ASPIRE_ONE,
3866f0b0 122 ALC268_DELL,
f12462c5 123 ALC268_ZEPTO,
86c53bd2
JW
124#ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126#endif
a361d84b
KY
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
129};
130
f6a92248
KY
131/* ALC269 models */
132enum {
133 ALC269_BASIC,
60db6b53 134 ALC269_QUANTA_FL1,
84898e87
KY
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
26f5df26 139 ALC269_FUJITSU,
64154835 140 ALC269_LIFEBOOK,
fe3eb0a7 141 ALC271_ACER,
f6a92248
KY
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
144};
145
df694daa
KY
146/* ALC861 models */
147enum {
148 ALC861_3ST,
9c7f852e 149 ALC660_3ST,
df694daa
KY
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
22309c3e 152 ALC861_UNIWILL_M31,
a53d1aec 153 ALC861_TOSHIBA,
7cdbff94 154 ALC861_ASUS,
56bb0cab 155 ALC861_ASUS_LAPTOP,
df694daa
KY
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
158};
159
f32610ed
JS
160/* ALC861-VD models */
161enum {
162 ALC660VD_3ST,
6963f84c 163 ALC660VD_3ST_DIG,
13c94744 164 ALC660VD_ASUS_V1S,
f32610ed
JS
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
bdd148a3 168 ALC861VD_LENOVO,
272a527c 169 ALC861VD_DALLAS,
d1a991a6 170 ALC861VD_HP,
f32610ed
JS
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
173};
174
bc9f98a9
KY
175/* ALC662 models */
176enum {
177 ALC662_3ST_2ch_DIG,
178 ALC662_3ST_6ch_DIG,
179 ALC662_3ST_6ch,
180 ALC662_5ST_DIG,
181 ALC662_LENOVO_101E,
291702f0 182 ALC662_ASUS_EEEPC_P701,
8c427226 183 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
f1d4e28b
KY
188 ALC662_ECS,
189 ALC663_ASUS_MODE1,
190 ALC662_ASUS_MODE2,
191 ALC663_ASUS_MODE3,
192 ALC663_ASUS_MODE4,
193 ALC663_ASUS_MODE5,
194 ALC663_ASUS_MODE6,
ebb83eeb
KY
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
622e84cd
KY
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
9541ba1d 199 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
202};
203
df694daa
KY
204/* ALC882 models */
205enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
4b146cb0 208 ALC882_ARIMA,
bdd148a3 209 ALC882_W2JC,
272a527c
KY
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
914759b7 212 ALC882_ASUS_A7M,
9102cd1c 213 ALC885_MACPRO,
76e6f5a9 214 ALC885_MBA21,
87350ad0 215 ALC885_MBP3,
41d5545d 216 ALC885_MB5,
e458b1fa 217 ALC885_MACMINI3,
c54728d8 218 ALC885_IMAC24,
4b7e1803 219 ALC885_IMAC91,
9c7f852e
TI
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
ccc656ce
KY
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
64a8be74 226 ALC883_TARGA_8ch_DIG,
bab282b9 227 ALC883_ACER,
2880a867 228 ALC883_ACER_ASPIRE,
5b2d1eca 229 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 230 ALC888_ACER_ASPIRE_6530G,
3b315d70 231 ALC888_ACER_ASPIRE_8930G,
fc86f954 232 ALC888_ACER_ASPIRE_7730G,
c07584c8 233 ALC883_MEDION,
ea1fb29a 234 ALC883_MEDION_MD2,
7ad7b218 235 ALC883_MEDION_WIM2160,
b373bdeb 236 ALC883_LAPTOP_EAPD,
bc9f98a9 237 ALC883_LENOVO_101E_2ch,
272a527c 238 ALC883_LENOVO_NB0763,
189609ae 239 ALC888_LENOVO_MS7195_DIG,
e2757d5e 240 ALC888_LENOVO_SKY,
ea1fb29a 241 ALC883_HAIER_W66,
4723c022 242 ALC888_3ST_HP,
5795b9e6 243 ALC888_6ST_DELL,
a8848bd6 244 ALC883_MITAC,
a65cc60f 245 ALC883_CLEVO_M540R,
0c4cc443 246 ALC883_CLEVO_M720,
fb97dc67 247 ALC883_FUJITSU_PI2515,
ef8ef5fb 248 ALC888_FUJITSU_XA3530,
17bba1b7 249 ALC883_3ST_6ch_INTEL,
87a8c370
JK
250 ALC889A_INTEL,
251 ALC889_INTEL,
e2757d5e
KY
252 ALC888_ASUS_M90V,
253 ALC888_ASUS_EEE1601,
eb4c41d3 254 ALC889A_MB31,
3ab90935 255 ALC1200_ASUS_P5Q,
3e1647c5 256 ALC883_SONY_VAIO_TT,
4953550a
TI
257 ALC882_AUTO,
258 ALC882_MODEL_LAST,
9c7f852e
TI
259};
260
d4a86d81
TI
261/* ALC680 models */
262enum {
263 ALC680_BASE,
264 ALC680_AUTO,
265 ALC680_MODEL_LAST,
266};
267
df694daa
KY
268/* for GPIO Poll */
269#define GPIO_MASK 0x03
270
4a79ba34
TI
271/* extra amp-initialization sequence types */
272enum {
273 ALC_INIT_NONE,
274 ALC_INIT_DEFAULT,
275 ALC_INIT_GPIO1,
276 ALC_INIT_GPIO2,
277 ALC_INIT_GPIO3,
278};
279
6c819492
TI
280struct alc_mic_route {
281 hda_nid_t pin;
282 unsigned char mux_idx;
283 unsigned char amix_idx;
284};
285
9ad0e496
KY
286struct alc_jack {
287 hda_nid_t nid;
288 int type;
289 struct snd_jack *jack;
290};
291
6c819492
TI
292#define MUX_IDX_UNDEF ((unsigned char)-1)
293
da00c244
KY
294struct alc_customize_define {
295 unsigned int sku_cfg;
296 unsigned char port_connectivity;
297 unsigned char check_sum;
298 unsigned char customization;
299 unsigned char external_amp;
300 unsigned int enable_pcbeep:1;
301 unsigned int platform_type:1;
302 unsigned int swap:1;
303 unsigned int override:1;
304};
305
1da177e4
LT
306struct alc_spec {
307 /* codec parameterization */
df694daa 308 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 309 unsigned int num_mixers;
f9e336f6 310 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 311 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 312
2d9c6482 313 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
314 * don't forget NULL
315 * termination!
e9edcee0
TI
316 */
317 unsigned int num_init_verbs;
1da177e4 318
aa563af7 319 char stream_name_analog[32]; /* analog PCM stream */
1da177e4
LT
320 struct hda_pcm_stream *stream_analog_playback;
321 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
322 struct hda_pcm_stream *stream_analog_alt_playback;
323 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 324
aa563af7 325 char stream_name_digital[32]; /* digital PCM stream */
1da177e4
LT
326 struct hda_pcm_stream *stream_digital_playback;
327 struct hda_pcm_stream *stream_digital_capture;
328
329 /* playback */
16ded525
TI
330 struct hda_multi_out multiout; /* playback set-up
331 * max_channels, dacs must be set
332 * dig_out_nid and hp_nid are optional
333 */
6330079f 334 hda_nid_t alt_dac_nid;
6a05ac4a 335 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 336 int dig_out_type;
1da177e4
LT
337
338 /* capture */
339 unsigned int num_adc_nids;
340 hda_nid_t *adc_nids;
e1406348 341 hda_nid_t *capsrc_nids;
16ded525 342 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4 343
840b64c0
TI
344 /* capture setup for dynamic dual-adc switch */
345 unsigned int cur_adc_idx;
346 hda_nid_t cur_adc;
347 unsigned int cur_adc_stream_tag;
348 unsigned int cur_adc_format;
349
1da177e4 350 /* capture source */
a1e8d2da 351 unsigned int num_mux_defs;
1da177e4
LT
352 const struct hda_input_mux *input_mux;
353 unsigned int cur_mux[3];
6c819492
TI
354 struct alc_mic_route ext_mic;
355 struct alc_mic_route int_mic;
1da177e4
LT
356
357 /* channel model */
d2a6d7dc 358 const struct hda_channel_mode *channel_mode;
1da177e4 359 int num_channel_mode;
4e195a7b 360 int need_dac_fix;
3b315d70
HM
361 int const_channel_count;
362 int ext_channel_count;
1da177e4
LT
363
364 /* PCM information */
4c5186ed 365 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 366
9ad0e496
KY
367 /* jack detection */
368 struct snd_array jacks;
369
e9edcee0
TI
370 /* dynamic controls, init_verbs and input_mux */
371 struct auto_pin_cfg autocfg;
da00c244 372 struct alc_customize_define cdefine;
603c4019 373 struct snd_array kctls;
61b9b9b1 374 struct hda_input_mux private_imux[3];
41923e44 375 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
376 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
377 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 378
ae6b813a
TI
379 /* hooks */
380 void (*init_hook)(struct hda_codec *codec);
381 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 382#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 383 void (*power_hook)(struct hda_codec *codec);
f5de24b0 384#endif
ae6b813a 385
834be88d
TI
386 /* for pin sensing */
387 unsigned int sense_updated: 1;
388 unsigned int jack_present: 1;
bec15c3a 389 unsigned int master_sw: 1;
6c819492 390 unsigned int auto_mic:1;
cb53c626 391
e64f14f4
TI
392 /* other flags */
393 unsigned int no_analog :1; /* digital I/O only */
840b64c0 394 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
4a79ba34 395 int init_amp;
d433a678 396 int codec_variant; /* flag for other variants */
e64f14f4 397
2134ea4f
TI
398 /* for virtual master */
399 hda_nid_t vmaster_nid;
cb53c626
TI
400#ifdef CONFIG_SND_HDA_POWER_SAVE
401 struct hda_loopback_check loopback;
402#endif
2c3bf9ab
TI
403
404 /* for PLL fix */
405 hda_nid_t pll_nid;
406 unsigned int pll_coef_idx, pll_coef_bit;
df694daa
KY
407};
408
409/*
410 * configuration template - to be copied to the spec instance
411 */
412struct alc_config_preset {
9c7f852e
TI
413 struct snd_kcontrol_new *mixers[5]; /* should be identical size
414 * with spec
415 */
f9e336f6 416 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
417 const struct hda_verb *init_verbs[5];
418 unsigned int num_dacs;
419 hda_nid_t *dac_nids;
420 hda_nid_t dig_out_nid; /* optional */
421 hda_nid_t hp_nid; /* optional */
b25c9da1 422 hda_nid_t *slave_dig_outs;
df694daa
KY
423 unsigned int num_adc_nids;
424 hda_nid_t *adc_nids;
e1406348 425 hda_nid_t *capsrc_nids;
df694daa
KY
426 hda_nid_t dig_in_nid;
427 unsigned int num_channel_mode;
428 const struct hda_channel_mode *channel_mode;
4e195a7b 429 int need_dac_fix;
3b315d70 430 int const_channel_count;
a1e8d2da 431 unsigned int num_mux_defs;
df694daa 432 const struct hda_input_mux *input_mux;
ae6b813a 433 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 434 void (*setup)(struct hda_codec *);
ae6b813a 435 void (*init_hook)(struct hda_codec *);
cb53c626
TI
436#ifdef CONFIG_SND_HDA_POWER_SAVE
437 struct hda_amp_list *loopbacks;
c97259df 438 void (*power_hook)(struct hda_codec *codec);
cb53c626 439#endif
1da177e4
LT
440};
441
1da177e4
LT
442
443/*
444 * input MUX handling
445 */
9c7f852e
TI
446static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
447 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
448{
449 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
450 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
451 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
452 if (mux_idx >= spec->num_mux_defs)
453 mux_idx = 0;
5311114d
TI
454 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
455 mux_idx = 0;
a1e8d2da 456 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
457}
458
9c7f852e
TI
459static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
460 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
461{
462 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
463 struct alc_spec *spec = codec->spec;
464 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
465
466 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
467 return 0;
468}
469
9c7f852e
TI
470static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
471 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
472{
473 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
474 struct alc_spec *spec = codec->spec;
cd896c33 475 const struct hda_input_mux *imux;
1da177e4 476 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 477 unsigned int mux_idx;
e1406348
TI
478 hda_nid_t nid = spec->capsrc_nids ?
479 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 480 unsigned int type;
1da177e4 481
cd896c33
TI
482 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
483 imux = &spec->input_mux[mux_idx];
5311114d
TI
484 if (!imux->num_items && mux_idx > 0)
485 imux = &spec->input_mux[0];
cd896c33 486
a22d543a 487 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 488 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
489 /* Matrix-mixer style (e.g. ALC882) */
490 unsigned int *cur_val = &spec->cur_mux[adc_idx];
491 unsigned int i, idx;
492
493 idx = ucontrol->value.enumerated.item[0];
494 if (idx >= imux->num_items)
495 idx = imux->num_items - 1;
496 if (*cur_val == idx)
497 return 0;
498 for (i = 0; i < imux->num_items; i++) {
499 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
500 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
501 imux->items[i].index,
502 HDA_AMP_MUTE, v);
503 }
504 *cur_val = idx;
505 return 1;
506 } else {
507 /* MUX style (e.g. ALC880) */
cd896c33 508 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
509 &spec->cur_mux[adc_idx]);
510 }
511}
e9edcee0 512
1da177e4
LT
513/*
514 * channel mode setting
515 */
9c7f852e
TI
516static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
517 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
518{
519 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
520 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
521 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
522 spec->num_channel_mode);
1da177e4
LT
523}
524
9c7f852e
TI
525static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
526 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
527{
528 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
529 struct alc_spec *spec = codec->spec;
d2a6d7dc 530 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 531 spec->num_channel_mode,
3b315d70 532 spec->ext_channel_count);
1da177e4
LT
533}
534
9c7f852e
TI
535static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
536 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
537{
538 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
539 struct alc_spec *spec = codec->spec;
4e195a7b
TI
540 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
541 spec->num_channel_mode,
3b315d70
HM
542 &spec->ext_channel_count);
543 if (err >= 0 && !spec->const_channel_count) {
544 spec->multiout.max_channels = spec->ext_channel_count;
545 if (spec->need_dac_fix)
546 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
547 }
4e195a7b 548 return err;
1da177e4
LT
549}
550
a9430dd8 551/*
4c5186ed 552 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 553 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
554 * being part of a format specifier. Maximum allowed length of a value is
555 * 63 characters plus NULL terminator.
7cf51e48
JW
556 *
557 * Note: some retasking pin complexes seem to ignore requests for input
558 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
559 * are requested. Therefore order this list so that this behaviour will not
560 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
561 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
562 * March 2006.
4c5186ed
JW
563 */
564static char *alc_pin_mode_names[] = {
7cf51e48
JW
565 "Mic 50pc bias", "Mic 80pc bias",
566 "Line in", "Line out", "Headphone out",
4c5186ed
JW
567};
568static unsigned char alc_pin_mode_values[] = {
7cf51e48 569 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
570};
571/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
572 * in the pin being assumed to be exclusively an input or an output pin. In
573 * addition, "input" pins may or may not process the mic bias option
574 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
575 * accept requests for bias as of chip versions up to March 2006) and/or
576 * wiring in the computer.
a9430dd8 577 */
a1e8d2da
JW
578#define ALC_PIN_DIR_IN 0x00
579#define ALC_PIN_DIR_OUT 0x01
580#define ALC_PIN_DIR_INOUT 0x02
581#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
582#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 583
ea1fb29a 584/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
585 * For each direction the minimum and maximum values are given.
586 */
a1e8d2da 587static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
588 { 0, 2 }, /* ALC_PIN_DIR_IN */
589 { 3, 4 }, /* ALC_PIN_DIR_OUT */
590 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
591 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
592 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
593};
594#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
595#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
596#define alc_pin_mode_n_items(_dir) \
597 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
598
9c7f852e
TI
599static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
600 struct snd_ctl_elem_info *uinfo)
a9430dd8 601{
4c5186ed
JW
602 unsigned int item_num = uinfo->value.enumerated.item;
603 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
604
605 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 606 uinfo->count = 1;
4c5186ed
JW
607 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
608
609 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
610 item_num = alc_pin_mode_min(dir);
611 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
612 return 0;
613}
614
9c7f852e
TI
615static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
616 struct snd_ctl_elem_value *ucontrol)
a9430dd8 617{
4c5186ed 618 unsigned int i;
a9430dd8
JW
619 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
620 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 621 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 622 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
623 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
624 AC_VERB_GET_PIN_WIDGET_CONTROL,
625 0x00);
a9430dd8 626
4c5186ed
JW
627 /* Find enumerated value for current pinctl setting */
628 i = alc_pin_mode_min(dir);
4b35d2ca 629 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 630 i++;
9c7f852e 631 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
632 return 0;
633}
634
9c7f852e
TI
635static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
636 struct snd_ctl_elem_value *ucontrol)
a9430dd8 637{
4c5186ed 638 signed int change;
a9430dd8
JW
639 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
640 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
641 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
642 long val = *ucontrol->value.integer.value;
9c7f852e
TI
643 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
644 AC_VERB_GET_PIN_WIDGET_CONTROL,
645 0x00);
a9430dd8 646
f12ab1e0 647 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
648 val = alc_pin_mode_min(dir);
649
650 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
651 if (change) {
652 /* Set pin mode to that requested */
82beb8fd
TI
653 snd_hda_codec_write_cache(codec, nid, 0,
654 AC_VERB_SET_PIN_WIDGET_CONTROL,
655 alc_pin_mode_values[val]);
cdcd9268 656
ea1fb29a 657 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
658 * for the requested pin mode. Enum values of 2 or less are
659 * input modes.
660 *
661 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
662 * reduces noise slightly (particularly on input) so we'll
663 * do it. However, having both input and output buffers
664 * enabled simultaneously doesn't seem to be problematic if
665 * this turns out to be necessary in the future.
cdcd9268
JW
666 */
667 if (val <= 2) {
47fd830a
TI
668 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
669 HDA_AMP_MUTE, HDA_AMP_MUTE);
670 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
671 HDA_AMP_MUTE, 0);
cdcd9268 672 } else {
47fd830a
TI
673 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
674 HDA_AMP_MUTE, HDA_AMP_MUTE);
675 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
676 HDA_AMP_MUTE, 0);
cdcd9268
JW
677 }
678 }
a9430dd8
JW
679 return change;
680}
681
4c5186ed 682#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 683 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 684 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
685 .info = alc_pin_mode_info, \
686 .get = alc_pin_mode_get, \
687 .put = alc_pin_mode_put, \
688 .private_value = nid | (dir<<16) }
df694daa 689
5c8f858d
JW
690/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
691 * together using a mask with more than one bit set. This control is
692 * currently used only by the ALC260 test model. At this stage they are not
693 * needed for any "production" models.
694 */
695#ifdef CONFIG_SND_DEBUG
a5ce8890 696#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 697
9c7f852e
TI
698static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
699 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
700{
701 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
702 hda_nid_t nid = kcontrol->private_value & 0xffff;
703 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
704 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
705 unsigned int val = snd_hda_codec_read(codec, nid, 0,
706 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
707
708 *valp = (val & mask) != 0;
709 return 0;
710}
9c7f852e
TI
711static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
712 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
713{
714 signed int change;
715 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
716 hda_nid_t nid = kcontrol->private_value & 0xffff;
717 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
718 long val = *ucontrol->value.integer.value;
9c7f852e
TI
719 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
720 AC_VERB_GET_GPIO_DATA,
721 0x00);
5c8f858d
JW
722
723 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
724 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
725 if (val == 0)
5c8f858d
JW
726 gpio_data &= ~mask;
727 else
728 gpio_data |= mask;
82beb8fd
TI
729 snd_hda_codec_write_cache(codec, nid, 0,
730 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
731
732 return change;
733}
734#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
735 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 736 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
737 .info = alc_gpio_data_info, \
738 .get = alc_gpio_data_get, \
739 .put = alc_gpio_data_put, \
740 .private_value = nid | (mask<<16) }
741#endif /* CONFIG_SND_DEBUG */
742
92621f13
JW
743/* A switch control to allow the enabling of the digital IO pins on the
744 * ALC260. This is incredibly simplistic; the intention of this control is
745 * to provide something in the test model allowing digital outputs to be
746 * identified if present. If models are found which can utilise these
747 * outputs a more complete mixer control can be devised for those models if
748 * necessary.
749 */
750#ifdef CONFIG_SND_DEBUG
a5ce8890 751#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 752
9c7f852e
TI
753static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
754 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
755{
756 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
757 hda_nid_t nid = kcontrol->private_value & 0xffff;
758 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
759 long *valp = ucontrol->value.integer.value;
9c7f852e 760 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 761 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
762
763 *valp = (val & mask) != 0;
764 return 0;
765}
9c7f852e
TI
766static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
767 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
768{
769 signed int change;
770 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
771 hda_nid_t nid = kcontrol->private_value & 0xffff;
772 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
773 long val = *ucontrol->value.integer.value;
9c7f852e 774 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 775 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 776 0x00);
92621f13
JW
777
778 /* Set/unset the masked control bit(s) as needed */
9c7f852e 779 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
780 if (val==0)
781 ctrl_data &= ~mask;
782 else
783 ctrl_data |= mask;
82beb8fd
TI
784 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
785 ctrl_data);
92621f13
JW
786
787 return change;
788}
789#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
790 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 791 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
792 .info = alc_spdif_ctrl_info, \
793 .get = alc_spdif_ctrl_get, \
794 .put = alc_spdif_ctrl_put, \
795 .private_value = nid | (mask<<16) }
796#endif /* CONFIG_SND_DEBUG */
797
f8225f6d
JW
798/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
799 * Again, this is only used in the ALC26x test models to help identify when
800 * the EAPD line must be asserted for features to work.
801 */
802#ifdef CONFIG_SND_DEBUG
803#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
804
805static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
806 struct snd_ctl_elem_value *ucontrol)
807{
808 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
809 hda_nid_t nid = kcontrol->private_value & 0xffff;
810 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
811 long *valp = ucontrol->value.integer.value;
812 unsigned int val = snd_hda_codec_read(codec, nid, 0,
813 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
814
815 *valp = (val & mask) != 0;
816 return 0;
817}
818
819static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
820 struct snd_ctl_elem_value *ucontrol)
821{
822 int change;
823 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
824 hda_nid_t nid = kcontrol->private_value & 0xffff;
825 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
826 long val = *ucontrol->value.integer.value;
827 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
828 AC_VERB_GET_EAPD_BTLENABLE,
829 0x00);
830
831 /* Set/unset the masked control bit(s) as needed */
832 change = (!val ? 0 : mask) != (ctrl_data & mask);
833 if (!val)
834 ctrl_data &= ~mask;
835 else
836 ctrl_data |= mask;
837 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
838 ctrl_data);
839
840 return change;
841}
842
843#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
844 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 845 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
846 .info = alc_eapd_ctrl_info, \
847 .get = alc_eapd_ctrl_get, \
848 .put = alc_eapd_ctrl_put, \
849 .private_value = nid | (mask<<16) }
850#endif /* CONFIG_SND_DEBUG */
851
23f0c048
TI
852/*
853 * set up the input pin config (depending on the given auto-pin type)
854 */
855static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
856 int auto_pin_type)
857{
858 unsigned int val = PIN_IN;
859
86e2959a 860 if (auto_pin_type == AUTO_PIN_MIC) {
23f0c048 861 unsigned int pincap;
954a29c8
TI
862 unsigned int oldval;
863 oldval = snd_hda_codec_read(codec, nid, 0,
864 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1327a32b 865 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048 866 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
954a29c8
TI
867 /* if the default pin setup is vref50, we give it priority */
868 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
23f0c048 869 val = PIN_VREF80;
461c6c3a
TI
870 else if (pincap & AC_PINCAP_VREF_50)
871 val = PIN_VREF50;
872 else if (pincap & AC_PINCAP_VREF_100)
873 val = PIN_VREF100;
874 else if (pincap & AC_PINCAP_VREF_GRD)
875 val = PIN_VREFGRD;
23f0c048
TI
876 }
877 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
878}
879
f6837bbd
TI
880static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
881{
882 struct alc_spec *spec = codec->spec;
883 struct auto_pin_cfg *cfg = &spec->autocfg;
884
885 if (!cfg->line_outs) {
886 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
887 cfg->line_out_pins[cfg->line_outs])
888 cfg->line_outs++;
889 }
890 if (!cfg->speaker_outs) {
891 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
892 cfg->speaker_pins[cfg->speaker_outs])
893 cfg->speaker_outs++;
894 }
895 if (!cfg->hp_outs) {
896 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
897 cfg->hp_pins[cfg->hp_outs])
898 cfg->hp_outs++;
899 }
900}
901
d88897ea
TI
902/*
903 */
904static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
905{
906 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
907 return;
908 spec->mixers[spec->num_mixers++] = mix;
909}
910
911static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
912{
913 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
914 return;
915 spec->init_verbs[spec->num_init_verbs++] = verb;
916}
917
df694daa
KY
918/*
919 * set up from the preset table
920 */
e9c364c0 921static void setup_preset(struct hda_codec *codec,
9c7f852e 922 const struct alc_config_preset *preset)
df694daa 923{
e9c364c0 924 struct alc_spec *spec = codec->spec;
df694daa
KY
925 int i;
926
927 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 928 add_mixer(spec, preset->mixers[i]);
f9e336f6 929 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
930 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
931 i++)
d88897ea 932 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 933
df694daa
KY
934 spec->channel_mode = preset->channel_mode;
935 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 936 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 937 spec->const_channel_count = preset->const_channel_count;
df694daa 938
3b315d70
HM
939 if (preset->const_channel_count)
940 spec->multiout.max_channels = preset->const_channel_count;
941 else
942 spec->multiout.max_channels = spec->channel_mode[0].channels;
943 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
944
945 spec->multiout.num_dacs = preset->num_dacs;
946 spec->multiout.dac_nids = preset->dac_nids;
947 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 948 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 949 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 950
a1e8d2da 951 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 952 if (!spec->num_mux_defs)
a1e8d2da 953 spec->num_mux_defs = 1;
df694daa
KY
954 spec->input_mux = preset->input_mux;
955
956 spec->num_adc_nids = preset->num_adc_nids;
957 spec->adc_nids = preset->adc_nids;
e1406348 958 spec->capsrc_nids = preset->capsrc_nids;
df694daa 959 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
960
961 spec->unsol_event = preset->unsol_event;
962 spec->init_hook = preset->init_hook;
cb53c626 963#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 964 spec->power_hook = preset->power_hook;
cb53c626
TI
965 spec->loopback.amplist = preset->loopbacks;
966#endif
e9c364c0
TI
967
968 if (preset->setup)
969 preset->setup(codec);
f6837bbd
TI
970
971 alc_fixup_autocfg_pin_nums(codec);
df694daa
KY
972}
973
bc9f98a9
KY
974/* Enable GPIO mask and set output */
975static struct hda_verb alc_gpio1_init_verbs[] = {
976 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
977 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
978 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
979 { }
980};
981
982static struct hda_verb alc_gpio2_init_verbs[] = {
983 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
984 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
985 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
986 { }
987};
988
bdd148a3
KY
989static struct hda_verb alc_gpio3_init_verbs[] = {
990 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
991 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
992 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
993 { }
994};
995
2c3bf9ab
TI
996/*
997 * Fix hardware PLL issue
998 * On some codecs, the analog PLL gating control must be off while
999 * the default value is 1.
1000 */
1001static void alc_fix_pll(struct hda_codec *codec)
1002{
1003 struct alc_spec *spec = codec->spec;
1004 unsigned int val;
1005
1006 if (!spec->pll_nid)
1007 return;
1008 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1009 spec->pll_coef_idx);
1010 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1011 AC_VERB_GET_PROC_COEF, 0);
1012 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1013 spec->pll_coef_idx);
1014 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1015 val & ~(1 << spec->pll_coef_bit));
1016}
1017
1018static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1019 unsigned int coef_idx, unsigned int coef_bit)
1020{
1021 struct alc_spec *spec = codec->spec;
1022 spec->pll_nid = nid;
1023 spec->pll_coef_idx = coef_idx;
1024 spec->pll_coef_bit = coef_bit;
1025 alc_fix_pll(codec);
1026}
1027
9ad0e496
KY
1028#ifdef CONFIG_SND_HDA_INPUT_JACK
1029static void alc_free_jack_priv(struct snd_jack *jack)
1030{
1031 struct alc_jack *jacks = jack->private_data;
1032 jacks->nid = 0;
1033 jacks->jack = NULL;
1034}
1035
1036static int alc_add_jack(struct hda_codec *codec,
1037 hda_nid_t nid, int type)
1038{
1039 struct alc_spec *spec;
1040 struct alc_jack *jack;
1041 const char *name;
1042 int err;
1043
1044 spec = codec->spec;
1045 snd_array_init(&spec->jacks, sizeof(*jack), 32);
1046 jack = snd_array_new(&spec->jacks);
1047 if (!jack)
1048 return -ENOMEM;
1049
1050 jack->nid = nid;
1051 jack->type = type;
1052 name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
1053
1054 err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
1055 if (err < 0)
1056 return err;
1057 jack->jack->private_data = jack;
1058 jack->jack->private_free = alc_free_jack_priv;
1059 return 0;
1060}
1061
1062static void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1063{
1064 struct alc_spec *spec = codec->spec;
1065 struct alc_jack *jacks = spec->jacks.list;
1066
1067 if (jacks) {
1068 int i;
1069 for (i = 0; i < spec->jacks.used; i++) {
1070 if (jacks->nid == nid) {
1071 unsigned int present;
1072 present = snd_hda_jack_detect(codec, nid);
1073
1074 present = (present) ? jacks->type : 0;
1075
1076 snd_jack_report(jacks->jack, present);
1077 }
1078 jacks++;
1079 }
1080 }
1081}
1082
1083static int alc_init_jacks(struct hda_codec *codec)
1084{
1085 struct alc_spec *spec = codec->spec;
1086 int err;
1087 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1088 unsigned int mic_nid = spec->ext_mic.pin;
1089
1090 err = alc_add_jack(codec, hp_nid, SND_JACK_HEADPHONE);
1091 if (err < 0)
1092 return err;
1093 alc_report_jack(codec, hp_nid);
1094
1095 err = alc_add_jack(codec, mic_nid, SND_JACK_MICROPHONE);
1096 if (err < 0)
1097 return err;
1098 alc_report_jack(codec, mic_nid);
1099
1100 return 0;
1101}
1102#else
1103static inline void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1104{
1105}
1106
1107static inline int alc_init_jacks(struct hda_codec *codec)
1108{
1109 return 0;
1110}
1111#endif
1112
bb35febd 1113static void alc_automute_speaker(struct hda_codec *codec, int pinctl)
c9b58006
KY
1114{
1115 struct alc_spec *spec = codec->spec;
bb35febd
TI
1116 unsigned int mute;
1117 hda_nid_t nid;
a9fd4f3f 1118 int i;
c9b58006 1119
bb35febd
TI
1120 spec->jack_present = 0;
1121 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1122 nid = spec->autocfg.hp_pins[i];
1123 if (!nid)
1124 break;
1125 if (snd_hda_jack_detect(codec, nid)) {
1126 spec->jack_present = 1;
1127 break;
1128 }
9ad0e496 1129 alc_report_jack(codec, spec->autocfg.hp_pins[i]);
bb35febd
TI
1130 }
1131
1132 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1133 /* Toggle internal speakers muting */
a9fd4f3f
TI
1134 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1135 nid = spec->autocfg.speaker_pins[i];
1136 if (!nid)
1137 break;
bb35febd
TI
1138 if (pinctl) {
1139 snd_hda_codec_write(codec, nid, 0,
a9fd4f3f
TI
1140 AC_VERB_SET_PIN_WIDGET_CONTROL,
1141 spec->jack_present ? 0 : PIN_OUT);
bb35febd
TI
1142 } else {
1143 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1144 HDA_AMP_MUTE, mute);
1145 }
a9fd4f3f 1146 }
c9b58006
KY
1147}
1148
bb35febd
TI
1149static void alc_automute_pin(struct hda_codec *codec)
1150{
1151 alc_automute_speaker(codec, 1);
1152}
1153
6c819492
TI
1154static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1155 hda_nid_t nid)
1156{
1157 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1158 int i, nums;
1159
1160 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1161 for (i = 0; i < nums; i++)
1162 if (conn[i] == nid)
1163 return i;
1164 return -1;
1165}
1166
840b64c0
TI
1167/* switch the current ADC according to the jack state */
1168static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1169{
1170 struct alc_spec *spec = codec->spec;
1171 unsigned int present;
1172 hda_nid_t new_adc;
1173
1174 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1175 if (present)
1176 spec->cur_adc_idx = 1;
1177 else
1178 spec->cur_adc_idx = 0;
1179 new_adc = spec->adc_nids[spec->cur_adc_idx];
1180 if (spec->cur_adc && spec->cur_adc != new_adc) {
1181 /* stream is running, let's swap the current ADC */
f0cea797 1182 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
840b64c0
TI
1183 spec->cur_adc = new_adc;
1184 snd_hda_codec_setup_stream(codec, new_adc,
1185 spec->cur_adc_stream_tag, 0,
1186 spec->cur_adc_format);
1187 }
1188}
1189
7fb0d78f
KY
1190static void alc_mic_automute(struct hda_codec *codec)
1191{
1192 struct alc_spec *spec = codec->spec;
6c819492
TI
1193 struct alc_mic_route *dead, *alive;
1194 unsigned int present, type;
1195 hda_nid_t cap_nid;
1196
b59bdf3b
TI
1197 if (!spec->auto_mic)
1198 return;
6c819492
TI
1199 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1200 return;
1201 if (snd_BUG_ON(!spec->adc_nids))
1202 return;
1203
840b64c0
TI
1204 if (spec->dual_adc_switch) {
1205 alc_dual_mic_adc_auto_switch(codec);
1206 return;
1207 }
1208
6c819492
TI
1209 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1210
864f92be 1211 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1212 if (present) {
1213 alive = &spec->ext_mic;
1214 dead = &spec->int_mic;
1215 } else {
1216 alive = &spec->int_mic;
1217 dead = &spec->ext_mic;
1218 }
1219
6c819492
TI
1220 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1221 if (type == AC_WID_AUD_MIX) {
1222 /* Matrix-mixer style (e.g. ALC882) */
1223 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1224 alive->mux_idx,
1225 HDA_AMP_MUTE, 0);
1226 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1227 dead->mux_idx,
1228 HDA_AMP_MUTE, HDA_AMP_MUTE);
1229 } else {
1230 /* MUX style (e.g. ALC880) */
1231 snd_hda_codec_write_cache(codec, cap_nid, 0,
1232 AC_VERB_SET_CONNECT_SEL,
1233 alive->mux_idx);
1234 }
9ad0e496 1235 alc_report_jack(codec, spec->ext_mic.pin);
6c819492
TI
1236
1237 /* FIXME: analog mixer */
7fb0d78f
KY
1238}
1239
c9b58006
KY
1240/* unsolicited event for HP jack sensing */
1241static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1242{
1243 if (codec->vendor_id == 0x10ec0880)
1244 res >>= 28;
1245 else
1246 res >>= 26;
a9fd4f3f
TI
1247 switch (res) {
1248 case ALC880_HP_EVENT:
1249 alc_automute_pin(codec);
1250 break;
1251 case ALC880_MIC_EVENT:
7fb0d78f 1252 alc_mic_automute(codec);
a9fd4f3f
TI
1253 break;
1254 }
7fb0d78f
KY
1255}
1256
1257static void alc_inithook(struct hda_codec *codec)
1258{
a9fd4f3f 1259 alc_automute_pin(codec);
7fb0d78f 1260 alc_mic_automute(codec);
c9b58006
KY
1261}
1262
f9423e7a
KY
1263/* additional initialization for ALC888 variants */
1264static void alc888_coef_init(struct hda_codec *codec)
1265{
1266 unsigned int tmp;
1267
1268 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1269 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1270 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1271 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1272 /* alc888S-VC */
1273 snd_hda_codec_read(codec, 0x20, 0,
1274 AC_VERB_SET_PROC_COEF, 0x830);
1275 else
1276 /* alc888-VB */
1277 snd_hda_codec_read(codec, 0x20, 0,
1278 AC_VERB_SET_PROC_COEF, 0x3030);
1279}
1280
87a8c370
JK
1281static void alc889_coef_init(struct hda_codec *codec)
1282{
1283 unsigned int tmp;
1284
1285 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1286 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1287 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1288 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1289}
1290
3fb4a508
TI
1291/* turn on/off EAPD control (only if available) */
1292static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1293{
1294 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1295 return;
1296 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1297 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1298 on ? 2 : 0);
1299}
1300
4a79ba34 1301static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1302{
4a79ba34 1303 unsigned int tmp;
bc9f98a9 1304
4a79ba34
TI
1305 switch (type) {
1306 case ALC_INIT_GPIO1:
bc9f98a9
KY
1307 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1308 break;
4a79ba34 1309 case ALC_INIT_GPIO2:
bc9f98a9
KY
1310 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1311 break;
4a79ba34 1312 case ALC_INIT_GPIO3:
bdd148a3
KY
1313 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1314 break;
4a79ba34 1315 case ALC_INIT_DEFAULT:
bdd148a3 1316 switch (codec->vendor_id) {
c9b58006 1317 case 0x10ec0260:
3fb4a508
TI
1318 set_eapd(codec, 0x0f, 1);
1319 set_eapd(codec, 0x10, 1);
c9b58006
KY
1320 break;
1321 case 0x10ec0262:
bdd148a3
KY
1322 case 0x10ec0267:
1323 case 0x10ec0268:
c9b58006 1324 case 0x10ec0269:
3fb4a508 1325 case 0x10ec0270:
c6e8f2da 1326 case 0x10ec0272:
f9423e7a
KY
1327 case 0x10ec0660:
1328 case 0x10ec0662:
1329 case 0x10ec0663:
c9b58006 1330 case 0x10ec0862:
20a3a05d 1331 case 0x10ec0889:
3fb4a508
TI
1332 set_eapd(codec, 0x14, 1);
1333 set_eapd(codec, 0x15, 1);
c9b58006 1334 break;
bdd148a3 1335 }
c9b58006
KY
1336 switch (codec->vendor_id) {
1337 case 0x10ec0260:
1338 snd_hda_codec_write(codec, 0x1a, 0,
1339 AC_VERB_SET_COEF_INDEX, 7);
1340 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1341 AC_VERB_GET_PROC_COEF, 0);
1342 snd_hda_codec_write(codec, 0x1a, 0,
1343 AC_VERB_SET_COEF_INDEX, 7);
1344 snd_hda_codec_write(codec, 0x1a, 0,
1345 AC_VERB_SET_PROC_COEF,
1346 tmp | 0x2010);
1347 break;
1348 case 0x10ec0262:
1349 case 0x10ec0880:
1350 case 0x10ec0882:
1351 case 0x10ec0883:
1352 case 0x10ec0885:
4a5a4c56 1353 case 0x10ec0887:
20a3a05d 1354 case 0x10ec0889:
87a8c370 1355 alc889_coef_init(codec);
c9b58006 1356 break;
f9423e7a 1357 case 0x10ec0888:
4a79ba34 1358 alc888_coef_init(codec);
f9423e7a 1359 break;
0aea778e 1360#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1361 case 0x10ec0267:
1362 case 0x10ec0268:
1363 snd_hda_codec_write(codec, 0x20, 0,
1364 AC_VERB_SET_COEF_INDEX, 7);
1365 tmp = snd_hda_codec_read(codec, 0x20, 0,
1366 AC_VERB_GET_PROC_COEF, 0);
1367 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1368 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1369 snd_hda_codec_write(codec, 0x20, 0,
1370 AC_VERB_SET_PROC_COEF,
1371 tmp | 0x3000);
1372 break;
0aea778e 1373#endif /* XXX */
bc9f98a9 1374 }
4a79ba34
TI
1375 break;
1376 }
1377}
1378
1379static void alc_init_auto_hp(struct hda_codec *codec)
1380{
1381 struct alc_spec *spec = codec->spec;
bb35febd
TI
1382 struct auto_pin_cfg *cfg = &spec->autocfg;
1383 int i;
4a79ba34 1384
bb35febd
TI
1385 if (!cfg->hp_pins[0]) {
1386 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
1387 return;
1388 }
4a79ba34 1389
bb35febd
TI
1390 if (!cfg->speaker_pins[0]) {
1391 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
4a79ba34 1392 return;
bb35febd
TI
1393 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1394 sizeof(cfg->speaker_pins));
1395 cfg->speaker_outs = cfg->line_outs;
1396 }
1397
1398 if (!cfg->hp_pins[0]) {
1399 memcpy(cfg->hp_pins, cfg->line_out_pins,
1400 sizeof(cfg->hp_pins));
1401 cfg->hp_outs = cfg->line_outs;
4a79ba34
TI
1402 }
1403
bb35febd
TI
1404 for (i = 0; i < cfg->hp_outs; i++) {
1405 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1406 cfg->hp_pins[i]);
1407 snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0,
4a79ba34
TI
1408 AC_VERB_SET_UNSOLICITED_ENABLE,
1409 AC_USRSP_EN | ALC880_HP_EVENT);
bb35febd 1410 }
4a79ba34
TI
1411 spec->unsol_event = alc_sku_unsol_event;
1412}
1413
6c819492
TI
1414static void alc_init_auto_mic(struct hda_codec *codec)
1415{
1416 struct alc_spec *spec = codec->spec;
1417 struct auto_pin_cfg *cfg = &spec->autocfg;
1418 hda_nid_t fixed, ext;
1419 int i;
1420
1421 /* there must be only two mic inputs exclusively */
66ceeb6b 1422 for (i = 0; i < cfg->num_inputs; i++)
86e2959a 1423 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN)
6c819492
TI
1424 return;
1425
1426 fixed = ext = 0;
66ceeb6b
TI
1427 for (i = 0; i < cfg->num_inputs; i++) {
1428 hda_nid_t nid = cfg->inputs[i].pin;
6c819492 1429 unsigned int defcfg;
6c819492 1430 defcfg = snd_hda_codec_get_pincfg(codec, nid);
99ae28be
TI
1431 switch (snd_hda_get_input_pin_attr(defcfg)) {
1432 case INPUT_PIN_ATTR_INT:
6c819492
TI
1433 if (fixed)
1434 return; /* already occupied */
1435 fixed = nid;
1436 break;
99ae28be
TI
1437 case INPUT_PIN_ATTR_UNUSED:
1438 return; /* invalid entry */
1439 default:
6c819492
TI
1440 if (ext)
1441 return; /* already occupied */
1442 ext = nid;
1443 break;
6c819492
TI
1444 }
1445 }
eaa9b3a7
TI
1446 if (!ext || !fixed)
1447 return;
6c819492
TI
1448 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1449 return; /* no unsol support */
1450 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1451 ext, fixed);
1452 spec->ext_mic.pin = ext;
1453 spec->int_mic.pin = fixed;
1454 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1455 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1456 spec->auto_mic = 1;
1457 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1458 AC_VERB_SET_UNSOLICITED_ENABLE,
1459 AC_USRSP_EN | ALC880_MIC_EVENT);
1460 spec->unsol_event = alc_sku_unsol_event;
1461}
1462
da00c244
KY
1463static int alc_auto_parse_customize_define(struct hda_codec *codec)
1464{
1465 unsigned int ass, tmp, i;
7fb56223 1466 unsigned nid = 0;
da00c244
KY
1467 struct alc_spec *spec = codec->spec;
1468
b6cbe517
TI
1469 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1470
da00c244 1471 ass = codec->subsystem_id & 0xffff;
b6cbe517 1472 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1473 goto do_sku;
1474
1475 nid = 0x1d;
1476 if (codec->vendor_id == 0x10ec0260)
1477 nid = 0x17;
1478 ass = snd_hda_codec_get_pincfg(codec, nid);
1479
1480 if (!(ass & 1)) {
1481 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1482 codec->chip_name, ass);
1483 return -1;
1484 }
1485
1486 /* check sum */
1487 tmp = 0;
1488 for (i = 1; i < 16; i++) {
1489 if ((ass >> i) & 1)
1490 tmp++;
1491 }
1492 if (((ass >> 16) & 0xf) != tmp)
1493 return -1;
1494
1495 spec->cdefine.port_connectivity = ass >> 30;
1496 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1497 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1498 spec->cdefine.customization = ass >> 8;
1499do_sku:
1500 spec->cdefine.sku_cfg = ass;
1501 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1502 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1503 spec->cdefine.swap = (ass & 0x2) >> 1;
1504 spec->cdefine.override = ass & 0x1;
1505
1506 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1507 nid, spec->cdefine.sku_cfg);
1508 snd_printd("SKU: port_connectivity=0x%x\n",
1509 spec->cdefine.port_connectivity);
1510 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1511 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1512 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1513 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1514 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1515 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1516 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1517
1518 return 0;
1519}
1520
4a79ba34
TI
1521/* check subsystem ID and set up device-specific initialization;
1522 * return 1 if initialized, 0 if invalid SSID
1523 */
1524/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1525 * 31 ~ 16 : Manufacture ID
1526 * 15 ~ 8 : SKU ID
1527 * 7 ~ 0 : Assembly ID
1528 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1529 */
1530static int alc_subsystem_id(struct hda_codec *codec,
1531 hda_nid_t porta, hda_nid_t porte,
6227cdce 1532 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1533{
1534 unsigned int ass, tmp, i;
1535 unsigned nid;
1536 struct alc_spec *spec = codec->spec;
1537
1538 ass = codec->subsystem_id & 0xffff;
1539 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1540 goto do_sku;
1541
1542 /* invalid SSID, check the special NID pin defcfg instead */
1543 /*
def319f9 1544 * 31~30 : port connectivity
4a79ba34
TI
1545 * 29~21 : reserve
1546 * 20 : PCBEEP input
1547 * 19~16 : Check sum (15:1)
1548 * 15~1 : Custom
1549 * 0 : override
1550 */
1551 nid = 0x1d;
1552 if (codec->vendor_id == 0x10ec0260)
1553 nid = 0x17;
1554 ass = snd_hda_codec_get_pincfg(codec, nid);
1555 snd_printd("realtek: No valid SSID, "
1556 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1557 ass, nid);
6227cdce 1558 if (!(ass & 1))
4a79ba34
TI
1559 return 0;
1560 if ((ass >> 30) != 1) /* no physical connection */
1561 return 0;
1562
1563 /* check sum */
1564 tmp = 0;
1565 for (i = 1; i < 16; i++) {
1566 if ((ass >> i) & 1)
1567 tmp++;
1568 }
1569 if (((ass >> 16) & 0xf) != tmp)
1570 return 0;
1571do_sku:
1572 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1573 ass & 0xffff, codec->vendor_id);
1574 /*
1575 * 0 : override
1576 * 1 : Swap Jack
1577 * 2 : 0 --> Desktop, 1 --> Laptop
1578 * 3~5 : External Amplifier control
1579 * 7~6 : Reserved
1580 */
1581 tmp = (ass & 0x38) >> 3; /* external Amp control */
1582 switch (tmp) {
1583 case 1:
1584 spec->init_amp = ALC_INIT_GPIO1;
1585 break;
1586 case 3:
1587 spec->init_amp = ALC_INIT_GPIO2;
1588 break;
1589 case 7:
1590 spec->init_amp = ALC_INIT_GPIO3;
1591 break;
1592 case 5:
1593 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1594 break;
1595 }
ea1fb29a 1596
8c427226 1597 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1598 * when the external headphone out jack is plugged"
1599 */
8c427226 1600 if (!(ass & 0x8000))
4a79ba34 1601 return 1;
c9b58006
KY
1602 /*
1603 * 10~8 : Jack location
1604 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1605 * 14~13: Resvered
1606 * 15 : 1 --> enable the function "Mute internal speaker
1607 * when the external headphone out jack is plugged"
1608 */
c9b58006 1609 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1610 hda_nid_t nid;
c9b58006
KY
1611 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1612 if (tmp == 0)
01d4825d 1613 nid = porta;
c9b58006 1614 else if (tmp == 1)
01d4825d 1615 nid = porte;
c9b58006 1616 else if (tmp == 2)
01d4825d 1617 nid = portd;
6227cdce
KY
1618 else if (tmp == 3)
1619 nid = porti;
c9b58006 1620 else
4a79ba34 1621 return 1;
01d4825d
TI
1622 for (i = 0; i < spec->autocfg.line_outs; i++)
1623 if (spec->autocfg.line_out_pins[i] == nid)
1624 return 1;
1625 spec->autocfg.hp_pins[0] = nid;
c9b58006
KY
1626 }
1627
4a79ba34 1628 alc_init_auto_hp(codec);
6c819492 1629 alc_init_auto_mic(codec);
4a79ba34
TI
1630 return 1;
1631}
ea1fb29a 1632
4a79ba34 1633static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1634 hda_nid_t porta, hda_nid_t porte,
1635 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1636{
6227cdce 1637 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1638 struct alc_spec *spec = codec->spec;
1639 snd_printd("realtek: "
1640 "Enable default setup for auto mode as fallback\n");
1641 spec->init_amp = ALC_INIT_DEFAULT;
1642 alc_init_auto_hp(codec);
6c819492 1643 alc_init_auto_mic(codec);
4a79ba34 1644 }
bc9f98a9
KY
1645}
1646
f95474ec 1647/*
f8f25ba3 1648 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1649 */
1650
1651struct alc_pincfg {
1652 hda_nid_t nid;
1653 u32 val;
1654};
1655
f8f25ba3
TI
1656struct alc_fixup {
1657 const struct alc_pincfg *pins;
1658 const struct hda_verb *verbs;
1659};
1660
1661static void alc_pick_fixup(struct hda_codec *codec,
f95474ec 1662 const struct snd_pci_quirk *quirk,
7fa90e87
TI
1663 const struct alc_fixup *fix,
1664 int pre_init)
f95474ec
TI
1665{
1666 const struct alc_pincfg *cfg;
1667
1668 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1669 if (!quirk)
1670 return;
f8f25ba3
TI
1671 fix += quirk->value;
1672 cfg = fix->pins;
7fa90e87
TI
1673 if (pre_init && cfg) {
1674#ifdef CONFIG_SND_DEBUG_VERBOSE
1675 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
1676 codec->chip_name, quirk->name);
1677#endif
f8f25ba3
TI
1678 for (; cfg->nid; cfg++)
1679 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1680 }
7fa90e87
TI
1681 if (!pre_init && fix->verbs) {
1682#ifdef CONFIG_SND_DEBUG_VERBOSE
1683 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
1684 codec->chip_name, quirk->name);
1685#endif
f8f25ba3 1686 add_verb(codec->spec, fix->verbs);
7fa90e87 1687 }
f95474ec
TI
1688}
1689
274693f3
KY
1690static int alc_read_coef_idx(struct hda_codec *codec,
1691 unsigned int coef_idx)
1692{
1693 unsigned int val;
1694 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1695 coef_idx);
1696 val = snd_hda_codec_read(codec, 0x20, 0,
1697 AC_VERB_GET_PROC_COEF, 0);
1698 return val;
1699}
1700
977ddd6b
KY
1701static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
1702 unsigned int coef_val)
1703{
1704 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1705 coef_idx);
1706 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
1707 coef_val);
1708}
1709
757899ac
TI
1710/* set right pin controls for digital I/O */
1711static void alc_auto_init_digital(struct hda_codec *codec)
1712{
1713 struct alc_spec *spec = codec->spec;
1714 int i;
1715 hda_nid_t pin;
1716
1717 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1718 pin = spec->autocfg.dig_out_pins[i];
1719 if (pin) {
1720 snd_hda_codec_write(codec, pin, 0,
1721 AC_VERB_SET_PIN_WIDGET_CONTROL,
1722 PIN_OUT);
1723 }
1724 }
1725 pin = spec->autocfg.dig_in_pin;
1726 if (pin)
1727 snd_hda_codec_write(codec, pin, 0,
1728 AC_VERB_SET_PIN_WIDGET_CONTROL,
1729 PIN_IN);
1730}
1731
1732/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1733static void alc_auto_parse_digital(struct hda_codec *codec)
1734{
1735 struct alc_spec *spec = codec->spec;
1736 int i, err;
1737 hda_nid_t dig_nid;
1738
1739 /* support multiple SPDIFs; the secondary is set up as a slave */
1740 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1741 err = snd_hda_get_connections(codec,
1742 spec->autocfg.dig_out_pins[i],
1743 &dig_nid, 1);
1744 if (err < 0)
1745 continue;
1746 if (!i) {
1747 spec->multiout.dig_out_nid = dig_nid;
1748 spec->dig_out_type = spec->autocfg.dig_out_type[0];
1749 } else {
1750 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1751 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1752 break;
1753 spec->slave_dig_outs[i - 1] = dig_nid;
1754 }
1755 }
1756
1757 if (spec->autocfg.dig_in_pin) {
1758 hda_nid_t dig_nid;
1759 err = snd_hda_get_connections(codec,
1760 spec->autocfg.dig_in_pin,
1761 &dig_nid, 1);
1762 if (err > 0)
1763 spec->dig_in_nid = dig_nid;
1764 }
1765}
1766
ef8ef5fb
VP
1767/*
1768 * ALC888
1769 */
1770
1771/*
1772 * 2ch mode
1773 */
1774static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1775/* Mic-in jack as mic in */
1776 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1777 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1778/* Line-in jack as Line in */
1779 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1780 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1781/* Line-Out as Front */
1782 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1783 { } /* end */
1784};
1785
1786/*
1787 * 4ch mode
1788 */
1789static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1790/* Mic-in jack as mic in */
1791 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1792 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1793/* Line-in jack as Surround */
1794 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1795 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1796/* Line-Out as Front */
1797 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1798 { } /* end */
1799};
1800
1801/*
1802 * 6ch mode
1803 */
1804static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1805/* Mic-in jack as CLFE */
1806 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1807 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1808/* Line-in jack as Surround */
1809 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1810 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1811/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1812 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1813 { } /* end */
1814};
1815
1816/*
1817 * 8ch mode
1818 */
1819static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1820/* Mic-in jack as CLFE */
1821 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1822 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1823/* Line-in jack as Surround */
1824 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1825 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1826/* Line-Out as Side */
1827 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1828 { } /* end */
1829};
1830
1831static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1832 { 2, alc888_4ST_ch2_intel_init },
1833 { 4, alc888_4ST_ch4_intel_init },
1834 { 6, alc888_4ST_ch6_intel_init },
1835 { 8, alc888_4ST_ch8_intel_init },
1836};
1837
1838/*
1839 * ALC888 Fujitsu Siemens Amillo xa3530
1840 */
1841
1842static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1843/* Front Mic: set to PIN_IN (empty by default) */
1844 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1845/* Connect Internal HP to Front */
1846 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1847 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1848 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1849/* Connect Bass HP to Front */
1850 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1851 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1852 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1853/* Connect Line-Out side jack (SPDIF) to Side */
1854 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1855 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1856 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1857/* Connect Mic jack to CLFE */
1858 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1859 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1860 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1861/* Connect Line-in jack to Surround */
1862 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1863 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1864 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1865/* Connect HP out jack to Front */
1866 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1867 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1868 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1869/* Enable unsolicited event for HP jack and Line-out jack */
1870 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1871 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1872 {}
1873};
1874
a9fd4f3f 1875static void alc_automute_amp(struct hda_codec *codec)
ef8ef5fb 1876{
bb35febd 1877 alc_automute_speaker(codec, 0);
ef8ef5fb
VP
1878}
1879
a9fd4f3f
TI
1880static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1881 unsigned int res)
ef8ef5fb 1882{
a9fd4f3f
TI
1883 if (codec->vendor_id == 0x10ec0880)
1884 res >>= 28;
1885 else
1886 res >>= 26;
1887 if (res == ALC880_HP_EVENT)
1888 alc_automute_amp(codec);
ef8ef5fb
VP
1889}
1890
4f5d1706 1891static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
1892{
1893 struct alc_spec *spec = codec->spec;
1894
1895 spec->autocfg.hp_pins[0] = 0x15;
1896 spec->autocfg.speaker_pins[0] = 0x14;
1897 spec->autocfg.speaker_pins[1] = 0x16;
1898 spec->autocfg.speaker_pins[2] = 0x17;
1899 spec->autocfg.speaker_pins[3] = 0x19;
1900 spec->autocfg.speaker_pins[4] = 0x1a;
6732bd0d
WF
1901}
1902
1903static void alc889_intel_init_hook(struct hda_codec *codec)
1904{
1905 alc889_coef_init(codec);
4f5d1706 1906 alc_automute_amp(codec);
6732bd0d
WF
1907}
1908
4f5d1706 1909static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
1910{
1911 struct alc_spec *spec = codec->spec;
1912
1913 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1914 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1915 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1916 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
a9fd4f3f 1917}
ef8ef5fb 1918
5b2d1eca
VP
1919/*
1920 * ALC888 Acer Aspire 4930G model
1921 */
1922
1923static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1924/* Front Mic: set to PIN_IN (empty by default) */
1925 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1926/* Unselect Front Mic by default in input mixer 3 */
1927 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 1928/* Enable unsolicited event for HP jack */
5b2d1eca
VP
1929 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1930/* Connect Internal HP to front */
1931 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1932 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1933 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1934/* Connect HP out to front */
1935 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1936 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1937 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1938 { }
1939};
1940
d2fd4b09
TV
1941/*
1942 * ALC888 Acer Aspire 6530G model
1943 */
1944
1945static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
1946/* Route to built-in subwoofer as well as speakers */
1947 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1948 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1949 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1950 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
1951/* Bias voltage on for external mic port */
1952 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
1953/* Front Mic: set to PIN_IN (empty by default) */
1954 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1955/* Unselect Front Mic by default in input mixer 3 */
1956 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
1957/* Enable unsolicited event for HP jack */
1958 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1959/* Enable speaker output */
1960 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1961 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 1962 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
1963/* Enable headphone output */
1964 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1965 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1966 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 1967 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
1968 { }
1969};
1970
3b315d70 1971/*
018df418 1972 * ALC889 Acer Aspire 8930G model
3b315d70
HM
1973 */
1974
018df418 1975static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
1976/* Front Mic: set to PIN_IN (empty by default) */
1977 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1978/* Unselect Front Mic by default in input mixer 3 */
1979 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1980/* Enable unsolicited event for HP jack */
1981 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1982/* Connect Internal Front to Front */
1983 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1984 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1985 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1986/* Connect Internal Rear to Rear */
1987 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1988 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1989 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1990/* Connect Internal CLFE to CLFE */
1991 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1992 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1993 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1994/* Connect HP out to Front */
018df418 1995 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
1996 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1997 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1998/* Enable all DACs */
1999/* DAC DISABLE/MUTE 1? */
2000/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2001 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2002 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2003/* DAC DISABLE/MUTE 2? */
2004/* some bit here disables the other DACs. Init=0x4900 */
2005 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2006 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
2007/* DMIC fix
2008 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2009 * which makes the stereo useless. However, either the mic or the ALC889
2010 * makes the signal become a difference/sum signal instead of standard
2011 * stereo, which is annoying. So instead we flip this bit which makes the
2012 * codec replicate the sum signal to both channels, turning it into a
2013 * normal mono mic.
2014 */
2015/* DMIC_CONTROL? Init value = 0x0001 */
2016 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2017 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
2018 { }
2019};
2020
ef8ef5fb 2021static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
2022 /* Front mic only available on one ADC */
2023 {
2024 .num_items = 4,
2025 .items = {
2026 { "Mic", 0x0 },
2027 { "Line", 0x2 },
2028 { "CD", 0x4 },
2029 { "Front Mic", 0xb },
2030 },
2031 },
2032 {
2033 .num_items = 3,
2034 .items = {
2035 { "Mic", 0x0 },
2036 { "Line", 0x2 },
2037 { "CD", 0x4 },
2038 },
2039 }
2040};
2041
d2fd4b09
TV
2042static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2043 /* Interal mic only available on one ADC */
2044 {
684a8842 2045 .num_items = 5,
d2fd4b09
TV
2046 .items = {
2047 { "Ext Mic", 0x0 },
684a8842 2048 { "Line In", 0x2 },
d2fd4b09 2049 { "CD", 0x4 },
684a8842 2050 { "Input Mix", 0xa },
d2fd4b09
TV
2051 { "Int Mic", 0xb },
2052 },
2053 },
2054 {
684a8842 2055 .num_items = 4,
d2fd4b09
TV
2056 .items = {
2057 { "Ext Mic", 0x0 },
684a8842 2058 { "Line In", 0x2 },
d2fd4b09 2059 { "CD", 0x4 },
684a8842 2060 { "Input Mix", 0xa },
d2fd4b09
TV
2061 },
2062 }
2063};
2064
018df418
HM
2065static struct hda_input_mux alc889_capture_sources[3] = {
2066 /* Digital mic only available on first "ADC" */
2067 {
2068 .num_items = 5,
2069 .items = {
2070 { "Mic", 0x0 },
2071 { "Line", 0x2 },
2072 { "CD", 0x4 },
2073 { "Front Mic", 0xb },
2074 { "Input Mix", 0xa },
2075 },
2076 },
2077 {
2078 .num_items = 4,
2079 .items = {
2080 { "Mic", 0x0 },
2081 { "Line", 0x2 },
2082 { "CD", 0x4 },
2083 { "Input Mix", 0xa },
2084 },
2085 },
2086 {
2087 .num_items = 4,
2088 .items = {
2089 { "Mic", 0x0 },
2090 { "Line", 0x2 },
2091 { "CD", 0x4 },
2092 { "Input Mix", 0xa },
2093 },
2094 }
2095};
2096
ef8ef5fb 2097static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
2098 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2099 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2100 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2101 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2102 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2103 HDA_OUTPUT),
2104 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2105 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2106 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2107 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2108 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2109 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2110 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2111 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2112 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2113 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2114 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
2115 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
2116 { } /* end */
2117};
2118
556eea9a
HM
2119static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2120 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2121 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2122 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2123 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2124 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2125 HDA_OUTPUT),
2126 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2127 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2128 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2129 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2130 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2131 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2132 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
2133 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2134 { } /* end */
2135};
2136
2137
4f5d1706 2138static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2139{
a9fd4f3f 2140 struct alc_spec *spec = codec->spec;
5b2d1eca 2141
a9fd4f3f
TI
2142 spec->autocfg.hp_pins[0] = 0x15;
2143 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2144 spec->autocfg.speaker_pins[1] = 0x16;
2145 spec->autocfg.speaker_pins[2] = 0x17;
5b2d1eca
VP
2146}
2147
4f5d1706 2148static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2149{
2150 struct alc_spec *spec = codec->spec;
2151
2152 spec->autocfg.hp_pins[0] = 0x15;
2153 spec->autocfg.speaker_pins[0] = 0x14;
2154 spec->autocfg.speaker_pins[1] = 0x16;
2155 spec->autocfg.speaker_pins[2] = 0x17;
320d5920
EL
2156}
2157
4f5d1706 2158static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2159{
2160 struct alc_spec *spec = codec->spec;
2161
2162 spec->autocfg.hp_pins[0] = 0x15;
2163 spec->autocfg.speaker_pins[0] = 0x14;
2164 spec->autocfg.speaker_pins[1] = 0x16;
2165 spec->autocfg.speaker_pins[2] = 0x1b;
3b315d70
HM
2166}
2167
1da177e4 2168/*
e9edcee0
TI
2169 * ALC880 3-stack model
2170 *
2171 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2172 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2173 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2174 */
2175
e9edcee0
TI
2176static hda_nid_t alc880_dac_nids[4] = {
2177 /* front, rear, clfe, rear_surr */
2178 0x02, 0x05, 0x04, 0x03
2179};
2180
2181static hda_nid_t alc880_adc_nids[3] = {
2182 /* ADC0-2 */
2183 0x07, 0x08, 0x09,
2184};
2185
2186/* The datasheet says the node 0x07 is connected from inputs,
2187 * but it shows zero connection in the real implementation on some devices.
df694daa 2188 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2189 */
e9edcee0
TI
2190static hda_nid_t alc880_adc_nids_alt[2] = {
2191 /* ADC1-2 */
2192 0x08, 0x09,
2193};
2194
2195#define ALC880_DIGOUT_NID 0x06
2196#define ALC880_DIGIN_NID 0x0a
2197
2198static struct hda_input_mux alc880_capture_source = {
2199 .num_items = 4,
2200 .items = {
2201 { "Mic", 0x0 },
2202 { "Front Mic", 0x3 },
2203 { "Line", 0x2 },
2204 { "CD", 0x4 },
2205 },
2206};
2207
2208/* channel source setting (2/6 channel selection for 3-stack) */
2209/* 2ch mode */
2210static struct hda_verb alc880_threestack_ch2_init[] = {
2211 /* set line-in to input, mute it */
2212 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2213 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2214 /* set mic-in to input vref 80%, mute it */
2215 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2216 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2217 { } /* end */
2218};
2219
2220/* 6ch mode */
2221static struct hda_verb alc880_threestack_ch6_init[] = {
2222 /* set line-in to output, unmute it */
2223 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2224 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2225 /* set mic-in to output, unmute it */
2226 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2227 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2228 { } /* end */
2229};
2230
d2a6d7dc 2231static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2232 { 2, alc880_threestack_ch2_init },
2233 { 6, alc880_threestack_ch6_init },
2234};
2235
c8b6bf9b 2236static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2237 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2238 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2239 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2240 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2241 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2242 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2243 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2244 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2245 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2246 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2247 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2248 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2249 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2250 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2251 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2252 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2253 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2254 {
2255 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2256 .name = "Channel Mode",
df694daa
KY
2257 .info = alc_ch_mode_info,
2258 .get = alc_ch_mode_get,
2259 .put = alc_ch_mode_put,
e9edcee0
TI
2260 },
2261 { } /* end */
2262};
2263
2264/* capture mixer elements */
f9e336f6
TI
2265static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2266 struct snd_ctl_elem_info *uinfo)
2267{
2268 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2269 struct alc_spec *spec = codec->spec;
2270 int err;
1da177e4 2271
5a9e02e9 2272 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2273 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2274 HDA_INPUT);
2275 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2276 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2277 return err;
2278}
2279
2280static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2281 unsigned int size, unsigned int __user *tlv)
2282{
2283 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2284 struct alc_spec *spec = codec->spec;
2285 int err;
1da177e4 2286
5a9e02e9 2287 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2288 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2289 HDA_INPUT);
2290 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2291 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2292 return err;
2293}
2294
2295typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2296 struct snd_ctl_elem_value *ucontrol);
2297
2298static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2299 struct snd_ctl_elem_value *ucontrol,
2300 getput_call_t func)
2301{
2302 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2303 struct alc_spec *spec = codec->spec;
2304 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2305 int err;
2306
5a9e02e9 2307 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2308 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2309 3, 0, HDA_INPUT);
2310 err = func(kcontrol, ucontrol);
5a9e02e9 2311 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2312 return err;
2313}
2314
2315static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2316 struct snd_ctl_elem_value *ucontrol)
2317{
2318 return alc_cap_getput_caller(kcontrol, ucontrol,
2319 snd_hda_mixer_amp_volume_get);
2320}
2321
2322static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2323 struct snd_ctl_elem_value *ucontrol)
2324{
2325 return alc_cap_getput_caller(kcontrol, ucontrol,
2326 snd_hda_mixer_amp_volume_put);
2327}
2328
2329/* capture mixer elements */
2330#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2331
2332static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2333 struct snd_ctl_elem_value *ucontrol)
2334{
2335 return alc_cap_getput_caller(kcontrol, ucontrol,
2336 snd_hda_mixer_amp_switch_get);
2337}
2338
2339static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2340 struct snd_ctl_elem_value *ucontrol)
2341{
2342 return alc_cap_getput_caller(kcontrol, ucontrol,
2343 snd_hda_mixer_amp_switch_put);
2344}
2345
a23b688f 2346#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2347 { \
2348 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2349 .name = "Capture Switch", \
2350 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2351 .count = num, \
2352 .info = alc_cap_sw_info, \
2353 .get = alc_cap_sw_get, \
2354 .put = alc_cap_sw_put, \
2355 }, \
2356 { \
2357 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2358 .name = "Capture Volume", \
2359 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2360 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2361 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2362 .count = num, \
2363 .info = alc_cap_vol_info, \
2364 .get = alc_cap_vol_get, \
2365 .put = alc_cap_vol_put, \
2366 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2367 }
2368
2369#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2370 { \
2371 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2372 /* .name = "Capture Source", */ \
2373 .name = "Input Source", \
2374 .count = num, \
2375 .info = alc_mux_enum_info, \
2376 .get = alc_mux_enum_get, \
2377 .put = alc_mux_enum_put, \
a23b688f
TI
2378 }
2379
2380#define DEFINE_CAPMIX(num) \
2381static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2382 _DEFINE_CAPMIX(num), \
2383 _DEFINE_CAPSRC(num), \
2384 { } /* end */ \
2385}
2386
2387#define DEFINE_CAPMIX_NOSRC(num) \
2388static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2389 _DEFINE_CAPMIX(num), \
2390 { } /* end */ \
f9e336f6
TI
2391}
2392
2393/* up to three ADCs */
2394DEFINE_CAPMIX(1);
2395DEFINE_CAPMIX(2);
2396DEFINE_CAPMIX(3);
a23b688f
TI
2397DEFINE_CAPMIX_NOSRC(1);
2398DEFINE_CAPMIX_NOSRC(2);
2399DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2400
2401/*
2402 * ALC880 5-stack model
2403 *
9c7f852e
TI
2404 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2405 * Side = 0x02 (0xd)
e9edcee0
TI
2406 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2407 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2408 */
2409
2410/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 2411static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2412 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2413 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2414 { } /* end */
2415};
2416
e9edcee0
TI
2417/* channel source setting (6/8 channel selection for 5-stack) */
2418/* 6ch mode */
2419static struct hda_verb alc880_fivestack_ch6_init[] = {
2420 /* set line-in to input, mute it */
2421 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2422 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2423 { } /* end */
2424};
2425
e9edcee0
TI
2426/* 8ch mode */
2427static struct hda_verb alc880_fivestack_ch8_init[] = {
2428 /* set line-in to output, unmute it */
2429 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2430 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2431 { } /* end */
2432};
2433
d2a6d7dc 2434static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2435 { 6, alc880_fivestack_ch6_init },
2436 { 8, alc880_fivestack_ch8_init },
2437};
2438
2439
2440/*
2441 * ALC880 6-stack model
2442 *
9c7f852e
TI
2443 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2444 * Side = 0x05 (0x0f)
e9edcee0
TI
2445 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2446 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2447 */
2448
2449static hda_nid_t alc880_6st_dac_nids[4] = {
2450 /* front, rear, clfe, rear_surr */
2451 0x02, 0x03, 0x04, 0x05
f12ab1e0 2452};
e9edcee0
TI
2453
2454static struct hda_input_mux alc880_6stack_capture_source = {
2455 .num_items = 4,
2456 .items = {
2457 { "Mic", 0x0 },
2458 { "Front Mic", 0x1 },
2459 { "Line", 0x2 },
2460 { "CD", 0x4 },
2461 },
2462};
2463
2464/* fixed 8-channels */
d2a6d7dc 2465static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2466 { 8, NULL },
2467};
2468
c8b6bf9b 2469static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2470 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2471 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2472 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2473 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2474 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2475 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2476 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2477 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2478 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2479 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2480 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2481 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2482 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2483 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2484 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2485 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2486 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2487 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2488 {
2489 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2490 .name = "Channel Mode",
df694daa
KY
2491 .info = alc_ch_mode_info,
2492 .get = alc_ch_mode_get,
2493 .put = alc_ch_mode_put,
16ded525
TI
2494 },
2495 { } /* end */
2496};
2497
e9edcee0
TI
2498
2499/*
2500 * ALC880 W810 model
2501 *
2502 * W810 has rear IO for:
2503 * Front (DAC 02)
2504 * Surround (DAC 03)
2505 * Center/LFE (DAC 04)
2506 * Digital out (06)
2507 *
2508 * The system also has a pair of internal speakers, and a headphone jack.
2509 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2510 *
e9edcee0
TI
2511 * There is a variable resistor to control the speaker or headphone
2512 * volume. This is a hardware-only device without a software API.
2513 *
2514 * Plugging headphones in will disable the internal speakers. This is
2515 * implemented in hardware, not via the driver using jack sense. In
2516 * a similar fashion, plugging into the rear socket marked "front" will
2517 * disable both the speakers and headphones.
2518 *
2519 * For input, there's a microphone jack, and an "audio in" jack.
2520 * These may not do anything useful with this driver yet, because I
2521 * haven't setup any initialization verbs for these yet...
2522 */
2523
2524static hda_nid_t alc880_w810_dac_nids[3] = {
2525 /* front, rear/surround, clfe */
2526 0x02, 0x03, 0x04
16ded525
TI
2527};
2528
e9edcee0 2529/* fixed 6 channels */
d2a6d7dc 2530static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2531 { 6, NULL }
2532};
2533
2534/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 2535static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2536 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2537 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2538 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2539 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2540 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2541 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2542 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2543 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2544 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2545 { } /* end */
2546};
2547
2548
2549/*
2550 * Z710V model
2551 *
2552 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2553 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2554 * Line = 0x1a
e9edcee0
TI
2555 */
2556
2557static hda_nid_t alc880_z71v_dac_nids[1] = {
2558 0x02
2559};
2560#define ALC880_Z71V_HP_DAC 0x03
2561
2562/* fixed 2 channels */
d2a6d7dc 2563static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2564 { 2, NULL }
2565};
2566
c8b6bf9b 2567static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2568 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2569 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2570 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2571 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2572 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2573 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2574 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2575 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2576 { } /* end */
2577};
2578
e9edcee0 2579
e9edcee0
TI
2580/*
2581 * ALC880 F1734 model
2582 *
2583 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2584 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2585 */
2586
2587static hda_nid_t alc880_f1734_dac_nids[1] = {
2588 0x03
2589};
2590#define ALC880_F1734_HP_DAC 0x02
2591
c8b6bf9b 2592static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2593 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2594 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2595 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2596 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2597 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2598 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2599 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2600 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2601 { } /* end */
2602};
2603
937b4160
TI
2604static struct hda_input_mux alc880_f1734_capture_source = {
2605 .num_items = 2,
2606 .items = {
2607 { "Mic", 0x1 },
2608 { "CD", 0x4 },
2609 },
2610};
2611
e9edcee0 2612
e9edcee0
TI
2613/*
2614 * ALC880 ASUS model
2615 *
2616 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2617 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2618 * Mic = 0x18, Line = 0x1a
2619 */
2620
2621#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2622#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2623
c8b6bf9b 2624static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2625 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2626 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2627 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2628 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2629 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2630 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2631 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2632 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2633 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2634 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2635 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2636 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2637 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2638 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2639 {
2640 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2641 .name = "Channel Mode",
df694daa
KY
2642 .info = alc_ch_mode_info,
2643 .get = alc_ch_mode_get,
2644 .put = alc_ch_mode_put,
16ded525
TI
2645 },
2646 { } /* end */
2647};
e9edcee0 2648
e9edcee0
TI
2649/*
2650 * ALC880 ASUS W1V model
2651 *
2652 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2653 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2654 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2655 */
2656
2657/* additional mixers to alc880_asus_mixer */
c8b6bf9b 2658static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
2659 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2660 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2661 { } /* end */
2662};
2663
df694daa
KY
2664/* TCL S700 */
2665static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2666 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2667 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2668 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2669 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2670 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2671 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2672 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2673 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2674 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2675 { } /* end */
2676};
2677
ccc656ce
KY
2678/* Uniwill */
2679static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2680 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2681 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2682 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2683 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2684 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2685 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2686 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2687 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2688 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2689 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2690 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2691 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2692 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2693 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2694 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2695 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2696 {
2697 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2698 .name = "Channel Mode",
2699 .info = alc_ch_mode_info,
2700 .get = alc_ch_mode_get,
2701 .put = alc_ch_mode_put,
2702 },
2703 { } /* end */
2704};
2705
2cf9f0fc
TD
2706static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2707 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2708 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2709 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2710 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2711 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2712 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2713 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2714 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2715 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2716 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2717 { } /* end */
2718};
2719
ccc656ce 2720static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2721 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2722 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2723 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2724 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2725 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2726 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2727 { } /* end */
2728};
2729
2134ea4f
TI
2730/*
2731 * virtual master controls
2732 */
2733
2734/*
2735 * slave controls for virtual master
2736 */
2737static const char *alc_slave_vols[] = {
2738 "Front Playback Volume",
2739 "Surround Playback Volume",
2740 "Center Playback Volume",
2741 "LFE Playback Volume",
2742 "Side Playback Volume",
2743 "Headphone Playback Volume",
2744 "Speaker Playback Volume",
2745 "Mono Playback Volume",
2134ea4f 2746 "Line-Out Playback Volume",
26f5df26 2747 "PCM Playback Volume",
2134ea4f
TI
2748 NULL,
2749};
2750
2751static const char *alc_slave_sws[] = {
2752 "Front Playback Switch",
2753 "Surround Playback Switch",
2754 "Center Playback Switch",
2755 "LFE Playback Switch",
2756 "Side Playback Switch",
2757 "Headphone Playback Switch",
2758 "Speaker Playback Switch",
2759 "Mono Playback Switch",
edb54a55 2760 "IEC958 Playback Switch",
23033b2b
TI
2761 "Line-Out Playback Switch",
2762 "PCM Playback Switch",
2134ea4f
TI
2763 NULL,
2764};
2765
1da177e4 2766/*
e9edcee0 2767 * build control elements
1da177e4 2768 */
603c4019 2769
5b0cb1d8
JK
2770#define NID_MAPPING (-1)
2771
2772#define SUBDEV_SPEAKER_ (0 << 6)
2773#define SUBDEV_HP_ (1 << 6)
2774#define SUBDEV_LINE_ (2 << 6)
2775#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2776#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2777#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2778
603c4019
TI
2779static void alc_free_kctls(struct hda_codec *codec);
2780
67d634c0 2781#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2782/* additional beep mixers; the actual parameters are overwritten at build */
2783static struct snd_kcontrol_new alc_beep_mixer[] = {
2784 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 2785 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
2786 { } /* end */
2787};
67d634c0 2788#endif
45bdd1c1 2789
1da177e4
LT
2790static int alc_build_controls(struct hda_codec *codec)
2791{
2792 struct alc_spec *spec = codec->spec;
2f44f847 2793 struct snd_kcontrol *kctl = NULL;
5b0cb1d8
JK
2794 struct snd_kcontrol_new *knew;
2795 int i, j, err;
2796 unsigned int u;
2797 hda_nid_t nid;
1da177e4
LT
2798
2799 for (i = 0; i < spec->num_mixers; i++) {
2800 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2801 if (err < 0)
2802 return err;
2803 }
f9e336f6
TI
2804 if (spec->cap_mixer) {
2805 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2806 if (err < 0)
2807 return err;
2808 }
1da177e4 2809 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2810 err = snd_hda_create_spdif_out_ctls(codec,
2811 spec->multiout.dig_out_nid);
1da177e4
LT
2812 if (err < 0)
2813 return err;
e64f14f4
TI
2814 if (!spec->no_analog) {
2815 err = snd_hda_create_spdif_share_sw(codec,
2816 &spec->multiout);
2817 if (err < 0)
2818 return err;
2819 spec->multiout.share_spdif = 1;
2820 }
1da177e4
LT
2821 }
2822 if (spec->dig_in_nid) {
2823 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2824 if (err < 0)
2825 return err;
2826 }
2134ea4f 2827
67d634c0 2828#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2829 /* create beep controls if needed */
2830 if (spec->beep_amp) {
2831 struct snd_kcontrol_new *knew;
2832 for (knew = alc_beep_mixer; knew->name; knew++) {
2833 struct snd_kcontrol *kctl;
2834 kctl = snd_ctl_new1(knew, codec);
2835 if (!kctl)
2836 return -ENOMEM;
2837 kctl->private_value = spec->beep_amp;
5e26dfd0 2838 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
2839 if (err < 0)
2840 return err;
2841 }
2842 }
67d634c0 2843#endif
45bdd1c1 2844
2134ea4f 2845 /* if we have no master control, let's create it */
e64f14f4
TI
2846 if (!spec->no_analog &&
2847 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2848 unsigned int vmaster_tlv[4];
2134ea4f 2849 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2850 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2851 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2852 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2853 if (err < 0)
2854 return err;
2855 }
e64f14f4
TI
2856 if (!spec->no_analog &&
2857 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2858 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2859 NULL, alc_slave_sws);
2860 if (err < 0)
2861 return err;
2862 }
2863
5b0cb1d8 2864 /* assign Capture Source enums to NID */
fbe618f2
TI
2865 if (spec->capsrc_nids || spec->adc_nids) {
2866 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2867 if (!kctl)
2868 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2869 for (i = 0; kctl && i < kctl->count; i++) {
2870 hda_nid_t *nids = spec->capsrc_nids;
2871 if (!nids)
2872 nids = spec->adc_nids;
2873 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
2874 if (err < 0)
2875 return err;
2876 }
5b0cb1d8
JK
2877 }
2878 if (spec->cap_mixer) {
2879 const char *kname = kctl ? kctl->id.name : NULL;
2880 for (knew = spec->cap_mixer; knew->name; knew++) {
2881 if (kname && strcmp(knew->name, kname) == 0)
2882 continue;
2883 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2884 for (i = 0; kctl && i < kctl->count; i++) {
2885 err = snd_hda_add_nid(codec, kctl, i,
2886 spec->adc_nids[i]);
2887 if (err < 0)
2888 return err;
2889 }
2890 }
2891 }
2892
2893 /* other nid->control mapping */
2894 for (i = 0; i < spec->num_mixers; i++) {
2895 for (knew = spec->mixers[i]; knew->name; knew++) {
2896 if (knew->iface != NID_MAPPING)
2897 continue;
2898 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2899 if (kctl == NULL)
2900 continue;
2901 u = knew->subdevice;
2902 for (j = 0; j < 4; j++, u >>= 8) {
2903 nid = u & 0x3f;
2904 if (nid == 0)
2905 continue;
2906 switch (u & 0xc0) {
2907 case SUBDEV_SPEAKER_:
2908 nid = spec->autocfg.speaker_pins[nid];
2909 break;
2910 case SUBDEV_LINE_:
2911 nid = spec->autocfg.line_out_pins[nid];
2912 break;
2913 case SUBDEV_HP_:
2914 nid = spec->autocfg.hp_pins[nid];
2915 break;
2916 default:
2917 continue;
2918 }
2919 err = snd_hda_add_nid(codec, kctl, 0, nid);
2920 if (err < 0)
2921 return err;
2922 }
2923 u = knew->private_value;
2924 for (j = 0; j < 4; j++, u >>= 8) {
2925 nid = u & 0xff;
2926 if (nid == 0)
2927 continue;
2928 err = snd_hda_add_nid(codec, kctl, 0, nid);
2929 if (err < 0)
2930 return err;
2931 }
2932 }
2933 }
bae84e70
TI
2934
2935 alc_free_kctls(codec); /* no longer needed */
2936
1da177e4
LT
2937 return 0;
2938}
2939
e9edcee0 2940
1da177e4
LT
2941/*
2942 * initialize the codec volumes, etc
2943 */
2944
e9edcee0
TI
2945/*
2946 * generic initialization of ADC, input mixers and output mixers
2947 */
2948static struct hda_verb alc880_volume_init_verbs[] = {
2949 /*
2950 * Unmute ADC0-2 and set the default input to mic-in
2951 */
71fe7b82 2952 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2953 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2954 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2955 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2956 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2957 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 2958
e9edcee0
TI
2959 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2960 * mixer widget
9c7f852e
TI
2961 * Note: PASD motherboards uses the Line In 2 as the input for front
2962 * panel mic (mic 2)
1da177e4 2963 */
e9edcee0 2964 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
2965 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2966 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2967 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2968 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2969 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2970 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2971 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 2972
e9edcee0
TI
2973 /*
2974 * Set up output mixers (0x0c - 0x0f)
1da177e4 2975 */
e9edcee0
TI
2976 /* set vol=0 to output mixers */
2977 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2978 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2979 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2980 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2981 /* set up input amps for analog loopback */
2982 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
2983 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2984 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2985 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2986 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2987 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2988 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2989 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2990 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
2991
2992 { }
2993};
2994
e9edcee0
TI
2995/*
2996 * 3-stack pin configuration:
2997 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2998 */
2999static struct hda_verb alc880_pin_3stack_init_verbs[] = {
3000 /*
3001 * preset connection lists of input pins
3002 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3003 */
3004 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3005 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3006 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3007
3008 /*
3009 * Set pin mode and muting
3010 */
3011 /* set front pin widgets 0x14 for output */
05acb863 3012 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3013 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3014 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3015 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3016 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3017 /* Mic2 (as headphone out) for HP output */
3018 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3019 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3020 /* Line In pin widget for input */
05acb863 3021 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3022 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3023 /* Line2 (as front mic) pin widget for input and vref at 80% */
3024 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3025 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3026 /* CD pin widget for input */
05acb863 3027 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3028
e9edcee0
TI
3029 { }
3030};
1da177e4 3031
e9edcee0
TI
3032/*
3033 * 5-stack pin configuration:
3034 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3035 * line-in/side = 0x1a, f-mic = 0x1b
3036 */
3037static struct hda_verb alc880_pin_5stack_init_verbs[] = {
3038 /*
3039 * preset connection lists of input pins
3040 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 3041 */
e9edcee0
TI
3042 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3043 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 3044
e9edcee0
TI
3045 /*
3046 * Set pin mode and muting
1da177e4 3047 */
e9edcee0
TI
3048 /* set pin widgets 0x14-0x17 for output */
3049 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3050 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3051 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3052 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3053 /* unmute pins for output (no gain on this amp) */
3054 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3055 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3056 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3057 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3058
3059 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3060 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3061 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3062 /* Mic2 (as headphone out) for HP output */
3063 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3064 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3065 /* Line In pin widget for input */
3066 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3067 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3068 /* Line2 (as front mic) pin widget for input and vref at 80% */
3069 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3070 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3071 /* CD pin widget for input */
3072 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3073
3074 { }
3075};
3076
e9edcee0
TI
3077/*
3078 * W810 pin configuration:
3079 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3080 */
3081static struct hda_verb alc880_pin_w810_init_verbs[] = {
3082 /* hphone/speaker input selector: front DAC */
3083 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 3084
05acb863 3085 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3086 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3087 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3088 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3089 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3090 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3091
e9edcee0 3092 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 3093 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3094
1da177e4
LT
3095 { }
3096};
3097
e9edcee0
TI
3098/*
3099 * Z71V pin configuration:
3100 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3101 */
3102static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 3103 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3104 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3105 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3106 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 3107
16ded525 3108 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3109 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 3110 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3111 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
3112
3113 { }
3114};
3115
e9edcee0
TI
3116/*
3117 * 6-stack pin configuration:
9c7f852e
TI
3118 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3119 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
3120 */
3121static struct hda_verb alc880_pin_6stack_init_verbs[] = {
3122 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3123
16ded525 3124 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3125 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3126 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3127 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3128 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3129 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3130 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3131 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3132
16ded525 3133 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3134 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3135 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3136 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3137 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3138 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3139 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3140 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3141 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3142
e9edcee0
TI
3143 { }
3144};
3145
ccc656ce
KY
3146/*
3147 * Uniwill pin configuration:
3148 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3149 * line = 0x1a
3150 */
3151static struct hda_verb alc880_uniwill_init_verbs[] = {
3152 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3153
3154 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3155 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3156 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3157 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3158 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3159 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3160 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3161 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3162 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3163 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3164 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3165 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3166 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3167 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3168
3169 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3170 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3171 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3172 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3173 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3174 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3175 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3176 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3177 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3178
3179 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3180 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3181
3182 { }
3183};
3184
3185/*
3186* Uniwill P53
ea1fb29a 3187* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
3188 */
3189static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3190 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3191
3192 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3193 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3194 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3195 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3196 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3197 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3198 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3199 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3200 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3201 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3202 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3203 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3204
3205 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3206 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3207 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3208 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3209 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3210 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3211
3212 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3213 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3214
3215 { }
3216};
3217
2cf9f0fc
TD
3218static struct hda_verb alc880_beep_init_verbs[] = {
3219 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3220 { }
3221};
3222
458a4fab
TI
3223/* auto-toggle front mic */
3224static void alc880_uniwill_mic_automute(struct hda_codec *codec)
3225{
3226 unsigned int present;
3227 unsigned char bits;
ccc656ce 3228
864f92be 3229 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3230 bits = present ? HDA_AMP_MUTE : 0;
3231 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3232}
3233
4f5d1706 3234static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3235{
a9fd4f3f
TI
3236 struct alc_spec *spec = codec->spec;
3237
3238 spec->autocfg.hp_pins[0] = 0x14;
3239 spec->autocfg.speaker_pins[0] = 0x15;
3240 spec->autocfg.speaker_pins[0] = 0x16;
4f5d1706
TI
3241}
3242
3243static void alc880_uniwill_init_hook(struct hda_codec *codec)
3244{
a9fd4f3f 3245 alc_automute_amp(codec);
458a4fab 3246 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
3247}
3248
3249static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3250 unsigned int res)
3251{
3252 /* Looks like the unsol event is incompatible with the standard
3253 * definition. 4bit tag is placed at 28 bit!
3254 */
458a4fab 3255 switch (res >> 28) {
458a4fab
TI
3256 case ALC880_MIC_EVENT:
3257 alc880_uniwill_mic_automute(codec);
3258 break;
a9fd4f3f
TI
3259 default:
3260 alc_automute_amp_unsol_event(codec, res);
3261 break;
458a4fab 3262 }
ccc656ce
KY
3263}
3264
4f5d1706 3265static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3266{
a9fd4f3f 3267 struct alc_spec *spec = codec->spec;
ccc656ce 3268
a9fd4f3f
TI
3269 spec->autocfg.hp_pins[0] = 0x14;
3270 spec->autocfg.speaker_pins[0] = 0x15;
ccc656ce
KY
3271}
3272
3273static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3274{
3275 unsigned int present;
ea1fb29a 3276
ccc656ce 3277 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3278 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3279 present &= HDA_AMP_VOLMASK;
3280 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3281 HDA_AMP_VOLMASK, present);
3282 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3283 HDA_AMP_VOLMASK, present);
ccc656ce 3284}
47fd830a 3285
ccc656ce
KY
3286static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3287 unsigned int res)
3288{
3289 /* Looks like the unsol event is incompatible with the standard
3290 * definition. 4bit tag is placed at 28 bit!
3291 */
f12ab1e0 3292 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3293 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
3294 else
3295 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
3296}
3297
e9edcee0
TI
3298/*
3299 * F1734 pin configuration:
3300 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3301 */
3302static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3303 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3304 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3305 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3306 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3307 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3308
e9edcee0 3309 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3310 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3311 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3312 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3313
e9edcee0
TI
3314 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3315 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3316 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3317 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3318 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3319 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3320 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3321 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3322 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3323
937b4160
TI
3324 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3325 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3326
dfc0ff62
TI
3327 { }
3328};
3329
e9edcee0
TI
3330/*
3331 * ASUS pin configuration:
3332 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3333 */
3334static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3335 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3336 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3337 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3338 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3339
3340 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3341 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3342 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3343 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3344 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3345 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3346 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3347 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3348
3349 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3350 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3351 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3352 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3353 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3354 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3355 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3356 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3357 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3358
e9edcee0
TI
3359 { }
3360};
16ded525 3361
e9edcee0 3362/* Enable GPIO mask and set output */
bc9f98a9
KY
3363#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3364#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3365#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3366
3367/* Clevo m520g init */
3368static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3369 /* headphone output */
3370 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3371 /* line-out */
3372 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3373 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3374 /* Line-in */
3375 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3376 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3377 /* CD */
3378 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3379 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3380 /* Mic1 (rear panel) */
3381 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3382 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3383 /* Mic2 (front panel) */
3384 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3385 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3386 /* headphone */
3387 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3388 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3389 /* change to EAPD mode */
3390 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3391 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3392
3393 { }
16ded525
TI
3394};
3395
df694daa 3396static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3397 /* change to EAPD mode */
3398 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3399 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3400
df694daa
KY
3401 /* Headphone output */
3402 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3403 /* Front output*/
3404 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3405 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3406
3407 /* Line In pin widget for input */
3408 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3409 /* CD pin widget for input */
3410 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3411 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3412 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3413
3414 /* change to EAPD mode */
3415 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3416 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3417
3418 { }
3419};
16ded525 3420
e9edcee0 3421/*
ae6b813a
TI
3422 * LG m1 express dual
3423 *
3424 * Pin assignment:
3425 * Rear Line-In/Out (blue): 0x14
3426 * Build-in Mic-In: 0x15
3427 * Speaker-out: 0x17
3428 * HP-Out (green): 0x1b
3429 * Mic-In/Out (red): 0x19
3430 * SPDIF-Out: 0x1e
3431 */
3432
3433/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3434static hda_nid_t alc880_lg_dac_nids[3] = {
3435 0x05, 0x02, 0x03
3436};
3437
3438/* seems analog CD is not working */
3439static struct hda_input_mux alc880_lg_capture_source = {
3440 .num_items = 3,
3441 .items = {
3442 { "Mic", 0x1 },
3443 { "Line", 0x5 },
3444 { "Internal Mic", 0x6 },
3445 },
3446};
3447
3448/* 2,4,6 channel modes */
3449static struct hda_verb alc880_lg_ch2_init[] = {
3450 /* set line-in and mic-in to input */
3451 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3452 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3453 { }
3454};
3455
3456static struct hda_verb alc880_lg_ch4_init[] = {
3457 /* set line-in to out and mic-in to input */
3458 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3459 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3460 { }
3461};
3462
3463static struct hda_verb alc880_lg_ch6_init[] = {
3464 /* set line-in and mic-in to output */
3465 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3466 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3467 { }
3468};
3469
3470static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3471 { 2, alc880_lg_ch2_init },
3472 { 4, alc880_lg_ch4_init },
3473 { 6, alc880_lg_ch6_init },
3474};
3475
3476static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3477 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3478 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3479 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3480 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3481 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3482 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3483 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3484 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3485 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3486 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3487 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3488 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3489 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3490 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3491 {
3492 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3493 .name = "Channel Mode",
3494 .info = alc_ch_mode_info,
3495 .get = alc_ch_mode_get,
3496 .put = alc_ch_mode_put,
3497 },
3498 { } /* end */
3499};
3500
3501static struct hda_verb alc880_lg_init_verbs[] = {
3502 /* set capture source to mic-in */
3503 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3504 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3505 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3506 /* mute all amp mixer inputs */
3507 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3508 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3509 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3510 /* line-in to input */
3511 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3512 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3513 /* built-in mic */
3514 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3515 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3516 /* speaker-out */
3517 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3518 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3519 /* mic-in to input */
3520 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3521 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3522 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3523 /* HP-out */
3524 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3525 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3526 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3527 /* jack sense */
a9fd4f3f 3528 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3529 { }
3530};
3531
3532/* toggle speaker-output according to the hp-jack state */
4f5d1706 3533static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3534{
a9fd4f3f 3535 struct alc_spec *spec = codec->spec;
ae6b813a 3536
a9fd4f3f
TI
3537 spec->autocfg.hp_pins[0] = 0x1b;
3538 spec->autocfg.speaker_pins[0] = 0x17;
ae6b813a
TI
3539}
3540
d681518a
TI
3541/*
3542 * LG LW20
3543 *
3544 * Pin assignment:
3545 * Speaker-out: 0x14
3546 * Mic-In: 0x18
e4f41da9
CM
3547 * Built-in Mic-In: 0x19
3548 * Line-In: 0x1b
3549 * HP-Out: 0x1a
d681518a
TI
3550 * SPDIF-Out: 0x1e
3551 */
3552
d681518a 3553static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3554 .num_items = 3,
d681518a
TI
3555 .items = {
3556 { "Mic", 0x0 },
3557 { "Internal Mic", 0x1 },
e4f41da9 3558 { "Line In", 0x2 },
d681518a
TI
3559 },
3560};
3561
0a8c5da3
CM
3562#define alc880_lg_lw_modes alc880_threestack_modes
3563
d681518a 3564static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3565 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3566 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3567 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3568 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3569 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3570 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3571 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3572 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3573 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3574 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3575 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3576 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3577 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3578 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3579 {
3580 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3581 .name = "Channel Mode",
3582 .info = alc_ch_mode_info,
3583 .get = alc_ch_mode_get,
3584 .put = alc_ch_mode_put,
3585 },
d681518a
TI
3586 { } /* end */
3587};
3588
3589static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3590 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3591 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3592 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3593
d681518a
TI
3594 /* set capture source to mic-in */
3595 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3596 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3597 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3598 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3599 /* speaker-out */
3600 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3601 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3602 /* HP-out */
d681518a
TI
3603 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3604 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3605 /* mic-in to input */
3606 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3607 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3608 /* built-in mic */
3609 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3610 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3611 /* jack sense */
a9fd4f3f 3612 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3613 { }
3614};
3615
3616/* toggle speaker-output according to the hp-jack state */
4f5d1706 3617static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3618{
a9fd4f3f 3619 struct alc_spec *spec = codec->spec;
d681518a 3620
a9fd4f3f
TI
3621 spec->autocfg.hp_pins[0] = 0x1b;
3622 spec->autocfg.speaker_pins[0] = 0x14;
d681518a
TI
3623}
3624
df99cd33
TI
3625static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3626 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3627 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3628 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3629 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3630 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3631 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3632 { } /* end */
3633};
3634
3635static struct hda_input_mux alc880_medion_rim_capture_source = {
3636 .num_items = 2,
3637 .items = {
3638 { "Mic", 0x0 },
3639 { "Internal Mic", 0x1 },
3640 },
3641};
3642
3643static struct hda_verb alc880_medion_rim_init_verbs[] = {
3644 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3645
3646 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3647 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3648
3649 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3650 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3651 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3652 /* Mic2 (as headphone out) for HP output */
3653 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3654 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3655 /* Internal Speaker */
3656 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3657 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3658
3659 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3660 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3661
3662 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3663 { }
3664};
3665
3666/* toggle speaker-output according to the hp-jack state */
3667static void alc880_medion_rim_automute(struct hda_codec *codec)
3668{
a9fd4f3f
TI
3669 struct alc_spec *spec = codec->spec;
3670 alc_automute_amp(codec);
3671 /* toggle EAPD */
3672 if (spec->jack_present)
df99cd33
TI
3673 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3674 else
3675 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3676}
3677
3678static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3679 unsigned int res)
3680{
3681 /* Looks like the unsol event is incompatible with the standard
3682 * definition. 4bit tag is placed at 28 bit!
3683 */
3684 if ((res >> 28) == ALC880_HP_EVENT)
3685 alc880_medion_rim_automute(codec);
3686}
3687
4f5d1706 3688static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
3689{
3690 struct alc_spec *spec = codec->spec;
3691
3692 spec->autocfg.hp_pins[0] = 0x14;
3693 spec->autocfg.speaker_pins[0] = 0x1b;
a9fd4f3f
TI
3694}
3695
cb53c626
TI
3696#ifdef CONFIG_SND_HDA_POWER_SAVE
3697static struct hda_amp_list alc880_loopbacks[] = {
3698 { 0x0b, HDA_INPUT, 0 },
3699 { 0x0b, HDA_INPUT, 1 },
3700 { 0x0b, HDA_INPUT, 2 },
3701 { 0x0b, HDA_INPUT, 3 },
3702 { 0x0b, HDA_INPUT, 4 },
3703 { } /* end */
3704};
3705
3706static struct hda_amp_list alc880_lg_loopbacks[] = {
3707 { 0x0b, HDA_INPUT, 1 },
3708 { 0x0b, HDA_INPUT, 6 },
3709 { 0x0b, HDA_INPUT, 7 },
3710 { } /* end */
3711};
3712#endif
3713
ae6b813a
TI
3714/*
3715 * Common callbacks
e9edcee0
TI
3716 */
3717
1da177e4
LT
3718static int alc_init(struct hda_codec *codec)
3719{
3720 struct alc_spec *spec = codec->spec;
e9edcee0
TI
3721 unsigned int i;
3722
2c3bf9ab 3723 alc_fix_pll(codec);
4a79ba34 3724 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 3725
e9edcee0
TI
3726 for (i = 0; i < spec->num_init_verbs; i++)
3727 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
3728
3729 if (spec->init_hook)
3730 spec->init_hook(codec);
3731
ad35879a
TI
3732#ifdef CONFIG_SND_HDA_POWER_SAVE
3733 if (codec->patch_ops.check_power_status)
3734 codec->patch_ops.check_power_status(codec, 0x01);
3735#endif
1da177e4
LT
3736 return 0;
3737}
3738
ae6b813a
TI
3739static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3740{
3741 struct alc_spec *spec = codec->spec;
3742
3743 if (spec->unsol_event)
3744 spec->unsol_event(codec, res);
3745}
3746
cb53c626
TI
3747#ifdef CONFIG_SND_HDA_POWER_SAVE
3748static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3749{
3750 struct alc_spec *spec = codec->spec;
3751 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3752}
3753#endif
3754
1da177e4
LT
3755/*
3756 * Analog playback callbacks
3757 */
3758static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3759 struct hda_codec *codec,
c8b6bf9b 3760 struct snd_pcm_substream *substream)
1da177e4
LT
3761{
3762 struct alc_spec *spec = codec->spec;
9a08160b
TI
3763 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3764 hinfo);
1da177e4
LT
3765}
3766
3767static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3768 struct hda_codec *codec,
3769 unsigned int stream_tag,
3770 unsigned int format,
c8b6bf9b 3771 struct snd_pcm_substream *substream)
1da177e4
LT
3772{
3773 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3774 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3775 stream_tag, format, substream);
1da177e4
LT
3776}
3777
3778static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3779 struct hda_codec *codec,
c8b6bf9b 3780 struct snd_pcm_substream *substream)
1da177e4
LT
3781{
3782 struct alc_spec *spec = codec->spec;
3783 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3784}
3785
3786/*
3787 * Digital out
3788 */
3789static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3790 struct hda_codec *codec,
c8b6bf9b 3791 struct snd_pcm_substream *substream)
1da177e4
LT
3792{
3793 struct alc_spec *spec = codec->spec;
3794 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3795}
3796
6b97eb45
TI
3797static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3798 struct hda_codec *codec,
3799 unsigned int stream_tag,
3800 unsigned int format,
3801 struct snd_pcm_substream *substream)
3802{
3803 struct alc_spec *spec = codec->spec;
3804 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3805 stream_tag, format, substream);
3806}
3807
9b5f12e5
TI
3808static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3809 struct hda_codec *codec,
3810 struct snd_pcm_substream *substream)
3811{
3812 struct alc_spec *spec = codec->spec;
3813 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3814}
3815
1da177e4
LT
3816static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3817 struct hda_codec *codec,
c8b6bf9b 3818 struct snd_pcm_substream *substream)
1da177e4
LT
3819{
3820 struct alc_spec *spec = codec->spec;
3821 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3822}
3823
3824/*
3825 * Analog capture
3826 */
6330079f 3827static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3828 struct hda_codec *codec,
3829 unsigned int stream_tag,
3830 unsigned int format,
c8b6bf9b 3831 struct snd_pcm_substream *substream)
1da177e4
LT
3832{
3833 struct alc_spec *spec = codec->spec;
3834
6330079f 3835 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3836 stream_tag, 0, format);
3837 return 0;
3838}
3839
6330079f 3840static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3841 struct hda_codec *codec,
c8b6bf9b 3842 struct snd_pcm_substream *substream)
1da177e4
LT
3843{
3844 struct alc_spec *spec = codec->spec;
3845
888afa15
TI
3846 snd_hda_codec_cleanup_stream(codec,
3847 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3848 return 0;
3849}
3850
840b64c0
TI
3851/* analog capture with dynamic dual-adc changes */
3852static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3853 struct hda_codec *codec,
3854 unsigned int stream_tag,
3855 unsigned int format,
3856 struct snd_pcm_substream *substream)
3857{
3858 struct alc_spec *spec = codec->spec;
3859 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
3860 spec->cur_adc_stream_tag = stream_tag;
3861 spec->cur_adc_format = format;
3862 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
3863 return 0;
3864}
3865
3866static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3867 struct hda_codec *codec,
3868 struct snd_pcm_substream *substream)
3869{
3870 struct alc_spec *spec = codec->spec;
3871 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
3872 spec->cur_adc = 0;
3873 return 0;
3874}
3875
3876static struct hda_pcm_stream dualmic_pcm_analog_capture = {
3877 .substreams = 1,
3878 .channels_min = 2,
3879 .channels_max = 2,
3880 .nid = 0, /* fill later */
3881 .ops = {
3882 .prepare = dualmic_capture_pcm_prepare,
3883 .cleanup = dualmic_capture_pcm_cleanup
3884 },
3885};
1da177e4
LT
3886
3887/*
3888 */
3889static struct hda_pcm_stream alc880_pcm_analog_playback = {
3890 .substreams = 1,
3891 .channels_min = 2,
3892 .channels_max = 8,
e9edcee0 3893 /* NID is set in alc_build_pcms */
1da177e4
LT
3894 .ops = {
3895 .open = alc880_playback_pcm_open,
3896 .prepare = alc880_playback_pcm_prepare,
3897 .cleanup = alc880_playback_pcm_cleanup
3898 },
3899};
3900
3901static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
3902 .substreams = 1,
3903 .channels_min = 2,
3904 .channels_max = 2,
3905 /* NID is set in alc_build_pcms */
3906};
3907
3908static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3909 .substreams = 1,
3910 .channels_min = 2,
3911 .channels_max = 2,
3912 /* NID is set in alc_build_pcms */
3913};
3914
3915static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3916 .substreams = 2, /* can be overridden */
1da177e4
LT
3917 .channels_min = 2,
3918 .channels_max = 2,
e9edcee0 3919 /* NID is set in alc_build_pcms */
1da177e4 3920 .ops = {
6330079f
TI
3921 .prepare = alc880_alt_capture_pcm_prepare,
3922 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
3923 },
3924};
3925
3926static struct hda_pcm_stream alc880_pcm_digital_playback = {
3927 .substreams = 1,
3928 .channels_min = 2,
3929 .channels_max = 2,
3930 /* NID is set in alc_build_pcms */
3931 .ops = {
3932 .open = alc880_dig_playback_pcm_open,
6b97eb45 3933 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
3934 .prepare = alc880_dig_playback_pcm_prepare,
3935 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
3936 },
3937};
3938
3939static struct hda_pcm_stream alc880_pcm_digital_capture = {
3940 .substreams = 1,
3941 .channels_min = 2,
3942 .channels_max = 2,
3943 /* NID is set in alc_build_pcms */
3944};
3945
4c5186ed 3946/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 3947static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
3948 .substreams = 0,
3949 .channels_min = 0,
3950 .channels_max = 0,
3951};
3952
1da177e4
LT
3953static int alc_build_pcms(struct hda_codec *codec)
3954{
3955 struct alc_spec *spec = codec->spec;
3956 struct hda_pcm *info = spec->pcm_rec;
3957 int i;
3958
3959 codec->num_pcms = 1;
3960 codec->pcm_info = info;
3961
e64f14f4
TI
3962 if (spec->no_analog)
3963 goto skip_analog;
3964
812a2cca
TI
3965 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3966 "%s Analog", codec->chip_name);
1da177e4 3967 info->name = spec->stream_name_analog;
274693f3 3968
4a471b7d 3969 if (spec->stream_analog_playback) {
da3cec35
TI
3970 if (snd_BUG_ON(!spec->multiout.dac_nids))
3971 return -EINVAL;
4a471b7d
TI
3972 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3973 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3974 }
3975 if (spec->stream_analog_capture) {
da3cec35
TI
3976 if (snd_BUG_ON(!spec->adc_nids))
3977 return -EINVAL;
4a471b7d
TI
3978 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3979 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3980 }
3981
3982 if (spec->channel_mode) {
3983 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3984 for (i = 0; i < spec->num_channel_mode; i++) {
3985 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3986 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3987 }
1da177e4
LT
3988 }
3989 }
3990
e64f14f4 3991 skip_analog:
e08a007d 3992 /* SPDIF for stream index #1 */
1da177e4 3993 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
3994 snprintf(spec->stream_name_digital,
3995 sizeof(spec->stream_name_digital),
3996 "%s Digital", codec->chip_name);
e08a007d 3997 codec->num_pcms = 2;
b25c9da1 3998 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 3999 info = spec->pcm_rec + 1;
1da177e4 4000 info->name = spec->stream_name_digital;
8c441982
TI
4001 if (spec->dig_out_type)
4002 info->pcm_type = spec->dig_out_type;
4003 else
4004 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
4005 if (spec->multiout.dig_out_nid &&
4006 spec->stream_digital_playback) {
1da177e4
LT
4007 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4008 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4009 }
4a471b7d
TI
4010 if (spec->dig_in_nid &&
4011 spec->stream_digital_capture) {
1da177e4
LT
4012 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4013 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4014 }
963f803f
TI
4015 /* FIXME: do we need this for all Realtek codec models? */
4016 codec->spdif_status_reset = 1;
1da177e4
LT
4017 }
4018
e64f14f4
TI
4019 if (spec->no_analog)
4020 return 0;
4021
e08a007d
TI
4022 /* If the use of more than one ADC is requested for the current
4023 * model, configure a second analog capture-only PCM.
4024 */
4025 /* Additional Analaog capture for index #2 */
6330079f
TI
4026 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4027 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 4028 codec->num_pcms = 3;
c06134d7 4029 info = spec->pcm_rec + 2;
e08a007d 4030 info->name = spec->stream_name_analog;
6330079f
TI
4031 if (spec->alt_dac_nid) {
4032 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4033 *spec->stream_analog_alt_playback;
4034 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4035 spec->alt_dac_nid;
4036 } else {
4037 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4038 alc_pcm_null_stream;
4039 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4040 }
4041 if (spec->num_adc_nids > 1) {
4042 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4043 *spec->stream_analog_alt_capture;
4044 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4045 spec->adc_nids[1];
4046 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4047 spec->num_adc_nids - 1;
4048 } else {
4049 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4050 alc_pcm_null_stream;
4051 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4052 }
4053 }
4054
1da177e4
LT
4055 return 0;
4056}
4057
a4e09aa3
TI
4058static inline void alc_shutup(struct hda_codec *codec)
4059{
4060 snd_hda_shutup_pins(codec);
4061}
4062
603c4019
TI
4063static void alc_free_kctls(struct hda_codec *codec)
4064{
4065 struct alc_spec *spec = codec->spec;
4066
4067 if (spec->kctls.list) {
4068 struct snd_kcontrol_new *kctl = spec->kctls.list;
4069 int i;
4070 for (i = 0; i < spec->kctls.used; i++)
4071 kfree(kctl[i].name);
4072 }
4073 snd_array_free(&spec->kctls);
4074}
4075
1da177e4
LT
4076static void alc_free(struct hda_codec *codec)
4077{
e9edcee0 4078 struct alc_spec *spec = codec->spec;
e9edcee0 4079
f12ab1e0 4080 if (!spec)
e9edcee0
TI
4081 return;
4082
a4e09aa3 4083 alc_shutup(codec);
603c4019 4084 alc_free_kctls(codec);
e9edcee0 4085 kfree(spec);
680cd536 4086 snd_hda_detach_beep_device(codec);
1da177e4
LT
4087}
4088
f5de24b0 4089#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4090static void alc_power_eapd(struct hda_codec *codec)
4091{
4092 /* We currently only handle front, HP */
4093 switch (codec->vendor_id) {
4094 case 0x10ec0260:
9e4c8496
TI
4095 set_eapd(codec, 0x0f, 0);
4096 set_eapd(codec, 0x10, 0);
c97259df
DC
4097 break;
4098 case 0x10ec0262:
4099 case 0x10ec0267:
4100 case 0x10ec0268:
4101 case 0x10ec0269:
9e4c8496 4102 case 0x10ec0270:
c97259df
DC
4103 case 0x10ec0272:
4104 case 0x10ec0660:
4105 case 0x10ec0662:
4106 case 0x10ec0663:
4107 case 0x10ec0862:
4108 case 0x10ec0889:
9e4c8496
TI
4109 set_eapd(codec, 0x14, 0);
4110 set_eapd(codec, 0x15, 0);
c97259df
DC
4111 break;
4112 }
4113}
4114
f5de24b0
HM
4115static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4116{
4117 struct alc_spec *spec = codec->spec;
a4e09aa3 4118 alc_shutup(codec);
f5de24b0 4119 if (spec && spec->power_hook)
c97259df 4120 spec->power_hook(codec);
f5de24b0
HM
4121 return 0;
4122}
4123#endif
4124
e044c39a 4125#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4126static int alc_resume(struct hda_codec *codec)
4127{
e044c39a
TI
4128 codec->patch_ops.init(codec);
4129 snd_hda_codec_resume_amp(codec);
4130 snd_hda_codec_resume_cache(codec);
ad35879a
TI
4131#ifdef CONFIG_SND_HDA_POWER_SAVE
4132 if (codec->patch_ops.check_power_status)
4133 codec->patch_ops.check_power_status(codec, 0x01);
4134#endif
e044c39a
TI
4135 return 0;
4136}
e044c39a
TI
4137#endif
4138
1da177e4
LT
4139/*
4140 */
4141static struct hda_codec_ops alc_patch_ops = {
4142 .build_controls = alc_build_controls,
4143 .build_pcms = alc_build_pcms,
4144 .init = alc_init,
4145 .free = alc_free,
ae6b813a 4146 .unsol_event = alc_unsol_event,
e044c39a
TI
4147#ifdef SND_HDA_NEEDS_RESUME
4148 .resume = alc_resume,
4149#endif
cb53c626 4150#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4151 .suspend = alc_suspend,
cb53c626
TI
4152 .check_power_status = alc_check_power_status,
4153#endif
c97259df 4154 .reboot_notify = alc_shutup,
1da177e4
LT
4155};
4156
c027ddcd
KY
4157/* replace the codec chip_name with the given string */
4158static int alc_codec_rename(struct hda_codec *codec, const char *name)
4159{
4160 kfree(codec->chip_name);
4161 codec->chip_name = kstrdup(name, GFP_KERNEL);
4162 if (!codec->chip_name) {
4163 alc_free(codec);
4164 return -ENOMEM;
4165 }
4166 return 0;
4167}
4168
2fa522be
TI
4169/*
4170 * Test configuration for debugging
4171 *
4172 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4173 * enum controls.
4174 */
4175#ifdef CONFIG_SND_DEBUG
4176static hda_nid_t alc880_test_dac_nids[4] = {
4177 0x02, 0x03, 0x04, 0x05
4178};
4179
4180static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4181 .num_items = 7,
2fa522be
TI
4182 .items = {
4183 { "In-1", 0x0 },
4184 { "In-2", 0x1 },
4185 { "In-3", 0x2 },
4186 { "In-4", 0x3 },
4187 { "CD", 0x4 },
ae6b813a
TI
4188 { "Front", 0x5 },
4189 { "Surround", 0x6 },
2fa522be
TI
4190 },
4191};
4192
d2a6d7dc 4193static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4194 { 2, NULL },
fd2c326d 4195 { 4, NULL },
2fa522be 4196 { 6, NULL },
fd2c326d 4197 { 8, NULL },
2fa522be
TI
4198};
4199
9c7f852e
TI
4200static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4201 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4202{
4203 static char *texts[] = {
4204 "N/A", "Line Out", "HP Out",
4205 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4206 };
4207 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4208 uinfo->count = 1;
4209 uinfo->value.enumerated.items = 8;
4210 if (uinfo->value.enumerated.item >= 8)
4211 uinfo->value.enumerated.item = 7;
4212 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4213 return 0;
4214}
4215
9c7f852e
TI
4216static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4217 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4218{
4219 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4220 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4221 unsigned int pin_ctl, item = 0;
4222
4223 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4224 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4225 if (pin_ctl & AC_PINCTL_OUT_EN) {
4226 if (pin_ctl & AC_PINCTL_HP_EN)
4227 item = 2;
4228 else
4229 item = 1;
4230 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4231 switch (pin_ctl & AC_PINCTL_VREFEN) {
4232 case AC_PINCTL_VREF_HIZ: item = 3; break;
4233 case AC_PINCTL_VREF_50: item = 4; break;
4234 case AC_PINCTL_VREF_GRD: item = 5; break;
4235 case AC_PINCTL_VREF_80: item = 6; break;
4236 case AC_PINCTL_VREF_100: item = 7; break;
4237 }
4238 }
4239 ucontrol->value.enumerated.item[0] = item;
4240 return 0;
4241}
4242
9c7f852e
TI
4243static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4244 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4245{
4246 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4247 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4248 static unsigned int ctls[] = {
4249 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4250 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4251 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4252 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4253 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4254 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4255 };
4256 unsigned int old_ctl, new_ctl;
4257
4258 old_ctl = snd_hda_codec_read(codec, nid, 0,
4259 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4260 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4261 if (old_ctl != new_ctl) {
82beb8fd
TI
4262 int val;
4263 snd_hda_codec_write_cache(codec, nid, 0,
4264 AC_VERB_SET_PIN_WIDGET_CONTROL,
4265 new_ctl);
47fd830a
TI
4266 val = ucontrol->value.enumerated.item[0] >= 3 ?
4267 HDA_AMP_MUTE : 0;
4268 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4269 HDA_AMP_MUTE, val);
2fa522be
TI
4270 return 1;
4271 }
4272 return 0;
4273}
4274
9c7f852e
TI
4275static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4276 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4277{
4278 static char *texts[] = {
4279 "Front", "Surround", "CLFE", "Side"
4280 };
4281 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4282 uinfo->count = 1;
4283 uinfo->value.enumerated.items = 4;
4284 if (uinfo->value.enumerated.item >= 4)
4285 uinfo->value.enumerated.item = 3;
4286 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4287 return 0;
4288}
4289
9c7f852e
TI
4290static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4291 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4292{
4293 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4294 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4295 unsigned int sel;
4296
4297 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4298 ucontrol->value.enumerated.item[0] = sel & 3;
4299 return 0;
4300}
4301
9c7f852e
TI
4302static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4303 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4304{
4305 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4306 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4307 unsigned int sel;
4308
4309 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4310 if (ucontrol->value.enumerated.item[0] != sel) {
4311 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4312 snd_hda_codec_write_cache(codec, nid, 0,
4313 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4314 return 1;
4315 }
4316 return 0;
4317}
4318
4319#define PIN_CTL_TEST(xname,nid) { \
4320 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4321 .name = xname, \
5b0cb1d8 4322 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4323 .info = alc_test_pin_ctl_info, \
4324 .get = alc_test_pin_ctl_get, \
4325 .put = alc_test_pin_ctl_put, \
4326 .private_value = nid \
4327 }
4328
4329#define PIN_SRC_TEST(xname,nid) { \
4330 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4331 .name = xname, \
5b0cb1d8 4332 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4333 .info = alc_test_pin_src_info, \
4334 .get = alc_test_pin_src_get, \
4335 .put = alc_test_pin_src_put, \
4336 .private_value = nid \
4337 }
4338
c8b6bf9b 4339static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4340 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4341 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4342 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4343 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4344 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4345 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4346 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4347 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4348 PIN_CTL_TEST("Front Pin Mode", 0x14),
4349 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4350 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4351 PIN_CTL_TEST("Side Pin Mode", 0x17),
4352 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4353 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4354 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4355 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4356 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4357 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4358 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4359 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4360 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4361 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4362 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4363 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4364 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4365 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4366 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4367 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4368 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4369 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4370 {
4371 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4372 .name = "Channel Mode",
df694daa
KY
4373 .info = alc_ch_mode_info,
4374 .get = alc_ch_mode_get,
4375 .put = alc_ch_mode_put,
2fa522be
TI
4376 },
4377 { } /* end */
4378};
4379
4380static struct hda_verb alc880_test_init_verbs[] = {
4381 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4382 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4383 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4384 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4385 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4386 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4387 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4388 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4389 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4390 /* Vol output for 0x0c-0x0f */
05acb863
TI
4391 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4392 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4393 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4394 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4395 /* Set output pins 0x14-0x17 */
05acb863
TI
4396 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4397 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4398 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4399 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4400 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4401 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4402 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4403 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4404 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4405 /* Set input pins 0x18-0x1c */
16ded525
TI
4406 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4407 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4408 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4409 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4410 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4411 /* Mute input pins 0x18-0x1b */
05acb863
TI
4412 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4413 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4414 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4415 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4416 /* ADC set up */
05acb863 4417 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4418 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4419 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4420 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4421 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4422 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4423 /* Analog input/passthru */
4424 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4425 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4426 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4427 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4428 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4429 { }
4430};
4431#endif
4432
1da177e4
LT
4433/*
4434 */
4435
f5fcc13c
TI
4436static const char *alc880_models[ALC880_MODEL_LAST] = {
4437 [ALC880_3ST] = "3stack",
4438 [ALC880_TCL_S700] = "tcl",
4439 [ALC880_3ST_DIG] = "3stack-digout",
4440 [ALC880_CLEVO] = "clevo",
4441 [ALC880_5ST] = "5stack",
4442 [ALC880_5ST_DIG] = "5stack-digout",
4443 [ALC880_W810] = "w810",
4444 [ALC880_Z71V] = "z71v",
4445 [ALC880_6ST] = "6stack",
4446 [ALC880_6ST_DIG] = "6stack-digout",
4447 [ALC880_ASUS] = "asus",
4448 [ALC880_ASUS_W1V] = "asus-w1v",
4449 [ALC880_ASUS_DIG] = "asus-dig",
4450 [ALC880_ASUS_DIG2] = "asus-dig2",
4451 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4452 [ALC880_UNIWILL_P53] = "uniwill-p53",
4453 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4454 [ALC880_F1734] = "F1734",
4455 [ALC880_LG] = "lg",
4456 [ALC880_LG_LW] = "lg-lw",
df99cd33 4457 [ALC880_MEDION_RIM] = "medion",
2fa522be 4458#ifdef CONFIG_SND_DEBUG
f5fcc13c 4459 [ALC880_TEST] = "test",
2fa522be 4460#endif
f5fcc13c
TI
4461 [ALC880_AUTO] = "auto",
4462};
4463
4464static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4465 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4466 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4467 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4468 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4469 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4470 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4471 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4472 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4473 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4474 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4475 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4476 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4477 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4478 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4479 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4480 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4481 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4482 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4483 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4484 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4485 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4486 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4487 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4488 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4489 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4490 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4491 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4492 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4493 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4494 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4495 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4496 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4497 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4498 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4499 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4500 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4501 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4502 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4503 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4504 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 4505 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
4506 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4507 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4508 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4509 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4510 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4511 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4512 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4513 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4514 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4515 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4516 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
4517 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4518 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4519 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4520 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4521 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4522 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4523 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4524 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4525 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4526 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4527 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4528 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4529 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4530 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4531 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4532 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4533 /* default Intel */
4534 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4535 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4536 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4537 {}
4538};
4539
16ded525 4540/*
df694daa 4541 * ALC880 codec presets
16ded525 4542 */
16ded525
TI
4543static struct alc_config_preset alc880_presets[] = {
4544 [ALC880_3ST] = {
e9edcee0 4545 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4546 .init_verbs = { alc880_volume_init_verbs,
4547 alc880_pin_3stack_init_verbs },
16ded525 4548 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4549 .dac_nids = alc880_dac_nids,
16ded525
TI
4550 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4551 .channel_mode = alc880_threestack_modes,
4e195a7b 4552 .need_dac_fix = 1,
16ded525
TI
4553 .input_mux = &alc880_capture_source,
4554 },
4555 [ALC880_3ST_DIG] = {
e9edcee0 4556 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4557 .init_verbs = { alc880_volume_init_verbs,
4558 alc880_pin_3stack_init_verbs },
16ded525 4559 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4560 .dac_nids = alc880_dac_nids,
4561 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4562 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4563 .channel_mode = alc880_threestack_modes,
4e195a7b 4564 .need_dac_fix = 1,
16ded525
TI
4565 .input_mux = &alc880_capture_source,
4566 },
df694daa
KY
4567 [ALC880_TCL_S700] = {
4568 .mixers = { alc880_tcl_s700_mixer },
4569 .init_verbs = { alc880_volume_init_verbs,
4570 alc880_pin_tcl_S700_init_verbs,
4571 alc880_gpio2_init_verbs },
4572 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4573 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4574 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4575 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4576 .hp_nid = 0x03,
4577 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4578 .channel_mode = alc880_2_jack_modes,
4579 .input_mux = &alc880_capture_source,
4580 },
16ded525 4581 [ALC880_5ST] = {
f12ab1e0
TI
4582 .mixers = { alc880_three_stack_mixer,
4583 alc880_five_stack_mixer},
4584 .init_verbs = { alc880_volume_init_verbs,
4585 alc880_pin_5stack_init_verbs },
16ded525
TI
4586 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4587 .dac_nids = alc880_dac_nids,
16ded525
TI
4588 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4589 .channel_mode = alc880_fivestack_modes,
4590 .input_mux = &alc880_capture_source,
4591 },
4592 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4593 .mixers = { alc880_three_stack_mixer,
4594 alc880_five_stack_mixer },
4595 .init_verbs = { alc880_volume_init_verbs,
4596 alc880_pin_5stack_init_verbs },
16ded525
TI
4597 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4598 .dac_nids = alc880_dac_nids,
4599 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4600 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4601 .channel_mode = alc880_fivestack_modes,
4602 .input_mux = &alc880_capture_source,
4603 },
b6482d48
TI
4604 [ALC880_6ST] = {
4605 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4606 .init_verbs = { alc880_volume_init_verbs,
4607 alc880_pin_6stack_init_verbs },
b6482d48
TI
4608 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4609 .dac_nids = alc880_6st_dac_nids,
4610 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4611 .channel_mode = alc880_sixstack_modes,
4612 .input_mux = &alc880_6stack_capture_source,
4613 },
16ded525 4614 [ALC880_6ST_DIG] = {
e9edcee0 4615 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4616 .init_verbs = { alc880_volume_init_verbs,
4617 alc880_pin_6stack_init_verbs },
16ded525
TI
4618 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4619 .dac_nids = alc880_6st_dac_nids,
4620 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4621 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4622 .channel_mode = alc880_sixstack_modes,
4623 .input_mux = &alc880_6stack_capture_source,
4624 },
4625 [ALC880_W810] = {
e9edcee0 4626 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4627 .init_verbs = { alc880_volume_init_verbs,
4628 alc880_pin_w810_init_verbs,
b0af0de5 4629 alc880_gpio2_init_verbs },
16ded525
TI
4630 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4631 .dac_nids = alc880_w810_dac_nids,
4632 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4633 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4634 .channel_mode = alc880_w810_modes,
4635 .input_mux = &alc880_capture_source,
4636 },
4637 [ALC880_Z71V] = {
e9edcee0 4638 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
4639 .init_verbs = { alc880_volume_init_verbs,
4640 alc880_pin_z71v_init_verbs },
16ded525
TI
4641 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4642 .dac_nids = alc880_z71v_dac_nids,
4643 .dig_out_nid = ALC880_DIGOUT_NID,
4644 .hp_nid = 0x03,
e9edcee0
TI
4645 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4646 .channel_mode = alc880_2_jack_modes,
16ded525
TI
4647 .input_mux = &alc880_capture_source,
4648 },
4649 [ALC880_F1734] = {
e9edcee0 4650 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
4651 .init_verbs = { alc880_volume_init_verbs,
4652 alc880_pin_f1734_init_verbs },
e9edcee0
TI
4653 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4654 .dac_nids = alc880_f1734_dac_nids,
4655 .hp_nid = 0x02,
4656 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4657 .channel_mode = alc880_2_jack_modes,
937b4160
TI
4658 .input_mux = &alc880_f1734_capture_source,
4659 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4660 .setup = alc880_uniwill_p53_setup,
4661 .init_hook = alc_automute_amp,
16ded525
TI
4662 },
4663 [ALC880_ASUS] = {
e9edcee0 4664 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4665 .init_verbs = { alc880_volume_init_verbs,
4666 alc880_pin_asus_init_verbs,
e9edcee0
TI
4667 alc880_gpio1_init_verbs },
4668 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4669 .dac_nids = alc880_asus_dac_nids,
4670 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4671 .channel_mode = alc880_asus_modes,
4e195a7b 4672 .need_dac_fix = 1,
16ded525
TI
4673 .input_mux = &alc880_capture_source,
4674 },
4675 [ALC880_ASUS_DIG] = {
e9edcee0 4676 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4677 .init_verbs = { alc880_volume_init_verbs,
4678 alc880_pin_asus_init_verbs,
e9edcee0
TI
4679 alc880_gpio1_init_verbs },
4680 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4681 .dac_nids = alc880_asus_dac_nids,
16ded525 4682 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4683 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4684 .channel_mode = alc880_asus_modes,
4e195a7b 4685 .need_dac_fix = 1,
16ded525
TI
4686 .input_mux = &alc880_capture_source,
4687 },
df694daa
KY
4688 [ALC880_ASUS_DIG2] = {
4689 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4690 .init_verbs = { alc880_volume_init_verbs,
4691 alc880_pin_asus_init_verbs,
df694daa
KY
4692 alc880_gpio2_init_verbs }, /* use GPIO2 */
4693 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4694 .dac_nids = alc880_asus_dac_nids,
4695 .dig_out_nid = ALC880_DIGOUT_NID,
4696 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4697 .channel_mode = alc880_asus_modes,
4e195a7b 4698 .need_dac_fix = 1,
df694daa
KY
4699 .input_mux = &alc880_capture_source,
4700 },
16ded525 4701 [ALC880_ASUS_W1V] = {
e9edcee0 4702 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
4703 .init_verbs = { alc880_volume_init_verbs,
4704 alc880_pin_asus_init_verbs,
e9edcee0
TI
4705 alc880_gpio1_init_verbs },
4706 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4707 .dac_nids = alc880_asus_dac_nids,
16ded525 4708 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4709 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4710 .channel_mode = alc880_asus_modes,
4e195a7b 4711 .need_dac_fix = 1,
16ded525
TI
4712 .input_mux = &alc880_capture_source,
4713 },
4714 [ALC880_UNIWILL_DIG] = {
45bdd1c1 4715 .mixers = { alc880_asus_mixer },
ccc656ce
KY
4716 .init_verbs = { alc880_volume_init_verbs,
4717 alc880_pin_asus_init_verbs },
e9edcee0
TI
4718 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4719 .dac_nids = alc880_asus_dac_nids,
16ded525 4720 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4721 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4722 .channel_mode = alc880_asus_modes,
4e195a7b 4723 .need_dac_fix = 1,
16ded525
TI
4724 .input_mux = &alc880_capture_source,
4725 },
ccc656ce
KY
4726 [ALC880_UNIWILL] = {
4727 .mixers = { alc880_uniwill_mixer },
4728 .init_verbs = { alc880_volume_init_verbs,
4729 alc880_uniwill_init_verbs },
4730 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4731 .dac_nids = alc880_asus_dac_nids,
4732 .dig_out_nid = ALC880_DIGOUT_NID,
4733 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4734 .channel_mode = alc880_threestack_modes,
4735 .need_dac_fix = 1,
4736 .input_mux = &alc880_capture_source,
4737 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 4738 .setup = alc880_uniwill_setup,
a9fd4f3f 4739 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
4740 },
4741 [ALC880_UNIWILL_P53] = {
4742 .mixers = { alc880_uniwill_p53_mixer },
4743 .init_verbs = { alc880_volume_init_verbs,
4744 alc880_uniwill_p53_init_verbs },
4745 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4746 .dac_nids = alc880_asus_dac_nids,
4747 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4748 .channel_mode = alc880_threestack_modes,
4749 .input_mux = &alc880_capture_source,
4750 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4751 .setup = alc880_uniwill_p53_setup,
4752 .init_hook = alc_automute_amp,
2cf9f0fc
TD
4753 },
4754 [ALC880_FUJITSU] = {
45bdd1c1 4755 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4756 .init_verbs = { alc880_volume_init_verbs,
4757 alc880_uniwill_p53_init_verbs,
4758 alc880_beep_init_verbs },
4759 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4760 .dac_nids = alc880_dac_nids,
d53d7d9e 4761 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4762 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4763 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4764 .input_mux = &alc880_capture_source,
4765 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4766 .setup = alc880_uniwill_p53_setup,
4767 .init_hook = alc_automute_amp,
ccc656ce 4768 },
df694daa
KY
4769 [ALC880_CLEVO] = {
4770 .mixers = { alc880_three_stack_mixer },
4771 .init_verbs = { alc880_volume_init_verbs,
4772 alc880_pin_clevo_init_verbs },
4773 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4774 .dac_nids = alc880_dac_nids,
4775 .hp_nid = 0x03,
4776 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4777 .channel_mode = alc880_threestack_modes,
4e195a7b 4778 .need_dac_fix = 1,
df694daa
KY
4779 .input_mux = &alc880_capture_source,
4780 },
ae6b813a
TI
4781 [ALC880_LG] = {
4782 .mixers = { alc880_lg_mixer },
4783 .init_verbs = { alc880_volume_init_verbs,
4784 alc880_lg_init_verbs },
4785 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4786 .dac_nids = alc880_lg_dac_nids,
4787 .dig_out_nid = ALC880_DIGOUT_NID,
4788 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4789 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4790 .need_dac_fix = 1,
ae6b813a 4791 .input_mux = &alc880_lg_capture_source,
a9fd4f3f 4792 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4793 .setup = alc880_lg_setup,
4794 .init_hook = alc_automute_amp,
cb53c626
TI
4795#ifdef CONFIG_SND_HDA_POWER_SAVE
4796 .loopbacks = alc880_lg_loopbacks,
4797#endif
ae6b813a 4798 },
d681518a
TI
4799 [ALC880_LG_LW] = {
4800 .mixers = { alc880_lg_lw_mixer },
4801 .init_verbs = { alc880_volume_init_verbs,
4802 alc880_lg_lw_init_verbs },
0a8c5da3 4803 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
4804 .dac_nids = alc880_dac_nids,
4805 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
4806 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4807 .channel_mode = alc880_lg_lw_modes,
d681518a 4808 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f 4809 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4810 .setup = alc880_lg_lw_setup,
4811 .init_hook = alc_automute_amp,
d681518a 4812 },
df99cd33
TI
4813 [ALC880_MEDION_RIM] = {
4814 .mixers = { alc880_medion_rim_mixer },
4815 .init_verbs = { alc880_volume_init_verbs,
4816 alc880_medion_rim_init_verbs,
4817 alc_gpio2_init_verbs },
4818 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4819 .dac_nids = alc880_dac_nids,
4820 .dig_out_nid = ALC880_DIGOUT_NID,
4821 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4822 .channel_mode = alc880_2_jack_modes,
4823 .input_mux = &alc880_medion_rim_capture_source,
4824 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
4825 .setup = alc880_medion_rim_setup,
4826 .init_hook = alc880_medion_rim_automute,
df99cd33 4827 },
16ded525
TI
4828#ifdef CONFIG_SND_DEBUG
4829 [ALC880_TEST] = {
e9edcee0
TI
4830 .mixers = { alc880_test_mixer },
4831 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
4832 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4833 .dac_nids = alc880_test_dac_nids,
4834 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4835 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4836 .channel_mode = alc880_test_modes,
4837 .input_mux = &alc880_test_capture_source,
4838 },
4839#endif
4840};
4841
e9edcee0
TI
4842/*
4843 * Automatic parse of I/O pins from the BIOS configuration
4844 */
4845
e9edcee0
TI
4846enum {
4847 ALC_CTL_WIDGET_VOL,
4848 ALC_CTL_WIDGET_MUTE,
4849 ALC_CTL_BIND_MUTE,
4850};
c8b6bf9b 4851static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
4852 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4853 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 4854 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
4855};
4856
4857/* add dynamic controls */
f12ab1e0 4858static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 4859 int cidx, unsigned long val)
e9edcee0 4860{
c8b6bf9b 4861 struct snd_kcontrol_new *knew;
e9edcee0 4862
603c4019
TI
4863 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4864 knew = snd_array_new(&spec->kctls);
4865 if (!knew)
4866 return -ENOMEM;
e9edcee0 4867 *knew = alc880_control_templates[type];
543537bd 4868 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 4869 if (!knew->name)
e9edcee0 4870 return -ENOMEM;
66ceeb6b 4871 knew->index = cidx;
4d02d1b6 4872 if (get_amp_nid_(val))
5e26dfd0 4873 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 4874 knew->private_value = val;
e9edcee0
TI
4875 return 0;
4876}
4877
0afe5f89
TI
4878static int add_control_with_pfx(struct alc_spec *spec, int type,
4879 const char *pfx, const char *dir,
66ceeb6b 4880 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
4881{
4882 char name[32];
4883 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 4884 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
4885}
4886
66ceeb6b
TI
4887#define add_pb_vol_ctrl(spec, type, pfx, val) \
4888 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
4889#define add_pb_sw_ctrl(spec, type, pfx, val) \
4890 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
4891#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
4892 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
4893#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
4894 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 4895
e9edcee0
TI
4896#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4897#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4898#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4899#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
4900#define alc880_idx_to_dac(nid) ((nid) + 0x02)
4901#define alc880_dac_to_idx(nid) ((nid) - 0x02)
4902#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4903#define alc880_idx_to_selector(nid) ((nid) + 0x10)
4904#define ALC880_PIN_CD_NID 0x1c
4905
4906/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
4907static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4908 const struct auto_pin_cfg *cfg)
e9edcee0
TI
4909{
4910 hda_nid_t nid;
4911 int assigned[4];
4912 int i, j;
4913
4914 memset(assigned, 0, sizeof(assigned));
b0af0de5 4915 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
4916
4917 /* check the pins hardwired to audio widget */
4918 for (i = 0; i < cfg->line_outs; i++) {
4919 nid = cfg->line_out_pins[i];
4920 if (alc880_is_fixed_pin(nid)) {
4921 int idx = alc880_fixed_pin_idx(nid);
5014f193 4922 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
4923 assigned[idx] = 1;
4924 }
4925 }
4926 /* left pins can be connect to any audio widget */
4927 for (i = 0; i < cfg->line_outs; i++) {
4928 nid = cfg->line_out_pins[i];
4929 if (alc880_is_fixed_pin(nid))
4930 continue;
4931 /* search for an empty channel */
4932 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
4933 if (!assigned[j]) {
4934 spec->multiout.dac_nids[i] =
4935 alc880_idx_to_dac(j);
e9edcee0
TI
4936 assigned[j] = 1;
4937 break;
4938 }
4939 }
4940 }
4941 spec->multiout.num_dacs = cfg->line_outs;
4942 return 0;
4943}
4944
4945/* add playback controls from the parsed DAC table */
df694daa
KY
4946static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4947 const struct auto_pin_cfg *cfg)
e9edcee0 4948{
f12ab1e0
TI
4949 static const char *chname[4] = {
4950 "Front", "Surround", NULL /*CLFE*/, "Side"
4951 };
e9edcee0
TI
4952 hda_nid_t nid;
4953 int i, err;
4954
4955 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 4956 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
4957 continue;
4958 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4959 if (i == 2) {
4960 /* Center/LFE */
0afe5f89
TI
4961 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4962 "Center",
f12ab1e0
TI
4963 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4964 HDA_OUTPUT));
4965 if (err < 0)
e9edcee0 4966 return err;
0afe5f89
TI
4967 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4968 "LFE",
f12ab1e0
TI
4969 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4970 HDA_OUTPUT));
4971 if (err < 0)
e9edcee0 4972 return err;
0afe5f89
TI
4973 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4974 "Center",
f12ab1e0
TI
4975 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4976 HDA_INPUT));
4977 if (err < 0)
e9edcee0 4978 return err;
0afe5f89
TI
4979 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4980 "LFE",
f12ab1e0
TI
4981 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4982 HDA_INPUT));
4983 if (err < 0)
e9edcee0
TI
4984 return err;
4985 } else {
cb162b6b
TI
4986 const char *pfx;
4987 if (cfg->line_outs == 1 &&
4988 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4989 pfx = "Speaker";
4990 else
4991 pfx = chname[i];
0afe5f89 4992 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
4993 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4994 HDA_OUTPUT));
4995 if (err < 0)
e9edcee0 4996 return err;
0afe5f89 4997 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
4998 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4999 HDA_INPUT));
5000 if (err < 0)
e9edcee0
TI
5001 return err;
5002 }
5003 }
e9edcee0
TI
5004 return 0;
5005}
5006
8d88bc3d
TI
5007/* add playback controls for speaker and HP outputs */
5008static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5009 const char *pfx)
e9edcee0
TI
5010{
5011 hda_nid_t nid;
5012 int err;
5013
f12ab1e0 5014 if (!pin)
e9edcee0
TI
5015 return 0;
5016
5017 if (alc880_is_fixed_pin(pin)) {
5018 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5019 /* specify the DAC as the extra output */
f12ab1e0 5020 if (!spec->multiout.hp_nid)
e9edcee0 5021 spec->multiout.hp_nid = nid;
82bc955f
TI
5022 else
5023 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5024 /* control HP volume/switch on the output mixer amp */
5025 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5026 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5027 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5028 if (err < 0)
e9edcee0 5029 return err;
0afe5f89 5030 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5031 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5032 if (err < 0)
e9edcee0
TI
5033 return err;
5034 } else if (alc880_is_multi_pin(pin)) {
5035 /* set manual connection */
e9edcee0 5036 /* we have only a switch on HP-out PIN */
0afe5f89 5037 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5038 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5039 if (err < 0)
e9edcee0
TI
5040 return err;
5041 }
5042 return 0;
5043}
5044
5045/* create input playback/capture controls for the given pin */
f12ab1e0 5046static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5047 const char *ctlname, int ctlidx,
df694daa 5048 int idx, hda_nid_t mix_nid)
e9edcee0 5049{
df694daa 5050 int err;
e9edcee0 5051
66ceeb6b 5052 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5053 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5054 if (err < 0)
e9edcee0 5055 return err;
66ceeb6b 5056 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5057 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5058 if (err < 0)
e9edcee0
TI
5059 return err;
5060 return 0;
5061}
5062
05f5f477
TI
5063static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5064{
5065 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5066 return (pincap & AC_PINCAP_IN) != 0;
5067}
5068
e9edcee0 5069/* create playback/capture controls for input pins */
05f5f477
TI
5070static int alc_auto_create_input_ctls(struct hda_codec *codec,
5071 const struct auto_pin_cfg *cfg,
5072 hda_nid_t mixer,
5073 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5074{
05f5f477 5075 struct alc_spec *spec = codec->spec;
61b9b9b1 5076 struct hda_input_mux *imux = &spec->private_imux[0];
66ceeb6b 5077 int i, err, idx, type, type_idx = 0;
e9edcee0 5078
66ceeb6b 5079 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5080 hda_nid_t pin;
10a20af7 5081 const char *label;
05f5f477 5082
66ceeb6b 5083 pin = cfg->inputs[i].pin;
05f5f477
TI
5084 if (!alc_is_input_pin(codec, pin))
5085 continue;
5086
66ceeb6b
TI
5087 type = cfg->inputs[i].type;
5088 if (i > 0 && type == cfg->inputs[i - 1].type)
5089 type_idx++;
5090 else
5091 type_idx = 0;
10a20af7 5092 label = hda_get_autocfg_input_label(codec, cfg, i);
05f5f477
TI
5093 if (mixer) {
5094 idx = get_connection_index(codec, mixer, pin);
5095 if (idx >= 0) {
5096 err = new_analog_input(spec, pin,
10a20af7
TI
5097 label, type_idx,
5098 idx, mixer);
05f5f477
TI
5099 if (err < 0)
5100 return err;
5101 }
5102 }
5103
5104 if (!cap1)
5105 continue;
5106 idx = get_connection_index(codec, cap1, pin);
5107 if (idx < 0 && cap2)
5108 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5109 if (idx >= 0)
5110 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5111 }
5112 return 0;
5113}
5114
05f5f477
TI
5115static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5116 const struct auto_pin_cfg *cfg)
5117{
5118 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5119}
5120
f6c7e546
TI
5121static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5122 unsigned int pin_type)
5123{
5124 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5125 pin_type);
5126 /* unmute pin */
d260cdf6
TI
5127 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5128 AMP_OUT_UNMUTE);
f6c7e546
TI
5129}
5130
df694daa
KY
5131static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5132 hda_nid_t nid, int pin_type,
e9edcee0
TI
5133 int dac_idx)
5134{
f6c7e546 5135 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5136 /* need the manual connection? */
5137 if (alc880_is_multi_pin(nid)) {
5138 struct alc_spec *spec = codec->spec;
5139 int idx = alc880_multi_pin_idx(nid);
5140 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5141 AC_VERB_SET_CONNECT_SEL,
5142 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5143 }
5144}
5145
baba8ee9
TI
5146static int get_pin_type(int line_out_type)
5147{
5148 if (line_out_type == AUTO_PIN_HP_OUT)
5149 return PIN_HP;
5150 else
5151 return PIN_OUT;
5152}
5153
e9edcee0
TI
5154static void alc880_auto_init_multi_out(struct hda_codec *codec)
5155{
5156 struct alc_spec *spec = codec->spec;
5157 int i;
ea1fb29a 5158
e9edcee0
TI
5159 for (i = 0; i < spec->autocfg.line_outs; i++) {
5160 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5161 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5162 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5163 }
5164}
5165
8d88bc3d 5166static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5167{
5168 struct alc_spec *spec = codec->spec;
5169 hda_nid_t pin;
5170
82bc955f 5171 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5172 if (pin) /* connect to front */
5173 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5174 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5175 if (pin) /* connect to front */
5176 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5177}
5178
5179static void alc880_auto_init_analog_input(struct hda_codec *codec)
5180{
5181 struct alc_spec *spec = codec->spec;
66ceeb6b 5182 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5183 int i;
5184
66ceeb6b
TI
5185 for (i = 0; i < cfg->num_inputs; i++) {
5186 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5187 if (alc_is_input_pin(codec, nid)) {
30ea098f 5188 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
5189 if (nid != ALC880_PIN_CD_NID &&
5190 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5191 snd_hda_codec_write(codec, nid, 0,
5192 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5193 AMP_OUT_MUTE);
5194 }
5195 }
5196}
5197
7f311a46
TI
5198static void alc880_auto_init_input_src(struct hda_codec *codec)
5199{
5200 struct alc_spec *spec = codec->spec;
5201 int c;
5202
5203 for (c = 0; c < spec->num_adc_nids; c++) {
5204 unsigned int mux_idx;
5205 const struct hda_input_mux *imux;
5206 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5207 imux = &spec->input_mux[mux_idx];
5208 if (!imux->num_items && mux_idx > 0)
5209 imux = &spec->input_mux[0];
5210 if (imux)
5211 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5212 AC_VERB_SET_CONNECT_SEL,
5213 imux->items[0].index);
5214 }
5215}
5216
e9edcee0 5217/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5218/* return 1 if successful, 0 if the proper config is not found,
5219 * or a negative error code
5220 */
e9edcee0
TI
5221static int alc880_parse_auto_config(struct hda_codec *codec)
5222{
5223 struct alc_spec *spec = codec->spec;
757899ac 5224 int err;
df694daa 5225 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5226
f12ab1e0
TI
5227 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5228 alc880_ignore);
5229 if (err < 0)
e9edcee0 5230 return err;
f12ab1e0 5231 if (!spec->autocfg.line_outs)
e9edcee0 5232 return 0; /* can't find valid BIOS pin config */
df694daa 5233
f12ab1e0
TI
5234 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5235 if (err < 0)
5236 return err;
5237 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5238 if (err < 0)
5239 return err;
5240 err = alc880_auto_create_extra_out(spec,
5241 spec->autocfg.speaker_pins[0],
5242 "Speaker");
5243 if (err < 0)
5244 return err;
5245 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5246 "Headphone");
5247 if (err < 0)
5248 return err;
05f5f477 5249 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5250 if (err < 0)
e9edcee0
TI
5251 return err;
5252
5253 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5254
757899ac 5255 alc_auto_parse_digital(codec);
e9edcee0 5256
603c4019 5257 if (spec->kctls.list)
d88897ea 5258 add_mixer(spec, spec->kctls.list);
e9edcee0 5259
d88897ea 5260 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5261
a1e8d2da 5262 spec->num_mux_defs = 1;
61b9b9b1 5263 spec->input_mux = &spec->private_imux[0];
e9edcee0 5264
6227cdce 5265 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5266
e9edcee0
TI
5267 return 1;
5268}
5269
ae6b813a
TI
5270/* additional initialization for auto-configuration model */
5271static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5272{
f6c7e546 5273 struct alc_spec *spec = codec->spec;
e9edcee0 5274 alc880_auto_init_multi_out(codec);
8d88bc3d 5275 alc880_auto_init_extra_out(codec);
e9edcee0 5276 alc880_auto_init_analog_input(codec);
7f311a46 5277 alc880_auto_init_input_src(codec);
757899ac 5278 alc_auto_init_digital(codec);
f6c7e546 5279 if (spec->unsol_event)
7fb0d78f 5280 alc_inithook(codec);
e9edcee0
TI
5281}
5282
b59bdf3b
TI
5283/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5284 * one of two digital mic pins, e.g. on ALC272
5285 */
5286static void fixup_automic_adc(struct hda_codec *codec)
5287{
5288 struct alc_spec *spec = codec->spec;
5289 int i;
5290
5291 for (i = 0; i < spec->num_adc_nids; i++) {
5292 hda_nid_t cap = spec->capsrc_nids ?
5293 spec->capsrc_nids[i] : spec->adc_nids[i];
5294 int iidx, eidx;
5295
5296 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5297 if (iidx < 0)
5298 continue;
5299 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5300 if (eidx < 0)
5301 continue;
5302 spec->int_mic.mux_idx = iidx;
5303 spec->ext_mic.mux_idx = eidx;
5304 if (spec->capsrc_nids)
5305 spec->capsrc_nids += i;
5306 spec->adc_nids += i;
5307 spec->num_adc_nids = 1;
5308 return;
5309 }
5310 snd_printd(KERN_INFO "hda_codec: %s: "
5311 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5312 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5313 spec->auto_mic = 0; /* disable auto-mic to be sure */
5314}
5315
748cce43
TI
5316/* select or unmute the given capsrc route */
5317static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5318 int idx)
5319{
5320 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5321 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5322 HDA_AMP_MUTE, 0);
5323 } else {
5324 snd_hda_codec_write_cache(codec, cap, 0,
5325 AC_VERB_SET_CONNECT_SEL, idx);
5326 }
5327}
5328
840b64c0
TI
5329/* set the default connection to that pin */
5330static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5331{
5332 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5333 int i;
5334
eaa9b3a7
TI
5335 for (i = 0; i < spec->num_adc_nids; i++) {
5336 hda_nid_t cap = spec->capsrc_nids ?
5337 spec->capsrc_nids[i] : spec->adc_nids[i];
5338 int idx;
5339
5340 idx = get_connection_index(codec, cap, pin);
5341 if (idx < 0)
5342 continue;
748cce43 5343 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5344 return i; /* return the found index */
5345 }
5346 return -1; /* not found */
5347}
5348
5349/* choose the ADC/MUX containing the input pin and initialize the setup */
5350static void fixup_single_adc(struct hda_codec *codec)
5351{
5352 struct alc_spec *spec = codec->spec;
66ceeb6b 5353 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5354 int i;
5355
5356 /* search for the input pin; there must be only one */
66ceeb6b 5357 if (cfg->num_inputs != 1)
eaa9b3a7 5358 return;
66ceeb6b 5359 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5360 if (i >= 0) {
5361 /* use only this ADC */
5362 if (spec->capsrc_nids)
5363 spec->capsrc_nids += i;
5364 spec->adc_nids += i;
5365 spec->num_adc_nids = 1;
eaa9b3a7
TI
5366 }
5367}
5368
840b64c0
TI
5369/* initialize dual adcs */
5370static void fixup_dual_adc_switch(struct hda_codec *codec)
5371{
5372 struct alc_spec *spec = codec->spec;
5373 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5374 init_capsrc_for_pin(codec, spec->int_mic.pin);
5375}
5376
b59bdf3b 5377static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5378{
b59bdf3b 5379 struct alc_spec *spec = codec->spec;
a23b688f
TI
5380 static struct snd_kcontrol_new *caps[2][3] = {
5381 { alc_capture_mixer_nosrc1,
5382 alc_capture_mixer_nosrc2,
5383 alc_capture_mixer_nosrc3 },
5384 { alc_capture_mixer1,
5385 alc_capture_mixer2,
5386 alc_capture_mixer3 },
f9e336f6 5387 };
a23b688f 5388 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5389 int mux = 0;
840b64c0
TI
5390 int num_adcs = spec->num_adc_nids;
5391 if (spec->dual_adc_switch)
5392 fixup_dual_adc_switch(codec);
5393 else if (spec->auto_mic)
b59bdf3b 5394 fixup_automic_adc(codec);
eaa9b3a7
TI
5395 else if (spec->input_mux) {
5396 if (spec->input_mux->num_items > 1)
5397 mux = 1;
5398 else if (spec->input_mux->num_items == 1)
5399 fixup_single_adc(codec);
5400 }
840b64c0
TI
5401 if (spec->dual_adc_switch)
5402 num_adcs = 1;
5403 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5404 }
f9e336f6
TI
5405}
5406
6694635d
TI
5407/* fill adc_nids (and capsrc_nids) containing all active input pins */
5408static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5409 int num_nids)
5410{
5411 struct alc_spec *spec = codec->spec;
66ceeb6b 5412 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5413 int n;
5414 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5415
5416 for (n = 0; n < num_nids; n++) {
5417 hda_nid_t adc, cap;
5418 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5419 int nconns, i, j;
5420
5421 adc = nids[n];
5422 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5423 continue;
5424 cap = adc;
5425 nconns = snd_hda_get_connections(codec, cap, conn,
5426 ARRAY_SIZE(conn));
5427 if (nconns == 1) {
5428 cap = conn[0];
5429 nconns = snd_hda_get_connections(codec, cap, conn,
5430 ARRAY_SIZE(conn));
5431 }
5432 if (nconns <= 0)
5433 continue;
5434 if (!fallback_adc) {
5435 fallback_adc = adc;
5436 fallback_cap = cap;
5437 }
66ceeb6b
TI
5438 for (i = 0; i < cfg->num_inputs; i++) {
5439 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5440 for (j = 0; j < nconns; j++) {
5441 if (conn[j] == nid)
5442 break;
5443 }
5444 if (j >= nconns)
5445 break;
5446 }
66ceeb6b 5447 if (i >= cfg->num_inputs) {
6694635d
TI
5448 int num_adcs = spec->num_adc_nids;
5449 spec->private_adc_nids[num_adcs] = adc;
5450 spec->private_capsrc_nids[num_adcs] = cap;
5451 spec->num_adc_nids++;
5452 spec->adc_nids = spec->private_adc_nids;
5453 if (adc != cap)
5454 spec->capsrc_nids = spec->private_capsrc_nids;
5455 }
5456 }
5457 if (!spec->num_adc_nids) {
5458 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5459 " using fallback 0x%x\n",
5460 codec->chip_name, fallback_adc);
6694635d
TI
5461 spec->private_adc_nids[0] = fallback_adc;
5462 spec->adc_nids = spec->private_adc_nids;
5463 if (fallback_adc != fallback_cap) {
5464 spec->private_capsrc_nids[0] = fallback_cap;
5465 spec->capsrc_nids = spec->private_adc_nids;
5466 }
5467 }
5468}
5469
67d634c0 5470#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5471#define set_beep_amp(spec, nid, idx, dir) \
5472 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25
TI
5473
5474static struct snd_pci_quirk beep_white_list[] = {
5475 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5476 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
e096c8e6 5477 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5478 {}
5479};
5480
5481static inline int has_cdefine_beep(struct hda_codec *codec)
5482{
5483 struct alc_spec *spec = codec->spec;
5484 const struct snd_pci_quirk *q;
5485 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5486 if (q)
5487 return q->value;
5488 return spec->cdefine.enable_pcbeep;
5489}
67d634c0
TI
5490#else
5491#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5492#define has_cdefine_beep(codec) 0
67d634c0 5493#endif
45bdd1c1
TI
5494
5495/*
5496 * OK, here we have finally the patch for ALC880
5497 */
5498
1da177e4
LT
5499static int patch_alc880(struct hda_codec *codec)
5500{
5501 struct alc_spec *spec;
5502 int board_config;
df694daa 5503 int err;
1da177e4 5504
e560d8d8 5505 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5506 if (spec == NULL)
5507 return -ENOMEM;
5508
5509 codec->spec = spec;
5510
f5fcc13c
TI
5511 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5512 alc880_models,
5513 alc880_cfg_tbl);
5514 if (board_config < 0) {
9a11f1aa
TI
5515 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5516 codec->chip_name);
e9edcee0 5517 board_config = ALC880_AUTO;
1da177e4 5518 }
1da177e4 5519
e9edcee0
TI
5520 if (board_config == ALC880_AUTO) {
5521 /* automatic parse from the BIOS config */
5522 err = alc880_parse_auto_config(codec);
5523 if (err < 0) {
5524 alc_free(codec);
5525 return err;
f12ab1e0 5526 } else if (!err) {
9c7f852e
TI
5527 printk(KERN_INFO
5528 "hda_codec: Cannot set up configuration "
5529 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5530 board_config = ALC880_3ST;
5531 }
1da177e4
LT
5532 }
5533
680cd536
KK
5534 err = snd_hda_attach_beep_device(codec, 0x1);
5535 if (err < 0) {
5536 alc_free(codec);
5537 return err;
5538 }
5539
df694daa 5540 if (board_config != ALC880_AUTO)
e9c364c0 5541 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5542
1da177e4
LT
5543 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5544 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5545 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5546
1da177e4
LT
5547 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5548 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5549
f12ab1e0 5550 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5551 /* check whether NID 0x07 is valid */
54d17403 5552 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5553 /* get type */
a22d543a 5554 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5555 if (wcap != AC_WID_AUD_IN) {
5556 spec->adc_nids = alc880_adc_nids_alt;
5557 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5558 } else {
5559 spec->adc_nids = alc880_adc_nids;
5560 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5561 }
5562 }
b59bdf3b 5563 set_capture_mixer(codec);
45bdd1c1 5564 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5565
2134ea4f
TI
5566 spec->vmaster_nid = 0x0c;
5567
1da177e4 5568 codec->patch_ops = alc_patch_ops;
e9edcee0 5569 if (board_config == ALC880_AUTO)
ae6b813a 5570 spec->init_hook = alc880_auto_init;
cb53c626
TI
5571#ifdef CONFIG_SND_HDA_POWER_SAVE
5572 if (!spec->loopback.amplist)
5573 spec->loopback.amplist = alc880_loopbacks;
5574#endif
1da177e4
LT
5575
5576 return 0;
5577}
5578
e9edcee0 5579
1da177e4
LT
5580/*
5581 * ALC260 support
5582 */
5583
e9edcee0
TI
5584static hda_nid_t alc260_dac_nids[1] = {
5585 /* front */
5586 0x02,
5587};
5588
5589static hda_nid_t alc260_adc_nids[1] = {
5590 /* ADC0 */
5591 0x04,
5592};
5593
df694daa 5594static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5595 /* ADC1 */
5596 0x05,
5597};
5598
d57fdac0
JW
5599/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5600 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5601 */
5602static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5603 /* ADC0, ADC1 */
5604 0x04, 0x05
5605};
5606
e9edcee0
TI
5607#define ALC260_DIGOUT_NID 0x03
5608#define ALC260_DIGIN_NID 0x06
5609
5610static struct hda_input_mux alc260_capture_source = {
5611 .num_items = 4,
5612 .items = {
5613 { "Mic", 0x0 },
5614 { "Front Mic", 0x1 },
5615 { "Line", 0x2 },
5616 { "CD", 0x4 },
5617 },
5618};
5619
17e7aec6 5620/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5621 * headphone jack and the internal CD lines since these are the only pins at
5622 * which audio can appear. For flexibility, also allow the option of
5623 * recording the mixer output on the second ADC (ADC0 doesn't have a
5624 * connection to the mixer output).
a9430dd8 5625 */
a1e8d2da
JW
5626static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5627 {
5628 .num_items = 3,
5629 .items = {
5630 { "Mic/Line", 0x0 },
5631 { "CD", 0x4 },
5632 { "Headphone", 0x2 },
5633 },
a9430dd8 5634 },
a1e8d2da
JW
5635 {
5636 .num_items = 4,
5637 .items = {
5638 { "Mic/Line", 0x0 },
5639 { "CD", 0x4 },
5640 { "Headphone", 0x2 },
5641 { "Mixer", 0x5 },
5642 },
5643 },
5644
a9430dd8
JW
5645};
5646
a1e8d2da
JW
5647/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5648 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5649 */
a1e8d2da
JW
5650static struct hda_input_mux alc260_acer_capture_sources[2] = {
5651 {
5652 .num_items = 4,
5653 .items = {
5654 { "Mic", 0x0 },
5655 { "Line", 0x2 },
5656 { "CD", 0x4 },
5657 { "Headphone", 0x5 },
5658 },
5659 },
5660 {
5661 .num_items = 5,
5662 .items = {
5663 { "Mic", 0x0 },
5664 { "Line", 0x2 },
5665 { "CD", 0x4 },
5666 { "Headphone", 0x6 },
5667 { "Mixer", 0x5 },
5668 },
0bfc90e9
JW
5669 },
5670};
cc959489
MS
5671
5672/* Maxdata Favorit 100XS */
5673static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5674 {
5675 .num_items = 2,
5676 .items = {
5677 { "Line/Mic", 0x0 },
5678 { "CD", 0x4 },
5679 },
5680 },
5681 {
5682 .num_items = 3,
5683 .items = {
5684 { "Line/Mic", 0x0 },
5685 { "CD", 0x4 },
5686 { "Mixer", 0x5 },
5687 },
5688 },
5689};
5690
1da177e4
LT
5691/*
5692 * This is just place-holder, so there's something for alc_build_pcms to look
5693 * at when it calculates the maximum number of channels. ALC260 has no mixer
5694 * element which allows changing the channel mode, so the verb list is
5695 * never used.
5696 */
d2a6d7dc 5697static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5698 { 2, NULL },
5699};
5700
df694daa
KY
5701
5702/* Mixer combinations
5703 *
5704 * basic: base_output + input + pc_beep + capture
5705 * HP: base_output + input + capture_alt
5706 * HP_3013: hp_3013 + input + capture
5707 * fujitsu: fujitsu + capture
0bfc90e9 5708 * acer: acer + capture
df694daa
KY
5709 */
5710
5711static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5712 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5713 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5714 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5715 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5716 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5717 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5718 { } /* end */
f12ab1e0 5719};
1da177e4 5720
df694daa 5721static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5722 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5723 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5724 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5725 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5726 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5727 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5728 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5729 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5730 { } /* end */
5731};
5732
bec15c3a
TI
5733/* update HP, line and mono out pins according to the master switch */
5734static void alc260_hp_master_update(struct hda_codec *codec,
5735 hda_nid_t hp, hda_nid_t line,
5736 hda_nid_t mono)
5737{
5738 struct alc_spec *spec = codec->spec;
5739 unsigned int val = spec->master_sw ? PIN_HP : 0;
5740 /* change HP and line-out pins */
30cde0aa 5741 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5742 val);
30cde0aa 5743 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5744 val);
5745 /* mono (speaker) depending on the HP jack sense */
5746 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5747 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5748 val);
5749}
5750
5751static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5752 struct snd_ctl_elem_value *ucontrol)
5753{
5754 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5755 struct alc_spec *spec = codec->spec;
5756 *ucontrol->value.integer.value = spec->master_sw;
5757 return 0;
5758}
5759
5760static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5761 struct snd_ctl_elem_value *ucontrol)
5762{
5763 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5764 struct alc_spec *spec = codec->spec;
5765 int val = !!*ucontrol->value.integer.value;
5766 hda_nid_t hp, line, mono;
5767
5768 if (val == spec->master_sw)
5769 return 0;
5770 spec->master_sw = val;
5771 hp = (kcontrol->private_value >> 16) & 0xff;
5772 line = (kcontrol->private_value >> 8) & 0xff;
5773 mono = kcontrol->private_value & 0xff;
5774 alc260_hp_master_update(codec, hp, line, mono);
5775 return 1;
5776}
5777
5778static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5779 {
5780 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5781 .name = "Master Playback Switch",
5b0cb1d8 5782 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5783 .info = snd_ctl_boolean_mono_info,
5784 .get = alc260_hp_master_sw_get,
5785 .put = alc260_hp_master_sw_put,
5786 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5787 },
5788 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5789 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5790 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5791 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5792 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5793 HDA_OUTPUT),
5794 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5795 { } /* end */
5796};
5797
5798static struct hda_verb alc260_hp_unsol_verbs[] = {
5799 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5800 {},
5801};
5802
5803static void alc260_hp_automute(struct hda_codec *codec)
5804{
5805 struct alc_spec *spec = codec->spec;
bec15c3a 5806
864f92be 5807 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5808 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5809}
5810
5811static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5812{
5813 if ((res >> 26) == ALC880_HP_EVENT)
5814 alc260_hp_automute(codec);
5815}
5816
df694daa 5817static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5818 {
5819 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5820 .name = "Master Playback Switch",
5b0cb1d8 5821 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5822 .info = snd_ctl_boolean_mono_info,
5823 .get = alc260_hp_master_sw_get,
5824 .put = alc260_hp_master_sw_put,
30cde0aa 5825 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5826 },
df694daa
KY
5827 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5828 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5829 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5830 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5831 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5832 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
5833 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5834 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
5835 { } /* end */
5836};
5837
3f878308
KY
5838static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5839 .ops = &snd_hda_bind_vol,
5840 .values = {
5841 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5842 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5843 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5844 0
5845 },
5846};
5847
5848static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5849 .ops = &snd_hda_bind_sw,
5850 .values = {
5851 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5852 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5853 0
5854 },
5855};
5856
5857static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5858 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5859 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5860 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5861 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5862 { } /* end */
5863};
5864
bec15c3a
TI
5865static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5866 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5867 {},
5868};
5869
5870static void alc260_hp_3013_automute(struct hda_codec *codec)
5871{
5872 struct alc_spec *spec = codec->spec;
bec15c3a 5873
864f92be 5874 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 5875 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
5876}
5877
5878static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5879 unsigned int res)
5880{
5881 if ((res >> 26) == ALC880_HP_EVENT)
5882 alc260_hp_3013_automute(codec);
5883}
5884
3f878308
KY
5885static void alc260_hp_3012_automute(struct hda_codec *codec)
5886{
864f92be 5887 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 5888
3f878308
KY
5889 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5890 bits);
5891 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5892 bits);
5893 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5894 bits);
5895}
5896
5897static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5898 unsigned int res)
5899{
5900 if ((res >> 26) == ALC880_HP_EVENT)
5901 alc260_hp_3012_automute(codec);
5902}
5903
5904/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
5905 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5906 */
c8b6bf9b 5907static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 5908 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5909 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 5910 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
5911 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5912 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5913 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5914 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 5915 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
5916 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5917 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
5918 { } /* end */
5919};
5920
a1e8d2da
JW
5921/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5922 * versions of the ALC260 don't act on requests to enable mic bias from NID
5923 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5924 * datasheet doesn't mention this restriction. At this stage it's not clear
5925 * whether this behaviour is intentional or is a hardware bug in chip
5926 * revisions available in early 2006. Therefore for now allow the
5927 * "Headphone Jack Mode" control to span all choices, but if it turns out
5928 * that the lack of mic bias for this NID is intentional we could change the
5929 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5930 *
5931 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5932 * don't appear to make the mic bias available from the "line" jack, even
5933 * though the NID used for this jack (0x14) can supply it. The theory is
5934 * that perhaps Acer have included blocking capacitors between the ALC260
5935 * and the output jack. If this turns out to be the case for all such
5936 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5937 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
5938 *
5939 * The C20x Tablet series have a mono internal speaker which is controlled
5940 * via the chip's Mono sum widget and pin complex, so include the necessary
5941 * controls for such models. On models without a "mono speaker" the control
5942 * won't do anything.
a1e8d2da 5943 */
0bfc90e9
JW
5944static struct snd_kcontrol_new alc260_acer_mixer[] = {
5945 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5946 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 5947 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 5948 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 5949 HDA_OUTPUT),
31bffaa9 5950 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 5951 HDA_INPUT),
0bfc90e9
JW
5952 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5953 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5954 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5955 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5956 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5957 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5958 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5959 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
5960 { } /* end */
5961};
5962
cc959489
MS
5963/* Maxdata Favorit 100XS: one output and one input (0x12) jack
5964 */
5965static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5966 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5967 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5968 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5969 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5970 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5971 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5972 { } /* end */
5973};
5974
bc9f98a9
KY
5975/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5976 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5977 */
5978static struct snd_kcontrol_new alc260_will_mixer[] = {
5979 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5980 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5981 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5982 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5983 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5984 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5985 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5986 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5987 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5988 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
5989 { } /* end */
5990};
5991
5992/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5993 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5994 */
5995static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5996 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5997 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5998 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5999 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6000 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6001 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6002 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6003 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6004 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6005 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6006 { } /* end */
6007};
6008
df694daa
KY
6009/*
6010 * initialization verbs
6011 */
1da177e4
LT
6012static struct hda_verb alc260_init_verbs[] = {
6013 /* Line In pin widget for input */
05acb863 6014 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6015 /* CD pin widget for input */
05acb863 6016 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6017 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6018 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6019 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6020 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6021 /* LINE-2 is used for line-out in rear */
05acb863 6022 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6023 /* select line-out */
fd56f2db 6024 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6025 /* LINE-OUT pin */
05acb863 6026 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6027 /* enable HP */
05acb863 6028 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6029 /* enable Mono */
05acb863
TI
6030 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6031 /* mute capture amp left and right */
16ded525 6032 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6033 /* set connection select to line in (default select for this ADC) */
6034 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6035 /* mute capture amp left and right */
6036 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6037 /* set connection select to line in (default select for this ADC) */
6038 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6039 /* set vol=0 Line-Out mixer amp left and right */
6040 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6041 /* unmute pin widget amp left and right (no gain on this amp) */
6042 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6043 /* set vol=0 HP mixer amp left and right */
6044 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6045 /* unmute pin widget amp left and right (no gain on this amp) */
6046 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6047 /* set vol=0 Mono mixer amp left and right */
6048 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6049 /* unmute pin widget amp left and right (no gain on this amp) */
6050 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6051 /* unmute LINE-2 out pin */
6052 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6053 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6054 * Line In 2 = 0x03
6055 */
cb53c626
TI
6056 /* mute analog inputs */
6057 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6058 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6059 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6060 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6061 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6062 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6063 /* mute Front out path */
6064 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6065 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6066 /* mute Headphone out path */
6067 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6068 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6069 /* mute Mono out path */
6070 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6071 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6072 { }
6073};
6074
474167d6 6075#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
6076static struct hda_verb alc260_hp_init_verbs[] = {
6077 /* Headphone and output */
6078 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6079 /* mono output */
6080 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6081 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6082 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6083 /* Mic2 (front panel) pin widget for input and vref at 80% */
6084 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6085 /* Line In pin widget for input */
6086 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6087 /* Line-2 pin widget for output */
6088 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6089 /* CD pin widget for input */
6090 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6091 /* unmute amp left and right */
6092 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6093 /* set connection select to line in (default select for this ADC) */
6094 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6095 /* unmute Line-Out mixer amp left and right (volume = 0) */
6096 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6097 /* mute pin widget amp left and right (no gain on this amp) */
6098 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6099 /* unmute HP mixer amp left and right (volume = 0) */
6100 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6101 /* mute pin widget amp left and right (no gain on this amp) */
6102 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6103 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6104 * Line In 2 = 0x03
6105 */
cb53c626
TI
6106 /* mute analog inputs */
6107 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6108 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6109 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6110 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6111 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6112 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6113 /* Unmute Front out path */
6114 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6115 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6116 /* Unmute Headphone out path */
6117 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6118 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6119 /* Unmute Mono out path */
6120 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6121 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6122 { }
6123};
474167d6 6124#endif
df694daa
KY
6125
6126static struct hda_verb alc260_hp_3013_init_verbs[] = {
6127 /* Line out and output */
6128 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6129 /* mono output */
6130 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6131 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6132 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6133 /* Mic2 (front panel) pin widget for input and vref at 80% */
6134 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6135 /* Line In pin widget for input */
6136 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6137 /* Headphone pin widget for output */
6138 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6139 /* CD pin widget for input */
6140 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6141 /* unmute amp left and right */
6142 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6143 /* set connection select to line in (default select for this ADC) */
6144 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6145 /* unmute Line-Out mixer amp left and right (volume = 0) */
6146 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6147 /* mute pin widget amp left and right (no gain on this amp) */
6148 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6149 /* unmute HP mixer amp left and right (volume = 0) */
6150 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6151 /* mute pin widget amp left and right (no gain on this amp) */
6152 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6153 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6154 * Line In 2 = 0x03
6155 */
cb53c626
TI
6156 /* mute analog inputs */
6157 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6158 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6159 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6160 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6161 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6162 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6163 /* Unmute Front out path */
6164 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6165 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6166 /* Unmute Headphone out path */
6167 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6168 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6169 /* Unmute Mono out path */
6170 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6171 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6172 { }
6173};
6174
a9430dd8 6175/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6176 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6177 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
6178 */
6179static struct hda_verb alc260_fujitsu_init_verbs[] = {
6180 /* Disable all GPIOs */
6181 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6182 /* Internal speaker is connected to headphone pin */
6183 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6184 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6185 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6186 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6187 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6188 /* Ensure all other unused pins are disabled and muted. */
6189 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6190 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6191 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6192 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6193 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6194 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6195 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6196 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6197
6198 /* Disable digital (SPDIF) pins */
6199 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6200 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6201
ea1fb29a 6202 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6203 * when acting as an output.
6204 */
6205 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6206
f7ace40d 6207 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6208 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6209 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6210 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6211 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6212 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6213 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6214 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6215 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6216 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6217
f7ace40d
JW
6218 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6219 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6220 /* Unmute Line1 pin widget output buffer since it starts as an output.
6221 * If the pin mode is changed by the user the pin mode control will
6222 * take care of enabling the pin's input/output buffers as needed.
6223 * Therefore there's no need to enable the input buffer at this
6224 * stage.
cdcd9268 6225 */
f7ace40d 6226 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6227 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6228 * mixer ctrl)
6229 */
f7ace40d
JW
6230 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6231
6232 /* Mute capture amp left and right */
6233 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6234 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6235 * in (on mic1 pin)
6236 */
6237 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6238
6239 /* Do the same for the second ADC: mute capture input amp and
6240 * set ADC connection to line in (on mic1 pin)
6241 */
6242 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6243 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6244
6245 /* Mute all inputs to mixer widget (even unconnected ones) */
6246 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6247 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6248 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6249 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6250 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6251 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6252 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6253 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6254
6255 { }
a9430dd8
JW
6256};
6257
0bfc90e9
JW
6258/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6259 * similar laptops (adapted from Fujitsu init verbs).
6260 */
6261static struct hda_verb alc260_acer_init_verbs[] = {
6262 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6263 * the headphone jack. Turn this on and rely on the standard mute
6264 * methods whenever the user wants to turn these outputs off.
6265 */
6266 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6267 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6268 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6269 /* Internal speaker/Headphone jack is connected to Line-out pin */
6270 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6271 /* Internal microphone/Mic jack is connected to Mic1 pin */
6272 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6273 /* Line In jack is connected to Line1 pin */
6274 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6275 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6276 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6277 /* Ensure all other unused pins are disabled and muted. */
6278 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6279 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6280 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6281 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6282 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6283 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6284 /* Disable digital (SPDIF) pins */
6285 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6286 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6287
ea1fb29a 6288 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6289 * bus when acting as outputs.
6290 */
6291 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6292 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6293
6294 /* Start with output sum widgets muted and their output gains at min */
6295 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6296 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6297 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6298 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6299 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6300 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6301 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6302 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6303 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6304
f12ab1e0
TI
6305 /* Unmute Line-out pin widget amp left and right
6306 * (no equiv mixer ctrl)
6307 */
0bfc90e9 6308 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6309 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6310 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6311 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6312 * inputs. If the pin mode is changed by the user the pin mode control
6313 * will take care of enabling the pin's input/output buffers as needed.
6314 * Therefore there's no need to enable the input buffer at this
6315 * stage.
6316 */
6317 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6318 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6319
6320 /* Mute capture amp left and right */
6321 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6322 /* Set ADC connection select to match default mixer setting - mic
6323 * (on mic1 pin)
6324 */
6325 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6326
6327 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6328 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6329 */
6330 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6331 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6332
6333 /* Mute all inputs to mixer widget (even unconnected ones) */
6334 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6335 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6336 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6337 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6338 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6339 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6340 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6341 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6342
6343 { }
6344};
6345
cc959489
MS
6346/* Initialisation sequence for Maxdata Favorit 100XS
6347 * (adapted from Acer init verbs).
6348 */
6349static struct hda_verb alc260_favorit100_init_verbs[] = {
6350 /* GPIO 0 enables the output jack.
6351 * Turn this on and rely on the standard mute
6352 * methods whenever the user wants to turn these outputs off.
6353 */
6354 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6355 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6356 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6357 /* Line/Mic input jack is connected to Mic1 pin */
6358 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6359 /* Ensure all other unused pins are disabled and muted. */
6360 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6361 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6362 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6363 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6364 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6365 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6366 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6367 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6368 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6369 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6370 /* Disable digital (SPDIF) pins */
6371 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6372 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6373
6374 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6375 * bus when acting as outputs.
6376 */
6377 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6378 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6379
6380 /* Start with output sum widgets muted and their output gains at min */
6381 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6382 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6383 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6384 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6385 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6386 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6387 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6388 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6389 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6390
6391 /* Unmute Line-out pin widget amp left and right
6392 * (no equiv mixer ctrl)
6393 */
6394 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6395 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6396 * inputs. If the pin mode is changed by the user the pin mode control
6397 * will take care of enabling the pin's input/output buffers as needed.
6398 * Therefore there's no need to enable the input buffer at this
6399 * stage.
6400 */
6401 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6402
6403 /* Mute capture amp left and right */
6404 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6405 /* Set ADC connection select to match default mixer setting - mic
6406 * (on mic1 pin)
6407 */
6408 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6409
6410 /* Do similar with the second ADC: mute capture input amp and
6411 * set ADC connection to mic to match ALSA's default state.
6412 */
6413 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6414 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6415
6416 /* Mute all inputs to mixer widget (even unconnected ones) */
6417 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6418 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6419 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6420 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6421 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6422 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6423 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6424 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6425
6426 { }
6427};
6428
bc9f98a9
KY
6429static struct hda_verb alc260_will_verbs[] = {
6430 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6431 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6432 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6433 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6434 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6435 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6436 {}
6437};
6438
6439static struct hda_verb alc260_replacer_672v_verbs[] = {
6440 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6441 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6442 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6443
6444 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6445 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6446 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6447
6448 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6449 {}
6450};
6451
6452/* toggle speaker-output according to the hp-jack state */
6453static void alc260_replacer_672v_automute(struct hda_codec *codec)
6454{
6455 unsigned int present;
6456
6457 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6458 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6459 if (present) {
82beb8fd
TI
6460 snd_hda_codec_write_cache(codec, 0x01, 0,
6461 AC_VERB_SET_GPIO_DATA, 1);
6462 snd_hda_codec_write_cache(codec, 0x0f, 0,
6463 AC_VERB_SET_PIN_WIDGET_CONTROL,
6464 PIN_HP);
bc9f98a9 6465 } else {
82beb8fd
TI
6466 snd_hda_codec_write_cache(codec, 0x01, 0,
6467 AC_VERB_SET_GPIO_DATA, 0);
6468 snd_hda_codec_write_cache(codec, 0x0f, 0,
6469 AC_VERB_SET_PIN_WIDGET_CONTROL,
6470 PIN_OUT);
bc9f98a9
KY
6471 }
6472}
6473
6474static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6475 unsigned int res)
6476{
6477 if ((res >> 26) == ALC880_HP_EVENT)
6478 alc260_replacer_672v_automute(codec);
6479}
6480
3f878308
KY
6481static struct hda_verb alc260_hp_dc7600_verbs[] = {
6482 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6483 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6484 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6485 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6486 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6487 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6488 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6489 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6490 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6491 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6492 {}
6493};
6494
7cf51e48
JW
6495/* Test configuration for debugging, modelled after the ALC880 test
6496 * configuration.
6497 */
6498#ifdef CONFIG_SND_DEBUG
6499static hda_nid_t alc260_test_dac_nids[1] = {
6500 0x02,
6501};
6502static hda_nid_t alc260_test_adc_nids[2] = {
6503 0x04, 0x05,
6504};
a1e8d2da 6505/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6506 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6507 * is NID 0x04.
17e7aec6 6508 */
a1e8d2da
JW
6509static struct hda_input_mux alc260_test_capture_sources[2] = {
6510 {
6511 .num_items = 7,
6512 .items = {
6513 { "MIC1 pin", 0x0 },
6514 { "MIC2 pin", 0x1 },
6515 { "LINE1 pin", 0x2 },
6516 { "LINE2 pin", 0x3 },
6517 { "CD pin", 0x4 },
6518 { "LINE-OUT pin", 0x5 },
6519 { "HP-OUT pin", 0x6 },
6520 },
6521 },
6522 {
6523 .num_items = 8,
6524 .items = {
6525 { "MIC1 pin", 0x0 },
6526 { "MIC2 pin", 0x1 },
6527 { "LINE1 pin", 0x2 },
6528 { "LINE2 pin", 0x3 },
6529 { "CD pin", 0x4 },
6530 { "Mixer", 0x5 },
6531 { "LINE-OUT pin", 0x6 },
6532 { "HP-OUT pin", 0x7 },
6533 },
7cf51e48
JW
6534 },
6535};
6536static struct snd_kcontrol_new alc260_test_mixer[] = {
6537 /* Output driver widgets */
6538 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6539 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6540 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6541 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6542 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6543 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6544
a1e8d2da
JW
6545 /* Modes for retasking pin widgets
6546 * Note: the ALC260 doesn't seem to act on requests to enable mic
6547 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6548 * mention this restriction. At this stage it's not clear whether
6549 * this behaviour is intentional or is a hardware bug in chip
6550 * revisions available at least up until early 2006. Therefore for
6551 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6552 * choices, but if it turns out that the lack of mic bias for these
6553 * NIDs is intentional we could change their modes from
6554 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6555 */
7cf51e48
JW
6556 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6557 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6558 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6559 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6560 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6561 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6562
6563 /* Loopback mixer controls */
6564 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6565 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6566 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6567 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6568 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6569 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6570 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6571 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6572 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6573 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6574 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6575 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6576 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6577 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6578
6579 /* Controls for GPIO pins, assuming they are configured as outputs */
6580 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6581 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6582 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6583 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6584
92621f13
JW
6585 /* Switches to allow the digital IO pins to be enabled. The datasheet
6586 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6587 * make this output available should provide clarification.
92621f13
JW
6588 */
6589 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6590 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6591
f8225f6d
JW
6592 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6593 * this output to turn on an external amplifier.
6594 */
6595 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6596 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6597
7cf51e48
JW
6598 { } /* end */
6599};
6600static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6601 /* Enable all GPIOs as outputs with an initial value of 0 */
6602 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6603 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6604 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6605
7cf51e48
JW
6606 /* Enable retasking pins as output, initially without power amp */
6607 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6608 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6609 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6610 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6611 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6612 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6613
92621f13
JW
6614 /* Disable digital (SPDIF) pins initially, but users can enable
6615 * them via a mixer switch. In the case of SPDIF-out, this initverb
6616 * payload also sets the generation to 0, output to be in "consumer"
6617 * PCM format, copyright asserted, no pre-emphasis and no validity
6618 * control.
6619 */
7cf51e48
JW
6620 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6621 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6622
ea1fb29a 6623 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6624 * OUT1 sum bus when acting as an output.
6625 */
6626 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6627 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6628 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6629 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6630
6631 /* Start with output sum widgets muted and their output gains at min */
6632 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6633 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6634 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6635 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6636 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6637 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6638 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6639 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6640 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6641
cdcd9268
JW
6642 /* Unmute retasking pin widget output buffers since the default
6643 * state appears to be output. As the pin mode is changed by the
6644 * user the pin mode control will take care of enabling the pin's
6645 * input/output buffers as needed.
6646 */
7cf51e48
JW
6647 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6648 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6649 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6650 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6651 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6652 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6653 /* Also unmute the mono-out pin widget */
6654 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6655
7cf51e48
JW
6656 /* Mute capture amp left and right */
6657 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6658 /* Set ADC connection select to match default mixer setting (mic1
6659 * pin)
7cf51e48
JW
6660 */
6661 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6662
6663 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6664 * set ADC connection to mic1 pin
7cf51e48
JW
6665 */
6666 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6667 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6668
6669 /* Mute all inputs to mixer widget (even unconnected ones) */
6670 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6671 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6672 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6673 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6674 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6675 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6676 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6677 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6678
6679 { }
6680};
6681#endif
6682
6330079f
TI
6683#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6684#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6685
a3bcba38
TI
6686#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6687#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6688
df694daa
KY
6689/*
6690 * for BIOS auto-configuration
6691 */
16ded525 6692
df694daa 6693static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6694 const char *pfx, int *vol_bits)
df694daa
KY
6695{
6696 hda_nid_t nid_vol;
6697 unsigned long vol_val, sw_val;
df694daa
KY
6698 int err;
6699
6700 if (nid >= 0x0f && nid < 0x11) {
6701 nid_vol = nid - 0x7;
6702 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6703 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6704 } else if (nid == 0x11) {
6705 nid_vol = nid - 0x7;
6706 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6707 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6708 } else if (nid >= 0x12 && nid <= 0x15) {
6709 nid_vol = 0x08;
6710 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6711 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6712 } else
6713 return 0; /* N/A */
ea1fb29a 6714
863b4518
TI
6715 if (!(*vol_bits & (1 << nid_vol))) {
6716 /* first control for the volume widget */
0afe5f89 6717 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6718 if (err < 0)
6719 return err;
6720 *vol_bits |= (1 << nid_vol);
6721 }
0afe5f89 6722 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6723 if (err < 0)
df694daa
KY
6724 return err;
6725 return 1;
6726}
6727
6728/* add playback controls from the parsed DAC table */
6729static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6730 const struct auto_pin_cfg *cfg)
6731{
6732 hda_nid_t nid;
6733 int err;
863b4518 6734 int vols = 0;
df694daa
KY
6735
6736 spec->multiout.num_dacs = 1;
6737 spec->multiout.dac_nids = spec->private_dac_nids;
6738 spec->multiout.dac_nids[0] = 0x02;
6739
6740 nid = cfg->line_out_pins[0];
6741 if (nid) {
23112d6d
TI
6742 const char *pfx;
6743 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6744 pfx = "Master";
6745 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6746 pfx = "Speaker";
6747 else
6748 pfx = "Front";
6749 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6750 if (err < 0)
6751 return err;
6752 }
6753
82bc955f 6754 nid = cfg->speaker_pins[0];
df694daa 6755 if (nid) {
863b4518 6756 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6757 if (err < 0)
6758 return err;
6759 }
6760
eb06ed8f 6761 nid = cfg->hp_pins[0];
df694daa 6762 if (nid) {
863b4518
TI
6763 err = alc260_add_playback_controls(spec, nid, "Headphone",
6764 &vols);
df694daa
KY
6765 if (err < 0)
6766 return err;
6767 }
f12ab1e0 6768 return 0;
df694daa
KY
6769}
6770
6771/* create playback/capture controls for input pins */
05f5f477 6772static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6773 const struct auto_pin_cfg *cfg)
6774{
05f5f477 6775 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6776}
6777
6778static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6779 hda_nid_t nid, int pin_type,
6780 int sel_idx)
6781{
f6c7e546 6782 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6783 /* need the manual connection? */
6784 if (nid >= 0x12) {
6785 int idx = nid - 0x12;
6786 snd_hda_codec_write(codec, idx + 0x0b, 0,
6787 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6788 }
6789}
6790
6791static void alc260_auto_init_multi_out(struct hda_codec *codec)
6792{
6793 struct alc_spec *spec = codec->spec;
6794 hda_nid_t nid;
6795
f12ab1e0 6796 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6797 if (nid) {
6798 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6799 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6800 }
ea1fb29a 6801
82bc955f 6802 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6803 if (nid)
6804 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6805
eb06ed8f 6806 nid = spec->autocfg.hp_pins[0];
df694daa 6807 if (nid)
baba8ee9 6808 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6809}
df694daa
KY
6810
6811#define ALC260_PIN_CD_NID 0x16
6812static void alc260_auto_init_analog_input(struct hda_codec *codec)
6813{
6814 struct alc_spec *spec = codec->spec;
66ceeb6b 6815 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
6816 int i;
6817
66ceeb6b
TI
6818 for (i = 0; i < cfg->num_inputs; i++) {
6819 hda_nid_t nid = cfg->inputs[i].pin;
df694daa 6820 if (nid >= 0x12) {
30ea098f 6821 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
6822 if (nid != ALC260_PIN_CD_NID &&
6823 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6824 snd_hda_codec_write(codec, nid, 0,
6825 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6826 AMP_OUT_MUTE);
6827 }
6828 }
6829}
6830
7f311a46
TI
6831#define alc260_auto_init_input_src alc880_auto_init_input_src
6832
df694daa
KY
6833/*
6834 * generic initialization of ADC, input mixers and output mixers
6835 */
6836static struct hda_verb alc260_volume_init_verbs[] = {
6837 /*
6838 * Unmute ADC0-1 and set the default input to mic-in
6839 */
6840 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6841 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6842 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6843 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 6844
df694daa
KY
6845 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6846 * mixer widget
f12ab1e0
TI
6847 * Note: PASD motherboards uses the Line In 2 as the input for
6848 * front panel mic (mic 2)
df694daa
KY
6849 */
6850 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6851 /* mute analog inputs */
6852 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6853 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6854 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6855 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6856 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6857
6858 /*
6859 * Set up output mixers (0x08 - 0x0a)
6860 */
6861 /* set vol=0 to output mixers */
6862 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6863 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6864 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6865 /* set up input amps for analog loopback */
6866 /* Amp Indices: DAC = 0, mixer = 1 */
6867 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6868 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6869 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6870 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6871 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6872 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 6873
df694daa
KY
6874 { }
6875};
6876
6877static int alc260_parse_auto_config(struct hda_codec *codec)
6878{
6879 struct alc_spec *spec = codec->spec;
df694daa
KY
6880 int err;
6881 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6882
f12ab1e0
TI
6883 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6884 alc260_ignore);
6885 if (err < 0)
df694daa 6886 return err;
f12ab1e0
TI
6887 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6888 if (err < 0)
4a471b7d 6889 return err;
603c4019 6890 if (!spec->kctls.list)
df694daa 6891 return 0; /* can't find valid BIOS pin config */
05f5f477 6892 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 6893 if (err < 0)
df694daa
KY
6894 return err;
6895
6896 spec->multiout.max_channels = 2;
6897
0852d7a6 6898 if (spec->autocfg.dig_outs)
df694daa 6899 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 6900 if (spec->kctls.list)
d88897ea 6901 add_mixer(spec, spec->kctls.list);
df694daa 6902
d88897ea 6903 add_verb(spec, alc260_volume_init_verbs);
df694daa 6904
a1e8d2da 6905 spec->num_mux_defs = 1;
61b9b9b1 6906 spec->input_mux = &spec->private_imux[0];
df694daa 6907
6227cdce 6908 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 6909
df694daa
KY
6910 return 1;
6911}
6912
ae6b813a
TI
6913/* additional initialization for auto-configuration model */
6914static void alc260_auto_init(struct hda_codec *codec)
df694daa 6915{
f6c7e546 6916 struct alc_spec *spec = codec->spec;
df694daa
KY
6917 alc260_auto_init_multi_out(codec);
6918 alc260_auto_init_analog_input(codec);
7f311a46 6919 alc260_auto_init_input_src(codec);
757899ac 6920 alc_auto_init_digital(codec);
f6c7e546 6921 if (spec->unsol_event)
7fb0d78f 6922 alc_inithook(codec);
df694daa
KY
6923}
6924
cb53c626
TI
6925#ifdef CONFIG_SND_HDA_POWER_SAVE
6926static struct hda_amp_list alc260_loopbacks[] = {
6927 { 0x07, HDA_INPUT, 0 },
6928 { 0x07, HDA_INPUT, 1 },
6929 { 0x07, HDA_INPUT, 2 },
6930 { 0x07, HDA_INPUT, 3 },
6931 { 0x07, HDA_INPUT, 4 },
6932 { } /* end */
6933};
6934#endif
6935
fc091769
TI
6936/*
6937 * Pin config fixes
6938 */
6939enum {
6940 PINFIX_HP_DC5750,
6941};
6942
fc091769
TI
6943static const struct alc_fixup alc260_fixups[] = {
6944 [PINFIX_HP_DC5750] = {
73413b12
TI
6945 .pins = (const struct alc_pincfg[]) {
6946 { 0x11, 0x90130110 }, /* speaker */
6947 { }
6948 }
fc091769
TI
6949 },
6950};
6951
6952static struct snd_pci_quirk alc260_fixup_tbl[] = {
6953 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
6954 {}
6955};
6956
df694daa
KY
6957/*
6958 * ALC260 configurations
6959 */
f5fcc13c
TI
6960static const char *alc260_models[ALC260_MODEL_LAST] = {
6961 [ALC260_BASIC] = "basic",
6962 [ALC260_HP] = "hp",
6963 [ALC260_HP_3013] = "hp-3013",
2922c9af 6964 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
6965 [ALC260_FUJITSU_S702X] = "fujitsu",
6966 [ALC260_ACER] = "acer",
bc9f98a9
KY
6967 [ALC260_WILL] = "will",
6968 [ALC260_REPLACER_672V] = "replacer",
cc959489 6969 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 6970#ifdef CONFIG_SND_DEBUG
f5fcc13c 6971 [ALC260_TEST] = "test",
7cf51e48 6972#endif
f5fcc13c
TI
6973 [ALC260_AUTO] = "auto",
6974};
6975
6976static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 6977 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 6978 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 6979 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 6980 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 6981 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 6982 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 6983 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 6984 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 6985 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
6986 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6987 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6988 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6989 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6990 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6991 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6992 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6993 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6994 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 6995 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 6996 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
6997 {}
6998};
6999
7000static struct alc_config_preset alc260_presets[] = {
7001 [ALC260_BASIC] = {
7002 .mixers = { alc260_base_output_mixer,
45bdd1c1 7003 alc260_input_mixer },
df694daa
KY
7004 .init_verbs = { alc260_init_verbs },
7005 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7006 .dac_nids = alc260_dac_nids,
f9e336f6 7007 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7008 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7009 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7010 .channel_mode = alc260_modes,
7011 .input_mux = &alc260_capture_source,
7012 },
7013 [ALC260_HP] = {
bec15c3a 7014 .mixers = { alc260_hp_output_mixer,
f9e336f6 7015 alc260_input_mixer },
bec15c3a
TI
7016 .init_verbs = { alc260_init_verbs,
7017 alc260_hp_unsol_verbs },
df694daa
KY
7018 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7019 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7020 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7021 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7022 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7023 .channel_mode = alc260_modes,
7024 .input_mux = &alc260_capture_source,
bec15c3a
TI
7025 .unsol_event = alc260_hp_unsol_event,
7026 .init_hook = alc260_hp_automute,
df694daa 7027 },
3f878308
KY
7028 [ALC260_HP_DC7600] = {
7029 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7030 alc260_input_mixer },
3f878308
KY
7031 .init_verbs = { alc260_init_verbs,
7032 alc260_hp_dc7600_verbs },
7033 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7034 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7035 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7036 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7037 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7038 .channel_mode = alc260_modes,
7039 .input_mux = &alc260_capture_source,
7040 .unsol_event = alc260_hp_3012_unsol_event,
7041 .init_hook = alc260_hp_3012_automute,
7042 },
df694daa
KY
7043 [ALC260_HP_3013] = {
7044 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7045 alc260_input_mixer },
bec15c3a
TI
7046 .init_verbs = { alc260_hp_3013_init_verbs,
7047 alc260_hp_3013_unsol_verbs },
df694daa
KY
7048 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7049 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7050 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7051 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7052 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7053 .channel_mode = alc260_modes,
7054 .input_mux = &alc260_capture_source,
bec15c3a
TI
7055 .unsol_event = alc260_hp_3013_unsol_event,
7056 .init_hook = alc260_hp_3013_automute,
df694daa
KY
7057 },
7058 [ALC260_FUJITSU_S702X] = {
f9e336f6 7059 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7060 .init_verbs = { alc260_fujitsu_init_verbs },
7061 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7062 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7063 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7064 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7065 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7066 .channel_mode = alc260_modes,
a1e8d2da
JW
7067 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7068 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7069 },
0bfc90e9 7070 [ALC260_ACER] = {
f9e336f6 7071 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7072 .init_verbs = { alc260_acer_init_verbs },
7073 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7074 .dac_nids = alc260_dac_nids,
7075 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7076 .adc_nids = alc260_dual_adc_nids,
7077 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7078 .channel_mode = alc260_modes,
a1e8d2da
JW
7079 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7080 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7081 },
cc959489
MS
7082 [ALC260_FAVORIT100] = {
7083 .mixers = { alc260_favorit100_mixer },
7084 .init_verbs = { alc260_favorit100_init_verbs },
7085 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7086 .dac_nids = alc260_dac_nids,
7087 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7088 .adc_nids = alc260_dual_adc_nids,
7089 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7090 .channel_mode = alc260_modes,
7091 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7092 .input_mux = alc260_favorit100_capture_sources,
7093 },
bc9f98a9 7094 [ALC260_WILL] = {
f9e336f6 7095 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7096 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7097 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7098 .dac_nids = alc260_dac_nids,
7099 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7100 .adc_nids = alc260_adc_nids,
7101 .dig_out_nid = ALC260_DIGOUT_NID,
7102 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7103 .channel_mode = alc260_modes,
7104 .input_mux = &alc260_capture_source,
7105 },
7106 [ALC260_REPLACER_672V] = {
f9e336f6 7107 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7108 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7109 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7110 .dac_nids = alc260_dac_nids,
7111 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7112 .adc_nids = alc260_adc_nids,
7113 .dig_out_nid = ALC260_DIGOUT_NID,
7114 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7115 .channel_mode = alc260_modes,
7116 .input_mux = &alc260_capture_source,
7117 .unsol_event = alc260_replacer_672v_unsol_event,
7118 .init_hook = alc260_replacer_672v_automute,
7119 },
7cf51e48
JW
7120#ifdef CONFIG_SND_DEBUG
7121 [ALC260_TEST] = {
f9e336f6 7122 .mixers = { alc260_test_mixer },
7cf51e48
JW
7123 .init_verbs = { alc260_test_init_verbs },
7124 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7125 .dac_nids = alc260_test_dac_nids,
7126 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7127 .adc_nids = alc260_test_adc_nids,
7128 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7129 .channel_mode = alc260_modes,
a1e8d2da
JW
7130 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7131 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7132 },
7133#endif
df694daa
KY
7134};
7135
7136static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7137{
7138 struct alc_spec *spec;
df694daa 7139 int err, board_config;
1da177e4 7140
e560d8d8 7141 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7142 if (spec == NULL)
7143 return -ENOMEM;
7144
7145 codec->spec = spec;
7146
f5fcc13c
TI
7147 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7148 alc260_models,
7149 alc260_cfg_tbl);
7150 if (board_config < 0) {
9a11f1aa 7151 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7152 codec->chip_name);
df694daa 7153 board_config = ALC260_AUTO;
16ded525 7154 }
1da177e4 7155
fc091769
TI
7156 if (board_config == ALC260_AUTO)
7157 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 1);
7158
df694daa
KY
7159 if (board_config == ALC260_AUTO) {
7160 /* automatic parse from the BIOS config */
7161 err = alc260_parse_auto_config(codec);
7162 if (err < 0) {
7163 alc_free(codec);
7164 return err;
f12ab1e0 7165 } else if (!err) {
9c7f852e
TI
7166 printk(KERN_INFO
7167 "hda_codec: Cannot set up configuration "
7168 "from BIOS. Using base mode...\n");
df694daa
KY
7169 board_config = ALC260_BASIC;
7170 }
a9430dd8 7171 }
e9edcee0 7172
680cd536
KK
7173 err = snd_hda_attach_beep_device(codec, 0x1);
7174 if (err < 0) {
7175 alc_free(codec);
7176 return err;
7177 }
7178
df694daa 7179 if (board_config != ALC260_AUTO)
e9c364c0 7180 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7181
1da177e4
LT
7182 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7183 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7184 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7185
a3bcba38
TI
7186 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7187 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7188
4ef0ef19
TI
7189 if (!spec->adc_nids && spec->input_mux) {
7190 /* check whether NID 0x04 is valid */
7191 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7192 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7193 /* get type */
7194 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7195 spec->adc_nids = alc260_adc_nids_alt;
7196 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7197 } else {
7198 spec->adc_nids = alc260_adc_nids;
7199 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7200 }
7201 }
b59bdf3b 7202 set_capture_mixer(codec);
45bdd1c1 7203 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7204
fc091769
TI
7205 if (board_config == ALC260_AUTO)
7206 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 0);
7207
2134ea4f
TI
7208 spec->vmaster_nid = 0x08;
7209
1da177e4 7210 codec->patch_ops = alc_patch_ops;
df694daa 7211 if (board_config == ALC260_AUTO)
ae6b813a 7212 spec->init_hook = alc260_auto_init;
cb53c626
TI
7213#ifdef CONFIG_SND_HDA_POWER_SAVE
7214 if (!spec->loopback.amplist)
7215 spec->loopback.amplist = alc260_loopbacks;
7216#endif
1da177e4
LT
7217
7218 return 0;
7219}
7220
e9edcee0 7221
1da177e4 7222/*
4953550a 7223 * ALC882/883/885/888/889 support
1da177e4
LT
7224 *
7225 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7226 * configuration. Each pin widget can choose any input DACs and a mixer.
7227 * Each ADC is connected from a mixer of all inputs. This makes possible
7228 * 6-channel independent captures.
7229 *
7230 * In addition, an independent DAC for the multi-playback (not used in this
7231 * driver yet).
7232 */
df694daa
KY
7233#define ALC882_DIGOUT_NID 0x06
7234#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7235#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7236#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7237#define ALC1200_DIGOUT_NID 0x10
7238
1da177e4 7239
d2a6d7dc 7240static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7241 { 8, NULL }
7242};
7243
4953550a 7244/* DACs */
1da177e4
LT
7245static hda_nid_t alc882_dac_nids[4] = {
7246 /* front, rear, clfe, rear_surr */
7247 0x02, 0x03, 0x04, 0x05
7248};
4953550a 7249#define alc883_dac_nids alc882_dac_nids
1da177e4 7250
4953550a 7251/* ADCs */
df694daa
KY
7252#define alc882_adc_nids alc880_adc_nids
7253#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
7254#define alc883_adc_nids alc882_adc_nids_alt
7255static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7256static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7257#define alc889_adc_nids alc880_adc_nids
1da177e4 7258
e1406348
TI
7259static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7260static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
7261#define alc883_capsrc_nids alc882_capsrc_nids_alt
7262static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7263#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7264
1da177e4
LT
7265/* input MUX */
7266/* FIXME: should be a matrix-type input source selection */
7267
7268static struct hda_input_mux alc882_capture_source = {
7269 .num_items = 4,
7270 .items = {
7271 { "Mic", 0x0 },
7272 { "Front Mic", 0x1 },
7273 { "Line", 0x2 },
7274 { "CD", 0x4 },
7275 },
7276};
41d5545d 7277
4953550a
TI
7278#define alc883_capture_source alc882_capture_source
7279
87a8c370
JK
7280static struct hda_input_mux alc889_capture_source = {
7281 .num_items = 3,
7282 .items = {
7283 { "Front Mic", 0x0 },
7284 { "Mic", 0x3 },
7285 { "Line", 0x2 },
7286 },
7287};
7288
41d5545d
KS
7289static struct hda_input_mux mb5_capture_source = {
7290 .num_items = 3,
7291 .items = {
7292 { "Mic", 0x1 },
b8f171e7 7293 { "Line", 0x7 },
41d5545d
KS
7294 { "CD", 0x4 },
7295 },
7296};
7297
e458b1fa
LY
7298static struct hda_input_mux macmini3_capture_source = {
7299 .num_items = 2,
7300 .items = {
7301 { "Line", 0x2 },
7302 { "CD", 0x4 },
7303 },
7304};
7305
4953550a
TI
7306static struct hda_input_mux alc883_3stack_6ch_intel = {
7307 .num_items = 4,
7308 .items = {
7309 { "Mic", 0x1 },
7310 { "Front Mic", 0x0 },
7311 { "Line", 0x2 },
7312 { "CD", 0x4 },
7313 },
7314};
7315
7316static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7317 .num_items = 2,
7318 .items = {
7319 { "Mic", 0x1 },
7320 { "Line", 0x2 },
7321 },
7322};
7323
7324static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7325 .num_items = 4,
7326 .items = {
7327 { "Mic", 0x0 },
150b432f 7328 { "Int Mic", 0x1 },
4953550a
TI
7329 { "Line", 0x2 },
7330 { "CD", 0x4 },
7331 },
7332};
7333
7334static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7335 .num_items = 2,
7336 .items = {
7337 { "Mic", 0x0 },
7338 { "Int Mic", 0x1 },
7339 },
7340};
7341
7342static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7343 .num_items = 3,
7344 .items = {
7345 { "Mic", 0x0 },
7346 { "Front Mic", 0x1 },
7347 { "Line", 0x4 },
7348 },
7349};
7350
7351static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7352 .num_items = 2,
7353 .items = {
7354 { "Mic", 0x0 },
7355 { "Line", 0x2 },
7356 },
7357};
7358
7359static struct hda_input_mux alc889A_mb31_capture_source = {
7360 .num_items = 2,
7361 .items = {
7362 { "Mic", 0x0 },
7363 /* Front Mic (0x01) unused */
7364 { "Line", 0x2 },
7365 /* Line 2 (0x03) unused */
af901ca1 7366 /* CD (0x04) unused? */
4953550a
TI
7367 },
7368};
7369
b7cccc52
JM
7370static struct hda_input_mux alc889A_imac91_capture_source = {
7371 .num_items = 2,
7372 .items = {
7373 { "Mic", 0x01 },
7374 { "Line", 0x2 }, /* Not sure! */
7375 },
7376};
7377
4953550a
TI
7378/*
7379 * 2ch mode
7380 */
7381static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7382 { 2, NULL }
7383};
7384
272a527c
KY
7385/*
7386 * 2ch mode
7387 */
7388static struct hda_verb alc882_3ST_ch2_init[] = {
7389 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7390 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7391 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7392 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7393 { } /* end */
7394};
7395
4953550a
TI
7396/*
7397 * 4ch mode
7398 */
7399static struct hda_verb alc882_3ST_ch4_init[] = {
7400 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7401 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7402 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7403 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7404 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7405 { } /* end */
7406};
7407
272a527c
KY
7408/*
7409 * 6ch mode
7410 */
7411static struct hda_verb alc882_3ST_ch6_init[] = {
7412 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7413 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7414 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7415 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7416 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7417 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7418 { } /* end */
7419};
7420
4953550a 7421static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7422 { 2, alc882_3ST_ch2_init },
4953550a 7423 { 4, alc882_3ST_ch4_init },
272a527c
KY
7424 { 6, alc882_3ST_ch6_init },
7425};
7426
4953550a
TI
7427#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7428
a65cc60f 7429/*
7430 * 2ch mode
7431 */
7432static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7433 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7434 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7435 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7436 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7437 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7438 { } /* end */
7439};
7440
7441/*
7442 * 4ch mode
7443 */
7444static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7445 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7446 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7447 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7448 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7449 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7450 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7451 { } /* end */
7452};
7453
7454/*
7455 * 6ch mode
7456 */
7457static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7458 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7459 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7460 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7461 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7462 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7463 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7464 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7465 { } /* end */
7466};
7467
7468static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7469 { 2, alc883_3ST_ch2_clevo_init },
7470 { 4, alc883_3ST_ch4_clevo_init },
7471 { 6, alc883_3ST_ch6_clevo_init },
7472};
7473
7474
df694daa
KY
7475/*
7476 * 6ch mode
7477 */
7478static struct hda_verb alc882_sixstack_ch6_init[] = {
7479 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7480 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7481 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7482 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7483 { } /* end */
7484};
7485
7486/*
7487 * 8ch mode
7488 */
7489static struct hda_verb alc882_sixstack_ch8_init[] = {
7490 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7491 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7492 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7493 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7494 { } /* end */
7495};
7496
7497static struct hda_channel_mode alc882_sixstack_modes[2] = {
7498 { 6, alc882_sixstack_ch6_init },
7499 { 8, alc882_sixstack_ch8_init },
7500};
7501
76e6f5a9
RH
7502
7503/* Macbook Air 2,1 */
7504
7505static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7506 { 2, NULL },
7507};
7508
87350ad0 7509/*
def319f9 7510 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7511 */
7512
7513/*
7514 * 2ch mode
7515 */
7516static struct hda_verb alc885_mbp_ch2_init[] = {
7517 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7518 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7519 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7520 { } /* end */
7521};
7522
7523/*
a3f730af 7524 * 4ch mode
87350ad0 7525 */
a3f730af 7526static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7527 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7528 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7529 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7530 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7531 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7532 { } /* end */
7533};
7534
a3f730af 7535static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7536 { 2, alc885_mbp_ch2_init },
a3f730af 7537 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7538};
7539
92b9de83
KS
7540/*
7541 * 2ch
7542 * Speakers/Woofer/HP = Front
7543 * LineIn = Input
7544 */
7545static struct hda_verb alc885_mb5_ch2_init[] = {
7546 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7547 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7548 { } /* end */
7549};
7550
7551/*
7552 * 6ch mode
7553 * Speakers/HP = Front
7554 * Woofer = LFE
7555 * LineIn = Surround
7556 */
7557static struct hda_verb alc885_mb5_ch6_init[] = {
7558 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7559 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7560 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7561 { } /* end */
7562};
7563
7564static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7565 { 2, alc885_mb5_ch2_init },
7566 { 6, alc885_mb5_ch6_init },
7567};
87350ad0 7568
d01aecdf 7569#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7570
7571/*
7572 * 2ch mode
7573 */
7574static struct hda_verb alc883_4ST_ch2_init[] = {
7575 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7576 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7577 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7578 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7579 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7580 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7581 { } /* end */
7582};
7583
7584/*
7585 * 4ch mode
7586 */
7587static struct hda_verb alc883_4ST_ch4_init[] = {
7588 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7589 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7590 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7591 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7592 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7593 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7594 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7595 { } /* end */
7596};
7597
7598/*
7599 * 6ch mode
7600 */
7601static struct hda_verb alc883_4ST_ch6_init[] = {
7602 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7603 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7604 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7605 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7606 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7607 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7608 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7609 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7610 { } /* end */
7611};
7612
7613/*
7614 * 8ch mode
7615 */
7616static struct hda_verb alc883_4ST_ch8_init[] = {
7617 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7618 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7619 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7620 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7621 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7622 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7623 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7624 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7625 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7626 { } /* end */
7627};
7628
7629static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7630 { 2, alc883_4ST_ch2_init },
7631 { 4, alc883_4ST_ch4_init },
7632 { 6, alc883_4ST_ch6_init },
7633 { 8, alc883_4ST_ch8_init },
7634};
7635
7636
7637/*
7638 * 2ch mode
7639 */
7640static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7641 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7642 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7643 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7644 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7645 { } /* end */
7646};
7647
7648/*
7649 * 4ch mode
7650 */
7651static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7652 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7653 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7654 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7655 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7656 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7657 { } /* end */
7658};
7659
7660/*
7661 * 6ch mode
7662 */
7663static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7664 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7665 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7666 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7667 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7668 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7669 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7670 { } /* end */
7671};
7672
7673static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7674 { 2, alc883_3ST_ch2_intel_init },
7675 { 4, alc883_3ST_ch4_intel_init },
7676 { 6, alc883_3ST_ch6_intel_init },
7677};
7678
dd7714c9
WF
7679/*
7680 * 2ch mode
7681 */
7682static struct hda_verb alc889_ch2_intel_init[] = {
7683 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7684 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7685 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7686 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7687 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7688 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7689 { } /* end */
7690};
7691
87a8c370
JK
7692/*
7693 * 6ch mode
7694 */
7695static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7696 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7697 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7698 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7699 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7700 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7701 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7702 { } /* end */
7703};
7704
7705/*
7706 * 8ch mode
7707 */
7708static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7709 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7710 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7711 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7712 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7713 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7714 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7715 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7716 { } /* end */
7717};
7718
dd7714c9
WF
7719static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7720 { 2, alc889_ch2_intel_init },
87a8c370
JK
7721 { 6, alc889_ch6_intel_init },
7722 { 8, alc889_ch8_intel_init },
7723};
7724
4953550a
TI
7725/*
7726 * 6ch mode
7727 */
7728static struct hda_verb alc883_sixstack_ch6_init[] = {
7729 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7730 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7731 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7732 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7733 { } /* end */
7734};
7735
7736/*
7737 * 8ch mode
7738 */
7739static struct hda_verb alc883_sixstack_ch8_init[] = {
7740 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7741 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7742 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7743 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7744 { } /* end */
7745};
7746
7747static struct hda_channel_mode alc883_sixstack_modes[2] = {
7748 { 6, alc883_sixstack_ch6_init },
7749 { 8, alc883_sixstack_ch8_init },
7750};
7751
7752
1da177e4
LT
7753/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7754 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7755 */
c8b6bf9b 7756static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7757 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7758 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7759 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7760 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7761 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7762 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7763 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7764 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7765 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7766 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7767 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7768 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7769 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7770 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7771 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7772 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7773 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
7774 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7775 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7776 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4 7777 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7778 { } /* end */
7779};
7780
76e6f5a9
RH
7781/* Macbook Air 2,1 same control for HP and internal Speaker */
7782
7783static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7784 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7785 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7786 { }
7787};
7788
7789
87350ad0 7790static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7791 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7792 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7793 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7794 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7795 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7796 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7797 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7798 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7799 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 7800 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
7801 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7802 { } /* end */
7803};
41d5545d
KS
7804
7805static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
7806 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7807 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7808 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7809 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7810 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7811 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
7812 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7813 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
7814 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7815 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
7816 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7817 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7818 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7819 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7820 { } /* end */
7821};
92b9de83 7822
e458b1fa
LY
7823static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7824 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7825 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7826 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7827 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7828 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7829 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7830 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7831 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7832 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7833 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7834 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7835 { } /* end */
7836};
7837
4b7e1803 7838static struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
7839 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7840 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
7841 { } /* end */
7842};
7843
7844
bdd148a3
KY
7845static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7846 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7847 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7848 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7849 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7850 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7851 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7852 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7853 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7854 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
7855 { } /* end */
7856};
7857
272a527c
KY
7858static struct snd_kcontrol_new alc882_targa_mixer[] = {
7859 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7860 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7861 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7862 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7863 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7864 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7865 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7866 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7867 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7868 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7869 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7870 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 7871 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
7872 { } /* end */
7873};
7874
7875/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7876 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7877 */
7878static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7879 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7880 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7881 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7882 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7883 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7884 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7885 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7886 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7887 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7888 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7889 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7890 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7891 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7892 { } /* end */
7893};
7894
914759b7
TI
7895static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7896 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7897 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7898 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7899 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7900 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7901 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7902 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7903 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7904 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7905 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
7906 { } /* end */
7907};
7908
df694daa
KY
7909static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7910 {
7911 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7912 .name = "Channel Mode",
7913 .info = alc_ch_mode_info,
7914 .get = alc_ch_mode_get,
7915 .put = alc_ch_mode_put,
7916 },
7917 { } /* end */
7918};
7919
4953550a 7920static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 7921 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
7922 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7923 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7924 /* Rear mixer */
05acb863
TI
7925 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7926 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7927 /* CLFE mixer */
05acb863
TI
7928 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7929 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7930 /* Side mixer */
05acb863
TI
7931 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7932 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7933
e9edcee0 7934 /* Front Pin: output 0 (0x0c) */
05acb863 7935 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7936 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7937 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 7938 /* Rear Pin: output 1 (0x0d) */
05acb863 7939 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7940 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7941 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 7942 /* CLFE Pin: output 2 (0x0e) */
05acb863 7943 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7944 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7945 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 7946 /* Side Pin: output 3 (0x0f) */
05acb863 7947 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7948 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7949 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 7950 /* Mic (rear) pin: input vref at 80% */
16ded525 7951 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7952 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7953 /* Front Mic pin: input vref at 80% */
16ded525 7954 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7955 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7956 /* Line In pin: input */
05acb863 7957 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
7958 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7959 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7960 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7961 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7962 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 7963 /* CD pin widget for input */
05acb863 7964 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
7965
7966 /* FIXME: use matrix-type input source selection */
7967 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 7968 /* Input mixer2 */
05acb863 7969 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 7970 /* Input mixer3 */
05acb863 7971 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
7972 /* ADC2: mute amp left and right */
7973 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7974 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
7975 /* ADC3: mute amp left and right */
7976 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7977 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
7978
7979 { }
7980};
7981
4953550a
TI
7982static struct hda_verb alc882_adc1_init_verbs[] = {
7983 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7984 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7985 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7986 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7987 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7988 /* ADC1: mute amp left and right */
7989 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7990 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7991 { }
7992};
7993
4b146cb0
TI
7994static struct hda_verb alc882_eapd_verbs[] = {
7995 /* change to EAPD mode */
7996 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 7997 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 7998 { }
4b146cb0
TI
7999};
8000
87a8c370
JK
8001static struct hda_verb alc889_eapd_verbs[] = {
8002 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8003 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8004 { }
8005};
8006
6732bd0d
WF
8007static struct hda_verb alc_hp15_unsol_verbs[] = {
8008 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8009 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8010 {}
8011};
87a8c370
JK
8012
8013static struct hda_verb alc885_init_verbs[] = {
8014 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8015 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8016 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8017 /* Rear mixer */
88102f3f
KY
8018 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8019 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8020 /* CLFE mixer */
88102f3f
KY
8021 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8022 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8023 /* Side mixer */
88102f3f
KY
8024 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8025 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8026
8027 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8028 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8029 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8030 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8031 /* Front Pin: output 0 (0x0c) */
8032 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8033 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8034 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8035 /* Rear Pin: output 1 (0x0d) */
8036 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8037 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8038 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8039 /* CLFE Pin: output 2 (0x0e) */
8040 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8041 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8042 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8043 /* Side Pin: output 3 (0x0f) */
8044 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8045 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8046 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8047 /* Mic (rear) pin: input vref at 80% */
8048 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8049 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8050 /* Front Mic pin: input vref at 80% */
8051 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8052 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8053 /* Line In pin: input */
8054 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8055 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8056
8057 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8058 /* Input mixer1 */
88102f3f 8059 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8060 /* Input mixer2 */
8061 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8062 /* Input mixer3 */
88102f3f 8063 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8064 /* ADC2: mute amp left and right */
8065 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8066 /* ADC3: mute amp left and right */
8067 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8068
8069 { }
8070};
8071
8072static struct hda_verb alc885_init_input_verbs[] = {
8073 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8074 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8075 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8076 { }
8077};
8078
8079
8080/* Unmute Selector 24h and set the default input to front mic */
8081static struct hda_verb alc889_init_input_verbs[] = {
8082 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8083 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8084 { }
8085};
8086
8087
4953550a
TI
8088#define alc883_init_verbs alc882_base_init_verbs
8089
9102cd1c
TD
8090/* Mac Pro test */
8091static struct snd_kcontrol_new alc882_macpro_mixer[] = {
8092 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8093 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8094 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8095 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8096 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8097 /* FIXME: this looks suspicious...
d355c82a
JK
8098 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8099 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8100 */
9102cd1c
TD
8101 { } /* end */
8102};
8103
8104static struct hda_verb alc882_macpro_init_verbs[] = {
8105 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8106 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8107 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8108 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8109 /* Front Pin: output 0 (0x0c) */
8110 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8111 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8112 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8113 /* Front Mic pin: input vref at 80% */
8114 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8115 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8116 /* Speaker: output */
8117 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8118 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8119 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8120 /* Headphone output (output 0 - 0x0c) */
8121 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8122 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8123 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8124
8125 /* FIXME: use matrix-type input source selection */
8126 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8127 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8128 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8129 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8130 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8131 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8132 /* Input mixer2 */
8133 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8134 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8135 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8136 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8137 /* Input mixer3 */
8138 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8139 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8140 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8141 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8142 /* ADC1: mute amp left and right */
8143 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8144 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8145 /* ADC2: mute amp left and right */
8146 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8147 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8148 /* ADC3: mute amp left and right */
8149 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8150 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8151
8152 { }
8153};
f12ab1e0 8154
41d5545d
KS
8155/* Macbook 5,1 */
8156static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8157 /* DACs */
8158 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8159 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8160 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8161 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8162 /* Front mixer */
41d5545d
KS
8163 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8164 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8165 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8166 /* Surround mixer */
8167 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8168 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8169 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8170 /* LFE mixer */
8171 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8172 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8173 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8174 /* HP mixer */
8175 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8176 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8177 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8178 /* Front Pin (0x0c) */
41d5545d
KS
8179 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8180 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8181 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8182 /* LFE Pin (0x0e) */
8183 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8184 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8185 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8186 /* HP Pin (0x0f) */
41d5545d
KS
8187 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8188 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8189 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8190 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8191 /* Front Mic pin: input vref at 80% */
8192 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8193 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8194 /* Line In pin */
8195 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8196 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8197
b8f171e7
AM
8198 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8199 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8200 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8201 { }
8202};
8203
e458b1fa
LY
8204/* Macmini 3,1 */
8205static struct hda_verb alc885_macmini3_init_verbs[] = {
8206 /* DACs */
8207 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8208 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8209 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8210 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8211 /* Front mixer */
8212 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8213 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8214 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8215 /* Surround mixer */
8216 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8217 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8218 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8219 /* LFE mixer */
8220 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8221 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8222 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8223 /* HP mixer */
8224 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8225 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8226 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8227 /* Front Pin (0x0c) */
8228 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8229 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8230 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8231 /* LFE Pin (0x0e) */
8232 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8233 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8234 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8235 /* HP Pin (0x0f) */
8236 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8237 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8238 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8239 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8240 /* Line In pin */
8241 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8242 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8243
8244 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8245 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8246 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8247 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8248 { }
8249};
8250
76e6f5a9
RH
8251
8252static struct hda_verb alc885_mba21_init_verbs[] = {
8253 /*Internal and HP Speaker Mixer*/
8254 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8255 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8256 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8257 /*Internal Speaker Pin (0x0c)*/
8258 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8259 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8260 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8261 /* HP Pin: output 0 (0x0e) */
8262 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8263 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8264 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8265 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8266 /* Line in (is hp when jack connected)*/
8267 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8268 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8269
8270 { }
8271 };
8272
8273
87350ad0
TI
8274/* Macbook Pro rev3 */
8275static struct hda_verb alc885_mbp3_init_verbs[] = {
8276 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8277 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8278 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8279 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8280 /* Rear mixer */
8281 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8282 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8283 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8284 /* HP mixer */
8285 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8286 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8287 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8288 /* Front Pin: output 0 (0x0c) */
8289 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8290 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8291 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8292 /* HP Pin: output 0 (0x0e) */
87350ad0 8293 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8294 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8295 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8296 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8297 /* Mic (rear) pin: input vref at 80% */
8298 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8299 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8300 /* Front Mic pin: input vref at 80% */
8301 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8302 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8303 /* Line In pin: use output 1 when in LineOut mode */
8304 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8305 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8306 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8307
8308 /* FIXME: use matrix-type input source selection */
8309 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8310 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8311 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8312 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8313 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8314 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8315 /* Input mixer2 */
8316 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8317 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8318 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8319 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8320 /* Input mixer3 */
8321 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8322 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8323 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8324 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8325 /* ADC1: mute amp left and right */
8326 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8327 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8328 /* ADC2: mute amp left and right */
8329 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8330 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8331 /* ADC3: mute amp left and right */
8332 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8333 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8334
8335 { }
8336};
8337
4b7e1803
JM
8338/* iMac 9,1 */
8339static struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8340 /* Internal Speaker Pin (0x0c) */
8341 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8342 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8343 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8344 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8345 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8346 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8347 /* HP Pin: Rear */
4b7e1803
JM
8348 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8349 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8350 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8351 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8352 /* Line in Rear */
8353 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8354 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8355 /* Front Mic pin: input vref at 80% */
8356 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8357 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8358 /* Rear mixer */
8359 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8360 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8361 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8362 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8363 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8364 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8365 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8366 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8367 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8368 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8369 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8370 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8371 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8372 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8373 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8374 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8375 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8376 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8377 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8378 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8379 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8380 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8381 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8382 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8383 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8384 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8385 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8386 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8387 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8388 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8389 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8390 { }
8391};
8392
c54728d8
NF
8393/* iMac 24 mixer. */
8394static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8395 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8396 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8397 { } /* end */
8398};
8399
8400/* iMac 24 init verbs. */
8401static struct hda_verb alc885_imac24_init_verbs[] = {
8402 /* Internal speakers: output 0 (0x0c) */
8403 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8404 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8405 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8406 /* Internal speakers: output 0 (0x0c) */
8407 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8408 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8409 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8410 /* Headphone: output 0 (0x0c) */
8411 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8412 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8413 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8414 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8415 /* Front Mic: input vref at 80% */
8416 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8417 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8418 { }
8419};
8420
8421/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8422static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8423{
a9fd4f3f 8424 struct alc_spec *spec = codec->spec;
c54728d8 8425
a9fd4f3f
TI
8426 spec->autocfg.hp_pins[0] = 0x14;
8427 spec->autocfg.speaker_pins[0] = 0x18;
8428 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8429}
8430
9d54f08b
TI
8431#define alc885_mb5_setup alc885_imac24_setup
8432#define alc885_macmini3_setup alc885_imac24_setup
8433
76e6f5a9
RH
8434/* Macbook Air 2,1 */
8435static void alc885_mba21_setup(struct hda_codec *codec)
8436{
8437 struct alc_spec *spec = codec->spec;
8438
8439 spec->autocfg.hp_pins[0] = 0x14;
8440 spec->autocfg.speaker_pins[0] = 0x18;
8441}
8442
8443
8444
4f5d1706 8445static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8446{
a9fd4f3f 8447 struct alc_spec *spec = codec->spec;
87350ad0 8448
a9fd4f3f
TI
8449 spec->autocfg.hp_pins[0] = 0x15;
8450 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8451}
8452
9d54f08b 8453static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8454{
9d54f08b 8455 struct alc_spec *spec = codec->spec;
4b7e1803 8456
9d54f08b 8457 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8458 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8459 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8460}
87350ad0 8461
272a527c
KY
8462static struct hda_verb alc882_targa_verbs[] = {
8463 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8464 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8465
8466 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8467 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8468
272a527c
KY
8469 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8470 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8471 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8472
8473 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8474 { } /* end */
8475};
8476
8477/* toggle speaker-output according to the hp-jack state */
8478static void alc882_targa_automute(struct hda_codec *codec)
8479{
a9fd4f3f
TI
8480 struct alc_spec *spec = codec->spec;
8481 alc_automute_amp(codec);
82beb8fd 8482 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8483 spec->jack_present ? 1 : 3);
8484}
8485
4f5d1706 8486static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8487{
8488 struct alc_spec *spec = codec->spec;
8489
8490 spec->autocfg.hp_pins[0] = 0x14;
8491 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8492}
8493
8494static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8495{
a9fd4f3f 8496 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8497 alc882_targa_automute(codec);
272a527c
KY
8498}
8499
8500static struct hda_verb alc882_asus_a7j_verbs[] = {
8501 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8502 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8503
8504 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8505 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8506 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8507
272a527c
KY
8508 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8509 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8510 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8511
8512 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8513 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8514 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8515 { } /* end */
8516};
8517
914759b7
TI
8518static struct hda_verb alc882_asus_a7m_verbs[] = {
8519 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8520 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8521
8522 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8523 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8524 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8525
914759b7
TI
8526 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8527 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8528 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8529
8530 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8531 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8532 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8533 { } /* end */
8534};
8535
9102cd1c
TD
8536static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8537{
8538 unsigned int gpiostate, gpiomask, gpiodir;
8539
8540 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8541 AC_VERB_GET_GPIO_DATA, 0);
8542
8543 if (!muted)
8544 gpiostate |= (1 << pin);
8545 else
8546 gpiostate &= ~(1 << pin);
8547
8548 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8549 AC_VERB_GET_GPIO_MASK, 0);
8550 gpiomask |= (1 << pin);
8551
8552 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8553 AC_VERB_GET_GPIO_DIRECTION, 0);
8554 gpiodir |= (1 << pin);
8555
8556
8557 snd_hda_codec_write(codec, codec->afg, 0,
8558 AC_VERB_SET_GPIO_MASK, gpiomask);
8559 snd_hda_codec_write(codec, codec->afg, 0,
8560 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8561
8562 msleep(1);
8563
8564 snd_hda_codec_write(codec, codec->afg, 0,
8565 AC_VERB_SET_GPIO_DATA, gpiostate);
8566}
8567
7debbe51
TI
8568/* set up GPIO at initialization */
8569static void alc885_macpro_init_hook(struct hda_codec *codec)
8570{
8571 alc882_gpio_mute(codec, 0, 0);
8572 alc882_gpio_mute(codec, 1, 0);
8573}
8574
8575/* set up GPIO and update auto-muting at initialization */
8576static void alc885_imac24_init_hook(struct hda_codec *codec)
8577{
8578 alc885_macpro_init_hook(codec);
4f5d1706 8579 alc_automute_amp(codec);
7debbe51
TI
8580}
8581
df694daa
KY
8582/*
8583 * generic initialization of ADC, input mixers and output mixers
8584 */
4953550a 8585static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8586 /*
8587 * Unmute ADC0-2 and set the default input to mic-in
8588 */
4953550a
TI
8589 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8590 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8591 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8592 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8593
4953550a
TI
8594 /*
8595 * Set up output mixers (0x0c - 0x0f)
8596 */
8597 /* set vol=0 to output mixers */
8598 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8599 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8600 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8601 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8602 /* set up input amps for analog loopback */
8603 /* Amp Indices: DAC = 0, mixer = 1 */
8604 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8605 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8606 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8607 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8608 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8609 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8610 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8611 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8612 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8613 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8614
4953550a
TI
8615 /* FIXME: use matrix-type input source selection */
8616 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8617 /* Input mixer2 */
88102f3f 8618 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8619 /* Input mixer3 */
88102f3f 8620 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8621 { }
9c7f852e
TI
8622};
8623
eb4c41d3
TS
8624/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8625static struct hda_verb alc889A_mb31_ch2_init[] = {
8626 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8627 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8628 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8629 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8630 { } /* end */
8631};
8632
8633/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8634static struct hda_verb alc889A_mb31_ch4_init[] = {
8635 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8636 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8637 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8638 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8639 { } /* end */
8640};
8641
8642/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8643static struct hda_verb alc889A_mb31_ch5_init[] = {
8644 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8645 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8646 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8647 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8648 { } /* end */
8649};
8650
8651/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8652static struct hda_verb alc889A_mb31_ch6_init[] = {
8653 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8654 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8655 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8656 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8657 { } /* end */
8658};
8659
8660static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8661 { 2, alc889A_mb31_ch2_init },
8662 { 4, alc889A_mb31_ch4_init },
8663 { 5, alc889A_mb31_ch5_init },
8664 { 6, alc889A_mb31_ch6_init },
8665};
8666
b373bdeb
AN
8667static struct hda_verb alc883_medion_eapd_verbs[] = {
8668 /* eanable EAPD on medion laptop */
8669 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8670 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8671 { }
8672};
8673
4953550a 8674#define alc883_base_mixer alc882_base_mixer
834be88d 8675
a8848bd6
AS
8676static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8677 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8678 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8679 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8680 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8681 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8682 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8683 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8684 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8685 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8686 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8687 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8688 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8689 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8690 { } /* end */
8691};
8692
0c4cc443 8693static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8694 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8695 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8696 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8697 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8698 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8699 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8700 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8701 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8702 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8703 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8704 { } /* end */
8705};
8706
fb97dc67
J
8707static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8708 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8709 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8710 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8711 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8712 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8713 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8714 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8715 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8716 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8717 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8718 { } /* end */
8719};
8720
9c7f852e
TI
8721static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8722 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8723 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8724 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8725 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8726 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8727 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8728 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8729 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8730 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8731 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8732 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8733 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8734 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8735 { } /* end */
8736};
df694daa 8737
9c7f852e
TI
8738static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8739 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8740 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8741 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8742 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8743 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8744 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8745 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8746 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8747 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8748 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8749 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8750 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8751 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8752 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8753 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8754 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8755 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8756 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8757 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8758 { } /* end */
8759};
8760
17bba1b7
J
8761static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8762 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8763 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8764 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8765 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8766 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8767 HDA_OUTPUT),
8768 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8769 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8770 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8771 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8772 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8773 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8774 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8775 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8776 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8777 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8778 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8779 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8780 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8781 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8782 { } /* end */
8783};
8784
87a8c370
JK
8785static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8786 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8787 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8788 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8789 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8790 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8791 HDA_OUTPUT),
8792 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8793 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8794 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8795 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8796 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8797 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8798 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8799 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8800 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8801 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
8802 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8803 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8804 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8805 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8806 { } /* end */
8807};
8808
d1d985f0 8809static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8810 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8811 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8812 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8813 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8814 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8815 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8816 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8817 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8818 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8819 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8820 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8821 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8822 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8823 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8824 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
8825 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8826 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8827 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8 8828 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
8829 { } /* end */
8830};
8831
c259249f 8832static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 8833 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8834 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8835 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8836 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8837 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8838 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8839 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8840 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8841 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8842 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8843 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8844 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8845 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8846 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8847 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8848 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8849 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 8850 { } /* end */
f12ab1e0 8851};
ccc656ce 8852
c259249f 8853static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 8854 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8855 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8856 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8857 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8858 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8859 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8861 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
8863 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8864 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8865 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 8866 { } /* end */
f12ab1e0 8867};
ccc656ce 8868
b99dba34
TI
8869static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8870 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8871 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8872 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8873 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8874 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8875 { } /* end */
8876};
8877
bc9f98a9
KY
8878static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8879 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8880 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
8881 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8882 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
8883 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8884 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8885 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8886 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 8887 { } /* end */
f12ab1e0 8888};
bc9f98a9 8889
272a527c
KY
8890static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8891 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8892 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8893 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8894 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8895 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8896 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8897 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
150b432f
DH
8898 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8899 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
8900 { } /* end */
8901};
8902
8903static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8904 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8905 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8906 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8907 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8908 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8909 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8910 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8911 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8912 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
272a527c 8913 { } /* end */
ea1fb29a 8914};
272a527c 8915
7ad7b218
MC
8916static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
8917 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8918 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8919 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8920 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
8921 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
8922 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
8923 { } /* end */
8924};
8925
8926static struct hda_verb alc883_medion_wim2160_verbs[] = {
8927 /* Unmute front mixer */
8928 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8929 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8930
8931 /* Set speaker pin to front mixer */
8932 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8933
8934 /* Init headphone pin */
8935 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8936 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8937 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8938 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8939
8940 { } /* end */
8941};
8942
8943/* toggle speaker-output according to the hp-jack state */
8944static void alc883_medion_wim2160_setup(struct hda_codec *codec)
8945{
8946 struct alc_spec *spec = codec->spec;
8947
8948 spec->autocfg.hp_pins[0] = 0x1a;
8949 spec->autocfg.speaker_pins[0] = 0x15;
8950}
8951
2880a867 8952static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
8953 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8954 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 8955 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
8956 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8957 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
8958 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8959 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8960 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 8961 { } /* end */
d1a991a6 8962};
2880a867 8963
d2fd4b09
TV
8964static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8965 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 8966 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
8967 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8968 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
8969 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8970 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8972 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8973 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8974 { } /* end */
8975};
8976
e2757d5e
KY
8977static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8978 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8979 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8980 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8981 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8982 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8983 0x0d, 1, 0x0, HDA_OUTPUT),
8984 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8985 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8986 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8987 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8988 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
8989 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8990 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8991 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8992 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8993 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8994 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8995 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8996 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8997 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8998 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
8999 { } /* end */
9000};
9001
eb4c41d3
TS
9002static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9003 /* Output mixers */
9004 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9005 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9006 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9007 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9008 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9009 HDA_OUTPUT),
9010 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9011 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9012 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9013 /* Output switches */
9014 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9015 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9016 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9017 /* Boost mixers */
9018 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
9019 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
9020 /* Input mixers */
9021 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9022 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9023 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9024 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9025 { } /* end */
9026};
9027
3e1647c5
GG
9028static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9029 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9030 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9031 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9032 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9033 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9034 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9035 { } /* end */
9036};
9037
e2757d5e
KY
9038static struct hda_bind_ctls alc883_bind_cap_vol = {
9039 .ops = &snd_hda_bind_vol,
9040 .values = {
9041 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9042 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9043 0
9044 },
9045};
9046
9047static struct hda_bind_ctls alc883_bind_cap_switch = {
9048 .ops = &snd_hda_bind_sw,
9049 .values = {
9050 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9051 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9052 0
9053 },
9054};
9055
9056static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9057 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9058 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9059 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9060 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9061 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9062 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4953550a
TI
9063 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9064 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9065 { } /* end */
9066};
df694daa 9067
4953550a
TI
9068static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9069 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9070 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9071 {
9072 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9073 /* .name = "Capture Source", */
9074 .name = "Input Source",
9075 .count = 1,
9076 .info = alc_mux_enum_info,
9077 .get = alc_mux_enum_get,
9078 .put = alc_mux_enum_put,
9079 },
9080 { } /* end */
9081};
9c7f852e 9082
4953550a
TI
9083static struct snd_kcontrol_new alc883_chmode_mixer[] = {
9084 {
9085 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9086 .name = "Channel Mode",
9087 .info = alc_ch_mode_info,
9088 .get = alc_ch_mode_get,
9089 .put = alc_ch_mode_put,
9090 },
9091 { } /* end */
9c7f852e
TI
9092};
9093
a8848bd6 9094/* toggle speaker-output according to the hp-jack state */
4f5d1706 9095static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9096{
a9fd4f3f 9097 struct alc_spec *spec = codec->spec;
a8848bd6 9098
a9fd4f3f
TI
9099 spec->autocfg.hp_pins[0] = 0x15;
9100 spec->autocfg.speaker_pins[0] = 0x14;
9101 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
9102}
9103
9104/* auto-toggle front mic */
9105/*
9106static void alc883_mitac_mic_automute(struct hda_codec *codec)
9107{
864f92be 9108 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
a8848bd6 9109
a8848bd6
AS
9110 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
9111}
9112*/
9113
a8848bd6
AS
9114static struct hda_verb alc883_mitac_verbs[] = {
9115 /* HP */
9116 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9117 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9118 /* Subwoofer */
9119 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9120 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9121
9122 /* enable unsolicited event */
9123 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9124 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9125
9126 { } /* end */
9127};
9128
a65cc60f 9129static struct hda_verb alc883_clevo_m540r_verbs[] = {
9130 /* HP */
9131 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9132 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9133 /* Int speaker */
9134 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9135
9136 /* enable unsolicited event */
9137 /*
9138 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9139 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9140 */
9141
9142 { } /* end */
9143};
9144
0c4cc443 9145static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9146 /* HP */
9147 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9148 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9149 /* Int speaker */
9150 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9151 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9152
9153 /* enable unsolicited event */
9154 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9155 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9156
9157 { } /* end */
9158};
9159
fb97dc67
J
9160static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9161 /* HP */
9162 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9163 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9164 /* Subwoofer */
9165 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9166 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9167
9168 /* enable unsolicited event */
9169 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9170
9171 { } /* end */
9172};
9173
c259249f 9174static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9175 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9176 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9177
9178 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9179 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9180
64a8be74
DH
9181/* Connect Line-Out side jack (SPDIF) to Side */
9182 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9183 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9184 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9185/* Connect Mic jack to CLFE */
9186 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9187 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9188 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9189/* Connect Line-in jack to Surround */
9190 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9191 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9192 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9193/* Connect HP out jack to Front */
9194 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9195 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9196 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9197
9198 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9199
9200 { } /* end */
9201};
9202
bc9f98a9
KY
9203static struct hda_verb alc883_lenovo_101e_verbs[] = {
9204 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9205 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9206 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9207 { } /* end */
9208};
9209
272a527c
KY
9210static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9211 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9212 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9213 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9214 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9215 { } /* end */
9216};
9217
9218static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9219 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9221 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9222 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9223 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9224 { } /* end */
9225};
9226
189609ae
KY
9227static struct hda_verb alc883_haier_w66_verbs[] = {
9228 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9229 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9230
9231 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9232
9233 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9234 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9235 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9236 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9237 { } /* end */
9238};
9239
e2757d5e
KY
9240static struct hda_verb alc888_lenovo_sky_verbs[] = {
9241 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9242 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9243 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9244 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9245 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9246 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9247 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9248 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9249 { } /* end */
9250};
9251
8718b700
HRK
9252static struct hda_verb alc888_6st_dell_verbs[] = {
9253 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9254 { }
9255};
9256
3e1647c5
GG
9257static struct hda_verb alc883_vaiott_verbs[] = {
9258 /* HP */
9259 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9260 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9261
9262 /* enable unsolicited event */
9263 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9264
9265 { } /* end */
9266};
9267
4f5d1706 9268static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9269{
a9fd4f3f 9270 struct alc_spec *spec = codec->spec;
8718b700 9271
a9fd4f3f
TI
9272 spec->autocfg.hp_pins[0] = 0x1b;
9273 spec->autocfg.speaker_pins[0] = 0x14;
9274 spec->autocfg.speaker_pins[1] = 0x16;
9275 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
9276}
9277
4723c022 9278static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9279 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9280 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9281 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9282 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9283 { } /* end */
5795b9e6
CM
9284};
9285
3ea0d7cf
HRK
9286/*
9287 * 2ch mode
9288 */
4723c022 9289static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9290 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9291 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9292 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9293 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9294 { } /* end */
8341de60
CM
9295};
9296
3ea0d7cf
HRK
9297/*
9298 * 4ch mode
9299 */
9300static struct hda_verb alc888_3st_hp_4ch_init[] = {
9301 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9302 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9303 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9304 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9305 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9306 { } /* end */
9307};
9308
9309/*
9310 * 6ch mode
9311 */
4723c022 9312static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9313 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9314 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9315 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9316 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9317 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9318 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9319 { } /* end */
8341de60
CM
9320};
9321
3ea0d7cf 9322static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9323 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9324 { 4, alc888_3st_hp_4ch_init },
4723c022 9325 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9326};
9327
272a527c
KY
9328/* toggle front-jack and RCA according to the hp-jack state */
9329static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9330{
864f92be 9331 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 9332
47fd830a
TI
9333 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9334 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9335 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9336 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
9337}
9338
9339/* toggle RCA according to the front-jack state */
9340static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9341{
864f92be 9342 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 9343
47fd830a
TI
9344 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9345 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 9346}
47fd830a 9347
272a527c
KY
9348static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9349 unsigned int res)
9350{
9351 if ((res >> 26) == ALC880_HP_EVENT)
9352 alc888_lenovo_ms7195_front_automute(codec);
9353 if ((res >> 26) == ALC880_FRONT_EVENT)
9354 alc888_lenovo_ms7195_rca_automute(codec);
9355}
9356
9357static struct hda_verb alc883_medion_md2_verbs[] = {
9358 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9359 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9360
9361 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9362
9363 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9364 { } /* end */
9365};
9366
9367/* toggle speaker-output according to the hp-jack state */
4f5d1706 9368static void alc883_medion_md2_setup(struct hda_codec *codec)
272a527c 9369{
a9fd4f3f 9370 struct alc_spec *spec = codec->spec;
272a527c 9371
a9fd4f3f
TI
9372 spec->autocfg.hp_pins[0] = 0x14;
9373 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
9374}
9375
ccc656ce 9376/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9377#define alc883_targa_init_hook alc882_targa_init_hook
9378#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9379
0c4cc443
HRK
9380static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
9381{
9382 unsigned int present;
9383
d56757ab 9384 present = snd_hda_jack_detect(codec, 0x18);
0c4cc443
HRK
9385 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
9386 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9387}
9388
4f5d1706 9389static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9390{
a9fd4f3f
TI
9391 struct alc_spec *spec = codec->spec;
9392
9393 spec->autocfg.hp_pins[0] = 0x15;
9394 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
9395}
9396
9397static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9398{
a9fd4f3f 9399 alc_automute_amp(codec);
0c4cc443
HRK
9400 alc883_clevo_m720_mic_automute(codec);
9401}
9402
9403static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9404 unsigned int res)
9405{
0c4cc443 9406 switch (res >> 26) {
0c4cc443
HRK
9407 case ALC880_MIC_EVENT:
9408 alc883_clevo_m720_mic_automute(codec);
9409 break;
a9fd4f3f
TI
9410 default:
9411 alc_automute_amp_unsol_event(codec, res);
9412 break;
0c4cc443 9413 }
368c7a95
J
9414}
9415
fb97dc67 9416/* toggle speaker-output according to the hp-jack state */
4f5d1706 9417static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9418{
a9fd4f3f 9419 struct alc_spec *spec = codec->spec;
fb97dc67 9420
a9fd4f3f
TI
9421 spec->autocfg.hp_pins[0] = 0x14;
9422 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9423}
9424
4f5d1706 9425static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9426{
a9fd4f3f 9427 struct alc_spec *spec = codec->spec;
189609ae 9428
a9fd4f3f
TI
9429 spec->autocfg.hp_pins[0] = 0x1b;
9430 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9431}
9432
bc9f98a9
KY
9433static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9434{
864f92be 9435 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9436
47fd830a
TI
9437 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9438 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9439}
9440
9441static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9442{
864f92be 9443 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9444
47fd830a
TI
9445 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9446 HDA_AMP_MUTE, bits);
9447 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9448 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9449}
9450
9451static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9452 unsigned int res)
9453{
9454 if ((res >> 26) == ALC880_HP_EVENT)
9455 alc883_lenovo_101e_all_automute(codec);
9456 if ((res >> 26) == ALC880_FRONT_EVENT)
9457 alc883_lenovo_101e_ispeaker_automute(codec);
9458}
9459
676a9b53 9460/* toggle speaker-output according to the hp-jack state */
4f5d1706 9461static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9462{
a9fd4f3f 9463 struct alc_spec *spec = codec->spec;
676a9b53 9464
a9fd4f3f
TI
9465 spec->autocfg.hp_pins[0] = 0x14;
9466 spec->autocfg.speaker_pins[0] = 0x15;
9467 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9468}
9469
d1a991a6
KY
9470static struct hda_verb alc883_acer_eapd_verbs[] = {
9471 /* HP Pin: output 0 (0x0c) */
9472 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9473 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9474 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9475 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9476 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9477 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9478 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9479 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9480 /* eanable EAPD on medion laptop */
9481 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9482 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9483 /* enable unsolicited event */
9484 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9485 { }
9486};
9487
fc86f954
DK
9488static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
9489 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9490 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9491 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9492 { } /* end */
9493};
9494
4f5d1706 9495static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9496{
a9fd4f3f 9497 struct alc_spec *spec = codec->spec;
5795b9e6 9498
a9fd4f3f
TI
9499 spec->autocfg.hp_pins[0] = 0x1b;
9500 spec->autocfg.speaker_pins[0] = 0x14;
9501 spec->autocfg.speaker_pins[1] = 0x15;
9502 spec->autocfg.speaker_pins[2] = 0x16;
9503 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9504}
9505
4f5d1706 9506static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9507{
a9fd4f3f 9508 struct alc_spec *spec = codec->spec;
e2757d5e 9509
a9fd4f3f
TI
9510 spec->autocfg.hp_pins[0] = 0x1b;
9511 spec->autocfg.speaker_pins[0] = 0x14;
9512 spec->autocfg.speaker_pins[1] = 0x15;
9513 spec->autocfg.speaker_pins[2] = 0x16;
9514 spec->autocfg.speaker_pins[3] = 0x17;
9515 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9516}
9517
4f5d1706 9518static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9519{
9520 struct alc_spec *spec = codec->spec;
9521
9522 spec->autocfg.hp_pins[0] = 0x15;
9523 spec->autocfg.speaker_pins[0] = 0x14;
9524 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9525}
9526
e2757d5e
KY
9527static struct hda_verb alc888_asus_m90v_verbs[] = {
9528 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9529 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9530 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9531 /* enable unsolicited event */
9532 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9533 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9534 { } /* end */
9535};
9536
4f5d1706 9537static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9538{
a9fd4f3f 9539 struct alc_spec *spec = codec->spec;
e2757d5e 9540
a9fd4f3f
TI
9541 spec->autocfg.hp_pins[0] = 0x1b;
9542 spec->autocfg.speaker_pins[0] = 0x14;
9543 spec->autocfg.speaker_pins[1] = 0x15;
9544 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9545 spec->ext_mic.pin = 0x18;
9546 spec->int_mic.pin = 0x19;
9547 spec->ext_mic.mux_idx = 0;
9548 spec->int_mic.mux_idx = 1;
9549 spec->auto_mic = 1;
e2757d5e
KY
9550}
9551
9552static struct hda_verb alc888_asus_eee1601_verbs[] = {
9553 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9554 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9555 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9556 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9557 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9558 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9559 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9560 /* enable unsolicited event */
9561 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9562 { } /* end */
9563};
9564
e2757d5e
KY
9565static void alc883_eee1601_inithook(struct hda_codec *codec)
9566{
a9fd4f3f
TI
9567 struct alc_spec *spec = codec->spec;
9568
9569 spec->autocfg.hp_pins[0] = 0x14;
9570 spec->autocfg.speaker_pins[0] = 0x1b;
9571 alc_automute_pin(codec);
e2757d5e
KY
9572}
9573
eb4c41d3
TS
9574static struct hda_verb alc889A_mb31_verbs[] = {
9575 /* Init rear pin (used as headphone output) */
9576 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9577 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9578 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9579 /* Init line pin (used as output in 4ch and 6ch mode) */
9580 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9581 /* Init line 2 pin (used as headphone out by default) */
9582 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9583 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9584 { } /* end */
9585};
9586
9587/* Mute speakers according to the headphone jack state */
9588static void alc889A_mb31_automute(struct hda_codec *codec)
9589{
9590 unsigned int present;
9591
9592 /* Mute only in 2ch or 4ch mode */
9593 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9594 == 0x00) {
864f92be 9595 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9596 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9597 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9598 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9599 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9600 }
9601}
9602
9603static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9604{
9605 if ((res >> 26) == ALC880_HP_EVENT)
9606 alc889A_mb31_automute(codec);
9607}
9608
4953550a 9609
cb53c626 9610#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9611#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9612#endif
9613
def319f9 9614/* pcm configuration: identical with ALC880 */
4953550a
TI
9615#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9616#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9617#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9618#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9619
9620static hda_nid_t alc883_slave_dig_outs[] = {
9621 ALC1200_DIGOUT_NID, 0,
9622};
9623
9624static hda_nid_t alc1200_slave_dig_outs[] = {
9625 ALC883_DIGOUT_NID, 0,
9626};
9c7f852e
TI
9627
9628/*
9629 * configuration and preset
9630 */
4953550a
TI
9631static const char *alc882_models[ALC882_MODEL_LAST] = {
9632 [ALC882_3ST_DIG] = "3stack-dig",
9633 [ALC882_6ST_DIG] = "6stack-dig",
9634 [ALC882_ARIMA] = "arima",
9635 [ALC882_W2JC] = "w2jc",
9636 [ALC882_TARGA] = "targa",
9637 [ALC882_ASUS_A7J] = "asus-a7j",
9638 [ALC882_ASUS_A7M] = "asus-a7m",
9639 [ALC885_MACPRO] = "macpro",
9640 [ALC885_MB5] = "mb5",
e458b1fa 9641 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9642 [ALC885_MBA21] = "mba21",
4953550a
TI
9643 [ALC885_MBP3] = "mbp3",
9644 [ALC885_IMAC24] = "imac24",
4b7e1803 9645 [ALC885_IMAC91] = "imac91",
4953550a 9646 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9647 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9648 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9649 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9650 [ALC883_TARGA_DIG] = "targa-dig",
9651 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9652 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9653 [ALC883_ACER] = "acer",
2880a867 9654 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9655 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9656 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9657 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9658 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9659 [ALC883_MEDION] = "medion",
272a527c 9660 [ALC883_MEDION_MD2] = "medion-md2",
7ad7b218 9661 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9662 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9663 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9664 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9665 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9666 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9667 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9668 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9669 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9670 [ALC883_MITAC] = "mitac",
a65cc60f 9671 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9672 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9673 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9674 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9675 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9676 [ALC889A_INTEL] = "intel-alc889a",
9677 [ALC889_INTEL] = "intel-x58",
3ab90935 9678 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9679 [ALC889A_MB31] = "mb31",
3e1647c5 9680 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9681 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9682};
9683
4953550a
TI
9684static struct snd_pci_quirk alc882_cfg_tbl[] = {
9685 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9686
ac3e3741 9687 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9688 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9689 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9690 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9691 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9692 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9693 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9694 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9695 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9696 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9697 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9698 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9699 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9700 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9701 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9702 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9703 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9704 ALC888_ACER_ASPIRE_6530G),
cc374c47 9705 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9706 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9707 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9708 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9709 /* default Acer -- disabled as it causes more problems.
9710 * model=auto should work fine now
9711 */
9712 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9713
5795b9e6 9714 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9715
febe3375 9716 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9717 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9718 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9719 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9720 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9721 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9722
9723 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9724 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9725 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9726 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9727 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9728 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9729 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9730 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9731 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9732 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9733 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9734
9735 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9736 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9737 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9738 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9739 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9740 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9741 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9742 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9743 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9744
6f3bf657 9745 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9746 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9747 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9748 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9749 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9750 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9751 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9752 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9753 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9754 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9755 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9756 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9757 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9758 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9759 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9760 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9761 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9762 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9763 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9764 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9765 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9766 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9767 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9768 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9769 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9770 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9771 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9772 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9773 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9774 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9775 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9776
ac3e3741 9777 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9778 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9779 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9780 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9781 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9782 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9783 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9784 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9785 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9786 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9787 ALC883_FUJITSU_PI2515),
bfb53037 9788 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9789 ALC888_FUJITSU_XA3530),
272a527c 9790 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9791 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9792 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9793 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9794 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
272a527c 9795 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
959973b9 9796 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9797 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9798 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9799
17bba1b7
J
9800 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9801 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9802 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9803 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9804 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9805 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9806 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9807
4953550a 9808 {}
f3cd3f5d
WF
9809};
9810
4953550a
TI
9811/* codec SSID table for Intel Mac */
9812static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9813 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9814 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9815 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9816 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9817 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9818 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9819 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 9820 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 9821 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 9822 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 9823 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
9824 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9825 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9826 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9827 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9828 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 9829 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
9830 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9831 * so apparently no perfect solution yet
4953550a
TI
9832 */
9833 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9834 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9835 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9836 {} /* terminator */
b25c9da1
WF
9837};
9838
4953550a
TI
9839static struct alc_config_preset alc882_presets[] = {
9840 [ALC882_3ST_DIG] = {
9841 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9842 .init_verbs = { alc882_base_init_verbs,
9843 alc882_adc1_init_verbs },
4953550a
TI
9844 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9845 .dac_nids = alc882_dac_nids,
9846 .dig_out_nid = ALC882_DIGOUT_NID,
9847 .dig_in_nid = ALC882_DIGIN_NID,
9848 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9849 .channel_mode = alc882_ch_modes,
9850 .need_dac_fix = 1,
9851 .input_mux = &alc882_capture_source,
9852 },
9853 [ALC882_6ST_DIG] = {
9854 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9855 .init_verbs = { alc882_base_init_verbs,
9856 alc882_adc1_init_verbs },
4953550a
TI
9857 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9858 .dac_nids = alc882_dac_nids,
9859 .dig_out_nid = ALC882_DIGOUT_NID,
9860 .dig_in_nid = ALC882_DIGIN_NID,
9861 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9862 .channel_mode = alc882_sixstack_modes,
9863 .input_mux = &alc882_capture_source,
9864 },
9865 [ALC882_ARIMA] = {
9866 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9867 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9868 alc882_eapd_verbs },
4953550a
TI
9869 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9870 .dac_nids = alc882_dac_nids,
9871 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9872 .channel_mode = alc882_sixstack_modes,
9873 .input_mux = &alc882_capture_source,
9874 },
9875 [ALC882_W2JC] = {
9876 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9877 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9878 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
9879 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9880 .dac_nids = alc882_dac_nids,
9881 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9882 .channel_mode = alc880_threestack_modes,
9883 .need_dac_fix = 1,
9884 .input_mux = &alc882_capture_source,
9885 .dig_out_nid = ALC882_DIGOUT_NID,
9886 },
76e6f5a9
RH
9887 [ALC885_MBA21] = {
9888 .mixers = { alc885_mba21_mixer },
9889 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9890 .num_dacs = 2,
9891 .dac_nids = alc882_dac_nids,
9892 .channel_mode = alc885_mba21_ch_modes,
9893 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9894 .input_mux = &alc882_capture_source,
9895 .unsol_event = alc_automute_amp_unsol_event,
9896 .setup = alc885_mba21_setup,
9897 .init_hook = alc_automute_amp,
9898 },
4953550a
TI
9899 [ALC885_MBP3] = {
9900 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9901 .init_verbs = { alc885_mbp3_init_verbs,
9902 alc880_gpio1_init_verbs },
be0ae923 9903 .num_dacs = 2,
4953550a 9904 .dac_nids = alc882_dac_nids,
be0ae923
TI
9905 .hp_nid = 0x04,
9906 .channel_mode = alc885_mbp_4ch_modes,
9907 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
9908 .input_mux = &alc882_capture_source,
9909 .dig_out_nid = ALC882_DIGOUT_NID,
9910 .dig_in_nid = ALC882_DIGIN_NID,
9911 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9912 .setup = alc885_mbp3_setup,
9913 .init_hook = alc_automute_amp,
4953550a
TI
9914 },
9915 [ALC885_MB5] = {
9916 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
9917 .init_verbs = { alc885_mb5_init_verbs,
9918 alc880_gpio1_init_verbs },
9919 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9920 .dac_nids = alc882_dac_nids,
9921 .channel_mode = alc885_mb5_6ch_modes,
9922 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
9923 .input_mux = &mb5_capture_source,
9924 .dig_out_nid = ALC882_DIGOUT_NID,
9925 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9926 .unsol_event = alc_automute_amp_unsol_event,
9927 .setup = alc885_mb5_setup,
9928 .init_hook = alc_automute_amp,
4953550a 9929 },
e458b1fa
LY
9930 [ALC885_MACMINI3] = {
9931 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9932 .init_verbs = { alc885_macmini3_init_verbs,
9933 alc880_gpio1_init_verbs },
9934 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9935 .dac_nids = alc882_dac_nids,
9936 .channel_mode = alc885_macmini3_6ch_modes,
9937 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9938 .input_mux = &macmini3_capture_source,
9939 .dig_out_nid = ALC882_DIGOUT_NID,
9940 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9941 .unsol_event = alc_automute_amp_unsol_event,
9942 .setup = alc885_macmini3_setup,
9943 .init_hook = alc_automute_amp,
e458b1fa 9944 },
4953550a
TI
9945 [ALC885_MACPRO] = {
9946 .mixers = { alc882_macpro_mixer },
9947 .init_verbs = { alc882_macpro_init_verbs },
9948 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9949 .dac_nids = alc882_dac_nids,
9950 .dig_out_nid = ALC882_DIGOUT_NID,
9951 .dig_in_nid = ALC882_DIGIN_NID,
9952 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9953 .channel_mode = alc882_ch_modes,
9954 .input_mux = &alc882_capture_source,
9955 .init_hook = alc885_macpro_init_hook,
9956 },
9957 [ALC885_IMAC24] = {
9958 .mixers = { alc885_imac24_mixer },
9959 .init_verbs = { alc885_imac24_init_verbs },
9960 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9961 .dac_nids = alc882_dac_nids,
9962 .dig_out_nid = ALC882_DIGOUT_NID,
9963 .dig_in_nid = ALC882_DIGIN_NID,
9964 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9965 .channel_mode = alc882_ch_modes,
9966 .input_mux = &alc882_capture_source,
9967 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 9968 .setup = alc885_imac24_setup,
4953550a
TI
9969 .init_hook = alc885_imac24_init_hook,
9970 },
4b7e1803 9971 [ALC885_IMAC91] = {
b7cccc52 9972 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
9973 .init_verbs = { alc885_imac91_init_verbs,
9974 alc880_gpio1_init_verbs },
9975 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9976 .dac_nids = alc882_dac_nids,
b7cccc52
JM
9977 .channel_mode = alc885_mba21_ch_modes,
9978 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9979 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
9980 .dig_out_nid = ALC882_DIGOUT_NID,
9981 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9982 .unsol_event = alc_automute_amp_unsol_event,
9983 .setup = alc885_imac91_setup,
9984 .init_hook = alc_automute_amp,
4b7e1803 9985 },
4953550a
TI
9986 [ALC882_TARGA] = {
9987 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 9988 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 9989 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
9990 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9991 .dac_nids = alc882_dac_nids,
9992 .dig_out_nid = ALC882_DIGOUT_NID,
9993 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9994 .adc_nids = alc882_adc_nids,
9995 .capsrc_nids = alc882_capsrc_nids,
9996 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9997 .channel_mode = alc882_3ST_6ch_modes,
9998 .need_dac_fix = 1,
9999 .input_mux = &alc882_capture_source,
10000 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
10001 .setup = alc882_targa_setup,
10002 .init_hook = alc882_targa_automute,
4953550a
TI
10003 },
10004 [ALC882_ASUS_A7J] = {
10005 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10006 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10007 alc882_asus_a7j_verbs},
4953550a
TI
10008 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10009 .dac_nids = alc882_dac_nids,
10010 .dig_out_nid = ALC882_DIGOUT_NID,
10011 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10012 .adc_nids = alc882_adc_nids,
10013 .capsrc_nids = alc882_capsrc_nids,
10014 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10015 .channel_mode = alc882_3ST_6ch_modes,
10016 .need_dac_fix = 1,
10017 .input_mux = &alc882_capture_source,
10018 },
10019 [ALC882_ASUS_A7M] = {
10020 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10021 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10022 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10023 alc882_asus_a7m_verbs },
10024 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10025 .dac_nids = alc882_dac_nids,
10026 .dig_out_nid = ALC882_DIGOUT_NID,
10027 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10028 .channel_mode = alc880_threestack_modes,
10029 .need_dac_fix = 1,
10030 .input_mux = &alc882_capture_source,
10031 },
9c7f852e
TI
10032 [ALC883_3ST_2ch_DIG] = {
10033 .mixers = { alc883_3ST_2ch_mixer },
10034 .init_verbs = { alc883_init_verbs },
10035 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10036 .dac_nids = alc883_dac_nids,
10037 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10038 .dig_in_nid = ALC883_DIGIN_NID,
10039 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10040 .channel_mode = alc883_3ST_2ch_modes,
10041 .input_mux = &alc883_capture_source,
10042 },
10043 [ALC883_3ST_6ch_DIG] = {
10044 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10045 .init_verbs = { alc883_init_verbs },
10046 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10047 .dac_nids = alc883_dac_nids,
10048 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10049 .dig_in_nid = ALC883_DIGIN_NID,
10050 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10051 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10052 .need_dac_fix = 1,
9c7f852e 10053 .input_mux = &alc883_capture_source,
f12ab1e0 10054 },
9c7f852e
TI
10055 [ALC883_3ST_6ch] = {
10056 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10057 .init_verbs = { alc883_init_verbs },
10058 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10059 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10060 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10061 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10062 .need_dac_fix = 1,
9c7f852e 10063 .input_mux = &alc883_capture_source,
f12ab1e0 10064 },
17bba1b7
J
10065 [ALC883_3ST_6ch_INTEL] = {
10066 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10067 .init_verbs = { alc883_init_verbs },
10068 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10069 .dac_nids = alc883_dac_nids,
10070 .dig_out_nid = ALC883_DIGOUT_NID,
10071 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10072 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10073 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10074 .channel_mode = alc883_3ST_6ch_intel_modes,
10075 .need_dac_fix = 1,
10076 .input_mux = &alc883_3stack_6ch_intel,
10077 },
87a8c370
JK
10078 [ALC889A_INTEL] = {
10079 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10080 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10081 alc_hp15_unsol_verbs },
87a8c370
JK
10082 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10083 .dac_nids = alc883_dac_nids,
10084 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10085 .adc_nids = alc889_adc_nids,
10086 .dig_out_nid = ALC883_DIGOUT_NID,
10087 .dig_in_nid = ALC883_DIGIN_NID,
10088 .slave_dig_outs = alc883_slave_dig_outs,
10089 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10090 .channel_mode = alc889_8ch_intel_modes,
10091 .capsrc_nids = alc889_capsrc_nids,
10092 .input_mux = &alc889_capture_source,
4f5d1706
TI
10093 .setup = alc889_automute_setup,
10094 .init_hook = alc_automute_amp,
6732bd0d 10095 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10096 .need_dac_fix = 1,
10097 },
10098 [ALC889_INTEL] = {
10099 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10100 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10101 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10102 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10103 .dac_nids = alc883_dac_nids,
10104 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10105 .adc_nids = alc889_adc_nids,
10106 .dig_out_nid = ALC883_DIGOUT_NID,
10107 .dig_in_nid = ALC883_DIGIN_NID,
10108 .slave_dig_outs = alc883_slave_dig_outs,
10109 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10110 .channel_mode = alc889_8ch_intel_modes,
10111 .capsrc_nids = alc889_capsrc_nids,
10112 .input_mux = &alc889_capture_source,
4f5d1706 10113 .setup = alc889_automute_setup,
6732bd0d
WF
10114 .init_hook = alc889_intel_init_hook,
10115 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
10116 .need_dac_fix = 1,
10117 },
9c7f852e
TI
10118 [ALC883_6ST_DIG] = {
10119 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10120 .init_verbs = { alc883_init_verbs },
10121 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10122 .dac_nids = alc883_dac_nids,
10123 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10124 .dig_in_nid = ALC883_DIGIN_NID,
10125 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10126 .channel_mode = alc883_sixstack_modes,
10127 .input_mux = &alc883_capture_source,
10128 },
ccc656ce 10129 [ALC883_TARGA_DIG] = {
c259249f 10130 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10131 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10132 alc883_targa_verbs},
ccc656ce
KY
10133 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10134 .dac_nids = alc883_dac_nids,
10135 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10136 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10137 .channel_mode = alc883_3ST_6ch_modes,
10138 .need_dac_fix = 1,
10139 .input_mux = &alc883_capture_source,
c259249f 10140 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10141 .setup = alc882_targa_setup,
10142 .init_hook = alc882_targa_automute,
ccc656ce
KY
10143 },
10144 [ALC883_TARGA_2ch_DIG] = {
c259249f 10145 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10146 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10147 alc883_targa_verbs},
ccc656ce
KY
10148 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10149 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10150 .adc_nids = alc883_adc_nids_alt,
10151 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10152 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10153 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10154 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10155 .channel_mode = alc883_3ST_2ch_modes,
10156 .input_mux = &alc883_capture_source,
c259249f 10157 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10158 .setup = alc882_targa_setup,
10159 .init_hook = alc882_targa_automute,
ccc656ce 10160 },
64a8be74 10161 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10162 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10163 alc883_chmode_mixer },
64a8be74 10164 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10165 alc883_targa_verbs },
64a8be74
DH
10166 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10167 .dac_nids = alc883_dac_nids,
10168 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10169 .adc_nids = alc883_adc_nids_rev,
10170 .capsrc_nids = alc883_capsrc_nids_rev,
10171 .dig_out_nid = ALC883_DIGOUT_NID,
10172 .dig_in_nid = ALC883_DIGIN_NID,
10173 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10174 .channel_mode = alc883_4ST_8ch_modes,
10175 .need_dac_fix = 1,
10176 .input_mux = &alc883_capture_source,
c259249f 10177 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10178 .setup = alc882_targa_setup,
10179 .init_hook = alc882_targa_automute,
64a8be74 10180 },
bab282b9 10181 [ALC883_ACER] = {
676a9b53 10182 .mixers = { alc883_base_mixer },
bab282b9
VA
10183 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10184 * and the headphone jack. Turn this on and rely on the
10185 * standard mute methods whenever the user wants to turn
10186 * these outputs off.
10187 */
10188 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10189 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10190 .dac_nids = alc883_dac_nids,
bab282b9
VA
10191 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10192 .channel_mode = alc883_3ST_2ch_modes,
10193 .input_mux = &alc883_capture_source,
10194 },
2880a867 10195 [ALC883_ACER_ASPIRE] = {
676a9b53 10196 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10197 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10198 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10199 .dac_nids = alc883_dac_nids,
10200 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10201 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10202 .channel_mode = alc883_3ST_2ch_modes,
10203 .input_mux = &alc883_capture_source,
a9fd4f3f 10204 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10205 .setup = alc883_acer_aspire_setup,
10206 .init_hook = alc_automute_amp,
d1a991a6 10207 },
5b2d1eca 10208 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 10209 .mixers = { alc888_base_mixer,
5b2d1eca
VP
10210 alc883_chmode_mixer },
10211 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10212 alc888_acer_aspire_4930g_verbs },
10213 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10214 .dac_nids = alc883_dac_nids,
10215 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10216 .adc_nids = alc883_adc_nids_rev,
10217 .capsrc_nids = alc883_capsrc_nids_rev,
10218 .dig_out_nid = ALC883_DIGOUT_NID,
10219 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10220 .channel_mode = alc883_3ST_6ch_modes,
10221 .need_dac_fix = 1,
973b8cb0 10222 .const_channel_count = 6,
5b2d1eca 10223 .num_mux_defs =
ef8ef5fb
VP
10224 ARRAY_SIZE(alc888_2_capture_sources),
10225 .input_mux = alc888_2_capture_sources,
d2fd4b09 10226 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10227 .setup = alc888_acer_aspire_4930g_setup,
10228 .init_hook = alc_automute_amp,
d2fd4b09
TV
10229 },
10230 [ALC888_ACER_ASPIRE_6530G] = {
10231 .mixers = { alc888_acer_aspire_6530_mixer },
10232 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10233 alc888_acer_aspire_6530g_verbs },
10234 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10235 .dac_nids = alc883_dac_nids,
10236 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10237 .adc_nids = alc883_adc_nids_rev,
10238 .capsrc_nids = alc883_capsrc_nids_rev,
10239 .dig_out_nid = ALC883_DIGOUT_NID,
10240 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10241 .channel_mode = alc883_3ST_2ch_modes,
10242 .num_mux_defs =
10243 ARRAY_SIZE(alc888_2_capture_sources),
10244 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 10245 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10246 .setup = alc888_acer_aspire_6530g_setup,
10247 .init_hook = alc_automute_amp,
5b2d1eca 10248 },
3b315d70 10249 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10250 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10251 alc883_chmode_mixer },
10252 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10253 alc889_acer_aspire_8930g_verbs,
10254 alc889_eapd_verbs},
3b315d70
HM
10255 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10256 .dac_nids = alc883_dac_nids,
018df418
HM
10257 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10258 .adc_nids = alc889_adc_nids,
10259 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10260 .dig_out_nid = ALC883_DIGOUT_NID,
10261 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10262 .channel_mode = alc883_3ST_6ch_modes,
10263 .need_dac_fix = 1,
10264 .const_channel_count = 6,
10265 .num_mux_defs =
018df418
HM
10266 ARRAY_SIZE(alc889_capture_sources),
10267 .input_mux = alc889_capture_sources,
3b315d70 10268 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10269 .setup = alc889_acer_aspire_8930g_setup,
10270 .init_hook = alc_automute_amp,
f5de24b0 10271#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10272 .power_hook = alc_power_eapd,
f5de24b0 10273#endif
3b315d70 10274 },
fc86f954
DK
10275 [ALC888_ACER_ASPIRE_7730G] = {
10276 .mixers = { alc883_3ST_6ch_mixer,
10277 alc883_chmode_mixer },
10278 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10279 alc888_acer_aspire_7730G_verbs },
10280 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10281 .dac_nids = alc883_dac_nids,
10282 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10283 .adc_nids = alc883_adc_nids_rev,
10284 .capsrc_nids = alc883_capsrc_nids_rev,
10285 .dig_out_nid = ALC883_DIGOUT_NID,
10286 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10287 .channel_mode = alc883_3ST_6ch_modes,
10288 .need_dac_fix = 1,
10289 .const_channel_count = 6,
10290 .input_mux = &alc883_capture_source,
10291 .unsol_event = alc_automute_amp_unsol_event,
10292 .setup = alc888_acer_aspire_6530g_setup,
10293 .init_hook = alc_automute_amp,
10294 },
c07584c8
TD
10295 [ALC883_MEDION] = {
10296 .mixers = { alc883_fivestack_mixer,
10297 alc883_chmode_mixer },
10298 .init_verbs = { alc883_init_verbs,
b373bdeb 10299 alc883_medion_eapd_verbs },
c07584c8
TD
10300 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10301 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10302 .adc_nids = alc883_adc_nids_alt,
10303 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10304 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10305 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10306 .channel_mode = alc883_sixstack_modes,
10307 .input_mux = &alc883_capture_source,
b373bdeb 10308 },
272a527c
KY
10309 [ALC883_MEDION_MD2] = {
10310 .mixers = { alc883_medion_md2_mixer},
10311 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
10312 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10313 .dac_nids = alc883_dac_nids,
10314 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10315 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10316 .channel_mode = alc883_3ST_2ch_modes,
10317 .input_mux = &alc883_capture_source,
a9fd4f3f 10318 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10319 .setup = alc883_medion_md2_setup,
10320 .init_hook = alc_automute_amp,
ea1fb29a 10321 },
7ad7b218
MC
10322 [ALC883_MEDION_WIM2160] = {
10323 .mixers = { alc883_medion_wim2160_mixer },
10324 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10325 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10326 .dac_nids = alc883_dac_nids,
10327 .dig_out_nid = ALC883_DIGOUT_NID,
10328 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10329 .adc_nids = alc883_adc_nids,
10330 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10331 .channel_mode = alc883_3ST_2ch_modes,
10332 .input_mux = &alc883_capture_source,
10333 .unsol_event = alc_automute_amp_unsol_event,
10334 .setup = alc883_medion_wim2160_setup,
10335 .init_hook = alc_automute_amp,
10336 },
b373bdeb 10337 [ALC883_LAPTOP_EAPD] = {
676a9b53 10338 .mixers = { alc883_base_mixer },
b373bdeb
AN
10339 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10340 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10341 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10342 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10343 .channel_mode = alc883_3ST_2ch_modes,
10344 .input_mux = &alc883_capture_source,
10345 },
a65cc60f 10346 [ALC883_CLEVO_M540R] = {
10347 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10348 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10349 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10350 .dac_nids = alc883_dac_nids,
10351 .dig_out_nid = ALC883_DIGOUT_NID,
10352 .dig_in_nid = ALC883_DIGIN_NID,
10353 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10354 .channel_mode = alc883_3ST_6ch_clevo_modes,
10355 .need_dac_fix = 1,
10356 .input_mux = &alc883_capture_source,
10357 /* This machine has the hardware HP auto-muting, thus
10358 * we need no software mute via unsol event
10359 */
10360 },
0c4cc443
HRK
10361 [ALC883_CLEVO_M720] = {
10362 .mixers = { alc883_clevo_m720_mixer },
10363 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10364 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10365 .dac_nids = alc883_dac_nids,
10366 .dig_out_nid = ALC883_DIGOUT_NID,
10367 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10368 .channel_mode = alc883_3ST_2ch_modes,
10369 .input_mux = &alc883_capture_source,
0c4cc443 10370 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10371 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10372 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10373 },
bc9f98a9
KY
10374 [ALC883_LENOVO_101E_2ch] = {
10375 .mixers = { alc883_lenovo_101e_2ch_mixer},
10376 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10377 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10378 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10379 .adc_nids = alc883_adc_nids_alt,
10380 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10381 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10382 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10383 .channel_mode = alc883_3ST_2ch_modes,
10384 .input_mux = &alc883_lenovo_101e_capture_source,
10385 .unsol_event = alc883_lenovo_101e_unsol_event,
10386 .init_hook = alc883_lenovo_101e_all_automute,
10387 },
272a527c
KY
10388 [ALC883_LENOVO_NB0763] = {
10389 .mixers = { alc883_lenovo_nb0763_mixer },
10390 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10391 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10392 .dac_nids = alc883_dac_nids,
272a527c
KY
10393 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10394 .channel_mode = alc883_3ST_2ch_modes,
10395 .need_dac_fix = 1,
10396 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 10397 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10398 .setup = alc883_medion_md2_setup,
10399 .init_hook = alc_automute_amp,
272a527c
KY
10400 },
10401 [ALC888_LENOVO_MS7195_DIG] = {
10402 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10403 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10404 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10405 .dac_nids = alc883_dac_nids,
10406 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10407 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10408 .channel_mode = alc883_3ST_6ch_modes,
10409 .need_dac_fix = 1,
10410 .input_mux = &alc883_capture_source,
10411 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10412 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
10413 },
10414 [ALC883_HAIER_W66] = {
c259249f 10415 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10416 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10417 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10418 .dac_nids = alc883_dac_nids,
10419 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10420 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10421 .channel_mode = alc883_3ST_2ch_modes,
10422 .input_mux = &alc883_capture_source,
a9fd4f3f 10423 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10424 .setup = alc883_haier_w66_setup,
10425 .init_hook = alc_automute_amp,
eea6419e 10426 },
4723c022 10427 [ALC888_3ST_HP] = {
eea6419e 10428 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10429 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10430 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10431 .dac_nids = alc883_dac_nids,
4723c022
CM
10432 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10433 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10434 .need_dac_fix = 1,
10435 .input_mux = &alc883_capture_source,
a9fd4f3f 10436 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10437 .setup = alc888_3st_hp_setup,
10438 .init_hook = alc_automute_amp,
8341de60 10439 },
5795b9e6 10440 [ALC888_6ST_DELL] = {
f24dbdc6 10441 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10442 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10443 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10444 .dac_nids = alc883_dac_nids,
10445 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10446 .dig_in_nid = ALC883_DIGIN_NID,
10447 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10448 .channel_mode = alc883_sixstack_modes,
10449 .input_mux = &alc883_capture_source,
a9fd4f3f 10450 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10451 .setup = alc888_6st_dell_setup,
10452 .init_hook = alc_automute_amp,
5795b9e6 10453 },
a8848bd6
AS
10454 [ALC883_MITAC] = {
10455 .mixers = { alc883_mitac_mixer },
10456 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10457 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10458 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10459 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10460 .channel_mode = alc883_3ST_2ch_modes,
10461 .input_mux = &alc883_capture_source,
a9fd4f3f 10462 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10463 .setup = alc883_mitac_setup,
10464 .init_hook = alc_automute_amp,
a8848bd6 10465 },
fb97dc67
J
10466 [ALC883_FUJITSU_PI2515] = {
10467 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10468 .init_verbs = { alc883_init_verbs,
10469 alc883_2ch_fujitsu_pi2515_verbs},
10470 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10471 .dac_nids = alc883_dac_nids,
10472 .dig_out_nid = ALC883_DIGOUT_NID,
10473 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10474 .channel_mode = alc883_3ST_2ch_modes,
10475 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10476 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10477 .setup = alc883_2ch_fujitsu_pi2515_setup,
10478 .init_hook = alc_automute_amp,
fb97dc67 10479 },
ef8ef5fb
VP
10480 [ALC888_FUJITSU_XA3530] = {
10481 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10482 .init_verbs = { alc883_init_verbs,
10483 alc888_fujitsu_xa3530_verbs },
10484 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10485 .dac_nids = alc883_dac_nids,
10486 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10487 .adc_nids = alc883_adc_nids_rev,
10488 .capsrc_nids = alc883_capsrc_nids_rev,
10489 .dig_out_nid = ALC883_DIGOUT_NID,
10490 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10491 .channel_mode = alc888_4ST_8ch_intel_modes,
10492 .num_mux_defs =
10493 ARRAY_SIZE(alc888_2_capture_sources),
10494 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10495 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10496 .setup = alc888_fujitsu_xa3530_setup,
10497 .init_hook = alc_automute_amp,
ef8ef5fb 10498 },
e2757d5e
KY
10499 [ALC888_LENOVO_SKY] = {
10500 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10501 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10502 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10503 .dac_nids = alc883_dac_nids,
10504 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10505 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10506 .channel_mode = alc883_sixstack_modes,
10507 .need_dac_fix = 1,
10508 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10509 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10510 .setup = alc888_lenovo_sky_setup,
10511 .init_hook = alc_automute_amp,
e2757d5e
KY
10512 },
10513 [ALC888_ASUS_M90V] = {
10514 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10515 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10516 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10517 .dac_nids = alc883_dac_nids,
10518 .dig_out_nid = ALC883_DIGOUT_NID,
10519 .dig_in_nid = ALC883_DIGIN_NID,
10520 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10521 .channel_mode = alc883_3ST_6ch_modes,
10522 .need_dac_fix = 1,
10523 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10524 .unsol_event = alc_sku_unsol_event,
10525 .setup = alc883_mode2_setup,
10526 .init_hook = alc_inithook,
e2757d5e
KY
10527 },
10528 [ALC888_ASUS_EEE1601] = {
10529 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10530 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10531 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10532 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10533 .dac_nids = alc883_dac_nids,
10534 .dig_out_nid = ALC883_DIGOUT_NID,
10535 .dig_in_nid = ALC883_DIGIN_NID,
10536 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10537 .channel_mode = alc883_3ST_2ch_modes,
10538 .need_dac_fix = 1,
10539 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10540 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10541 .init_hook = alc883_eee1601_inithook,
10542 },
3ab90935
WF
10543 [ALC1200_ASUS_P5Q] = {
10544 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10545 .init_verbs = { alc883_init_verbs },
10546 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10547 .dac_nids = alc883_dac_nids,
10548 .dig_out_nid = ALC1200_DIGOUT_NID,
10549 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10550 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10551 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10552 .channel_mode = alc883_sixstack_modes,
10553 .input_mux = &alc883_capture_source,
10554 },
eb4c41d3
TS
10555 [ALC889A_MB31] = {
10556 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10557 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10558 alc880_gpio1_init_verbs },
10559 .adc_nids = alc883_adc_nids,
10560 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10561 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10562 .dac_nids = alc883_dac_nids,
10563 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10564 .channel_mode = alc889A_mb31_6ch_modes,
10565 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10566 .input_mux = &alc889A_mb31_capture_source,
10567 .dig_out_nid = ALC883_DIGOUT_NID,
10568 .unsol_event = alc889A_mb31_unsol_event,
10569 .init_hook = alc889A_mb31_automute,
10570 },
3e1647c5
GG
10571 [ALC883_SONY_VAIO_TT] = {
10572 .mixers = { alc883_vaiott_mixer },
10573 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10574 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10575 .dac_nids = alc883_dac_nids,
10576 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10577 .channel_mode = alc883_3ST_2ch_modes,
10578 .input_mux = &alc883_capture_source,
10579 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10580 .setup = alc883_vaiott_setup,
10581 .init_hook = alc_automute_amp,
3e1647c5 10582 },
9c7f852e
TI
10583};
10584
10585
4953550a
TI
10586/*
10587 * Pin config fixes
10588 */
10589enum {
954a29c8
TI
10590 PINFIX_ABIT_AW9D_MAX,
10591 PINFIX_PB_M5210,
4953550a
TI
10592};
10593
f8f25ba3
TI
10594static const struct alc_fixup alc882_fixups[] = {
10595 [PINFIX_ABIT_AW9D_MAX] = {
73413b12
TI
10596 .pins = (const struct alc_pincfg[]) {
10597 { 0x15, 0x01080104 }, /* side */
10598 { 0x16, 0x01011012 }, /* rear */
10599 { 0x17, 0x01016011 }, /* clfe */
10600 { }
10601 }
f8f25ba3 10602 },
954a29c8 10603 [PINFIX_PB_M5210] = {
73413b12
TI
10604 .verbs = (const struct hda_verb[]) {
10605 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10606 {}
10607 }
954a29c8 10608 },
4953550a
TI
10609};
10610
f8f25ba3 10611static struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10612 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
4953550a
TI
10613 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10614 {}
10615};
10616
9c7f852e
TI
10617/*
10618 * BIOS auto configuration
10619 */
05f5f477
TI
10620static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10621 const struct auto_pin_cfg *cfg)
10622{
10623 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10624}
10625
4953550a 10626static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10627 hda_nid_t nid, int pin_type,
489008cd 10628 hda_nid_t dac)
9c7f852e 10629{
f12ab1e0
TI
10630 int idx;
10631
489008cd 10632 /* set as output */
f6c7e546 10633 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10634
10635 if (dac == 0x25)
9c7f852e 10636 idx = 4;
489008cd
TI
10637 else if (dac >= 0x02 && dac <= 0x05)
10638 idx = dac - 2;
f9700d5a 10639 else
489008cd 10640 return;
9c7f852e 10641 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
10642}
10643
4953550a 10644static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10645{
10646 struct alc_spec *spec = codec->spec;
10647 int i;
10648
10649 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10650 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10651 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10652 if (nid)
4953550a 10653 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 10654 spec->multiout.dac_nids[i]);
9c7f852e
TI
10655 }
10656}
10657
4953550a 10658static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10659{
10660 struct alc_spec *spec = codec->spec;
489008cd 10661 hda_nid_t pin, dac;
5855fb80 10662 int i;
9c7f852e 10663
5855fb80
TI
10664 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
10665 pin = spec->autocfg.hp_pins[i];
10666 if (!pin)
10667 break;
489008cd
TI
10668 dac = spec->multiout.hp_nid;
10669 if (!dac)
10670 dac = spec->multiout.dac_nids[0]; /* to front */
10671 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10672 }
5855fb80
TI
10673 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
10674 pin = spec->autocfg.speaker_pins[i];
10675 if (!pin)
10676 break;
489008cd
TI
10677 dac = spec->multiout.extra_out_nid[0];
10678 if (!dac)
10679 dac = spec->multiout.dac_nids[0]; /* to front */
10680 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10681 }
9c7f852e
TI
10682}
10683
4953550a 10684static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10685{
10686 struct alc_spec *spec = codec->spec;
66ceeb6b 10687 struct auto_pin_cfg *cfg = &spec->autocfg;
9c7f852e
TI
10688 int i;
10689
66ceeb6b
TI
10690 for (i = 0; i < cfg->num_inputs; i++) {
10691 hda_nid_t nid = cfg->inputs[i].pin;
30ea098f 10692 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
4953550a
TI
10693 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10694 snd_hda_codec_write(codec, nid, 0,
10695 AC_VERB_SET_AMP_GAIN_MUTE,
10696 AMP_OUT_MUTE);
10697 }
10698}
10699
10700static void alc882_auto_init_input_src(struct hda_codec *codec)
10701{
10702 struct alc_spec *spec = codec->spec;
10703 int c;
10704
10705 for (c = 0; c < spec->num_adc_nids; c++) {
10706 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10707 hda_nid_t nid = spec->capsrc_nids[c];
10708 unsigned int mux_idx;
10709 const struct hda_input_mux *imux;
10710 int conns, mute, idx, item;
10711
10712 conns = snd_hda_get_connections(codec, nid, conn_list,
10713 ARRAY_SIZE(conn_list));
10714 if (conns < 0)
10715 continue;
10716 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10717 imux = &spec->input_mux[mux_idx];
5311114d
TI
10718 if (!imux->num_items && mux_idx > 0)
10719 imux = &spec->input_mux[0];
4953550a
TI
10720 for (idx = 0; idx < conns; idx++) {
10721 /* if the current connection is the selected one,
10722 * unmute it as default - otherwise mute it
10723 */
10724 mute = AMP_IN_MUTE(idx);
10725 for (item = 0; item < imux->num_items; item++) {
10726 if (imux->items[item].index == idx) {
10727 if (spec->cur_mux[c] == item)
10728 mute = AMP_IN_UNMUTE(idx);
10729 break;
10730 }
10731 }
10732 /* check if we have a selector or mixer
10733 * we could check for the widget type instead, but
10734 * just check for Amp-In presence (in case of mixer
10735 * without amp-in there is something wrong, this
10736 * function shouldn't be used or capsrc nid is wrong)
10737 */
10738 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10739 snd_hda_codec_write(codec, nid, 0,
10740 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10741 mute);
10742 else if (mute != AMP_IN_MUTE(idx))
10743 snd_hda_codec_write(codec, nid, 0,
10744 AC_VERB_SET_CONNECT_SEL,
10745 idx);
9c7f852e
TI
10746 }
10747 }
10748}
10749
4953550a
TI
10750/* add mic boosts if needed */
10751static int alc_auto_add_mic_boost(struct hda_codec *codec)
10752{
10753 struct alc_spec *spec = codec->spec;
66ceeb6b
TI
10754 struct auto_pin_cfg *cfg = &spec->autocfg;
10755 int i, err;
4953550a
TI
10756 hda_nid_t nid;
10757
66ceeb6b 10758 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 10759 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
10760 break;
10761 nid = cfg->inputs[i].pin;
10762 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
10a20af7
TI
10763 char label[32];
10764 snprintf(label, sizeof(label), "%s Boost",
10765 hda_get_autocfg_input_label(codec, cfg, i));
66ceeb6b 10766 err = add_control(spec, ALC_CTL_WIDGET_VOL, label, 0,
4953550a 10767 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
10768 if (err < 0)
10769 return err;
10770 }
4953550a
TI
10771 }
10772 return 0;
10773}
f511b01c 10774
9c7f852e 10775/* almost identical with ALC880 parser... */
4953550a 10776static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10777{
10778 struct alc_spec *spec = codec->spec;
05f5f477 10779 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 10780 int err;
9c7f852e 10781
05f5f477
TI
10782 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10783 alc882_ignore);
9c7f852e
TI
10784 if (err < 0)
10785 return err;
05f5f477
TI
10786 if (!spec->autocfg.line_outs)
10787 return 0; /* can't find valid BIOS pin config */
776e184e 10788
05f5f477
TI
10789 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10790 if (err < 0)
10791 return err;
10792 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
10793 if (err < 0)
10794 return err;
10795 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10796 "Headphone");
05f5f477
TI
10797 if (err < 0)
10798 return err;
10799 err = alc880_auto_create_extra_out(spec,
10800 spec->autocfg.speaker_pins[0],
10801 "Speaker");
10802 if (err < 0)
10803 return err;
05f5f477 10804 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10805 if (err < 0)
10806 return err;
10807
05f5f477
TI
10808 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10809
757899ac 10810 alc_auto_parse_digital(codec);
05f5f477
TI
10811
10812 if (spec->kctls.list)
10813 add_mixer(spec, spec->kctls.list);
10814
10815 add_verb(spec, alc883_auto_init_verbs);
4953550a 10816 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10817 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10818 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10819
05f5f477
TI
10820 spec->num_mux_defs = 1;
10821 spec->input_mux = &spec->private_imux[0];
10822
6227cdce 10823 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10824
10825 err = alc_auto_add_mic_boost(codec);
10826 if (err < 0)
10827 return err;
61b9b9b1 10828
776e184e 10829 return 1; /* config found */
9c7f852e
TI
10830}
10831
10832/* additional initialization for auto-configuration model */
4953550a 10833static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10834{
f6c7e546 10835 struct alc_spec *spec = codec->spec;
4953550a
TI
10836 alc882_auto_init_multi_out(codec);
10837 alc882_auto_init_hp_out(codec);
10838 alc882_auto_init_analog_input(codec);
10839 alc882_auto_init_input_src(codec);
757899ac 10840 alc_auto_init_digital(codec);
f6c7e546 10841 if (spec->unsol_event)
7fb0d78f 10842 alc_inithook(codec);
9c7f852e
TI
10843}
10844
4953550a 10845static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10846{
10847 struct alc_spec *spec;
10848 int err, board_config;
10849
10850 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10851 if (spec == NULL)
10852 return -ENOMEM;
10853
10854 codec->spec = spec;
10855
da00c244
KY
10856 alc_auto_parse_customize_define(codec);
10857
4953550a
TI
10858 switch (codec->vendor_id) {
10859 case 0x10ec0882:
10860 case 0x10ec0885:
10861 break;
10862 default:
10863 /* ALC883 and variants */
10864 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10865 break;
10866 }
2c3bf9ab 10867
4953550a
TI
10868 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10869 alc882_models,
10870 alc882_cfg_tbl);
10871
10872 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10873 board_config = snd_hda_check_board_codec_sid_config(codec,
10874 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10875
10876 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 10877 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
10878 codec->chip_name);
10879 board_config = ALC882_AUTO;
9c7f852e
TI
10880 }
10881
7fa90e87
TI
10882 if (board_config == ALC882_AUTO)
10883 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
4953550a
TI
10884
10885 if (board_config == ALC882_AUTO) {
9c7f852e 10886 /* automatic parse from the BIOS config */
4953550a 10887 err = alc882_parse_auto_config(codec);
9c7f852e
TI
10888 if (err < 0) {
10889 alc_free(codec);
10890 return err;
f12ab1e0 10891 } else if (!err) {
9c7f852e
TI
10892 printk(KERN_INFO
10893 "hda_codec: Cannot set up configuration "
10894 "from BIOS. Using base mode...\n");
4953550a 10895 board_config = ALC882_3ST_DIG;
9c7f852e
TI
10896 }
10897 }
10898
dc1eae25 10899 if (has_cdefine_beep(codec)) {
8af2591d
TI
10900 err = snd_hda_attach_beep_device(codec, 0x1);
10901 if (err < 0) {
10902 alc_free(codec);
10903 return err;
10904 }
680cd536
KK
10905 }
10906
4953550a 10907 if (board_config != ALC882_AUTO)
e9c364c0 10908 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 10909
4953550a
TI
10910 spec->stream_analog_playback = &alc882_pcm_analog_playback;
10911 spec->stream_analog_capture = &alc882_pcm_analog_capture;
10912 /* FIXME: setup DAC5 */
10913 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
10914 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
10915
10916 spec->stream_digital_playback = &alc882_pcm_digital_playback;
10917 spec->stream_digital_capture = &alc882_pcm_digital_capture;
10918
4953550a 10919 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 10920 int i, j;
4953550a
TI
10921 spec->num_adc_nids = 0;
10922 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 10923 const struct hda_input_mux *imux = spec->input_mux;
4953550a 10924 hda_nid_t cap;
d11f74c6 10925 hda_nid_t items[16];
4953550a
TI
10926 hda_nid_t nid = alc882_adc_nids[i];
10927 unsigned int wcap = get_wcaps(codec, nid);
10928 /* get type */
a22d543a 10929 wcap = get_wcaps_type(wcap);
4953550a
TI
10930 if (wcap != AC_WID_AUD_IN)
10931 continue;
10932 spec->private_adc_nids[spec->num_adc_nids] = nid;
10933 err = snd_hda_get_connections(codec, nid, &cap, 1);
10934 if (err < 0)
10935 continue;
d11f74c6
TI
10936 err = snd_hda_get_connections(codec, cap, items,
10937 ARRAY_SIZE(items));
10938 if (err < 0)
10939 continue;
10940 for (j = 0; j < imux->num_items; j++)
10941 if (imux->items[j].index >= err)
10942 break;
10943 if (j < imux->num_items)
10944 continue;
4953550a
TI
10945 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
10946 spec->num_adc_nids++;
61b9b9b1 10947 }
4953550a
TI
10948 spec->adc_nids = spec->private_adc_nids;
10949 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
10950 }
10951
b59bdf3b 10952 set_capture_mixer(codec);
da00c244 10953
dc1eae25 10954 if (has_cdefine_beep(codec))
da00c244 10955 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 10956
7fa90e87
TI
10957 if (board_config == ALC882_AUTO)
10958 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
10959
2134ea4f
TI
10960 spec->vmaster_nid = 0x0c;
10961
9c7f852e 10962 codec->patch_ops = alc_patch_ops;
4953550a
TI
10963 if (board_config == ALC882_AUTO)
10964 spec->init_hook = alc882_auto_init;
cb53c626
TI
10965#ifdef CONFIG_SND_HDA_POWER_SAVE
10966 if (!spec->loopback.amplist)
4953550a 10967 spec->loopback.amplist = alc882_loopbacks;
cb53c626 10968#endif
9c7f852e
TI
10969
10970 return 0;
10971}
10972
4953550a 10973
9c7f852e
TI
10974/*
10975 * ALC262 support
10976 */
10977
10978#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
10979#define ALC262_DIGIN_NID ALC880_DIGIN_NID
10980
10981#define alc262_dac_nids alc260_dac_nids
10982#define alc262_adc_nids alc882_adc_nids
10983#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
10984#define alc262_capsrc_nids alc882_capsrc_nids
10985#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
10986
10987#define alc262_modes alc260_modes
10988#define alc262_capture_source alc882_capture_source
10989
4e555fe5
KY
10990static hda_nid_t alc262_dmic_adc_nids[1] = {
10991 /* ADC0 */
10992 0x09
10993};
10994
10995static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
10996
9c7f852e
TI
10997static struct snd_kcontrol_new alc262_base_mixer[] = {
10998 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10999 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11000 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11001 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11002 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11003 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11004 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11005 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 11006 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11007 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11008 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 11009 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11010 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11011 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11012 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11013 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11014 { } /* end */
11015};
11016
ce875f07
TI
11017/* update HP, line and mono-out pins according to the master switch */
11018static void alc262_hp_master_update(struct hda_codec *codec)
11019{
11020 struct alc_spec *spec = codec->spec;
11021 int val = spec->master_sw;
11022
11023 /* HP & line-out */
11024 snd_hda_codec_write_cache(codec, 0x1b, 0,
11025 AC_VERB_SET_PIN_WIDGET_CONTROL,
11026 val ? PIN_HP : 0);
11027 snd_hda_codec_write_cache(codec, 0x15, 0,
11028 AC_VERB_SET_PIN_WIDGET_CONTROL,
11029 val ? PIN_HP : 0);
11030 /* mono (speaker) depending on the HP jack sense */
11031 val = val && !spec->jack_present;
11032 snd_hda_codec_write_cache(codec, 0x16, 0,
11033 AC_VERB_SET_PIN_WIDGET_CONTROL,
11034 val ? PIN_OUT : 0);
11035}
11036
11037static void alc262_hp_bpc_automute(struct hda_codec *codec)
11038{
11039 struct alc_spec *spec = codec->spec;
864f92be
WF
11040
11041 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
11042 alc262_hp_master_update(codec);
11043}
11044
11045static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
11046{
11047 if ((res >> 26) != ALC880_HP_EVENT)
11048 return;
11049 alc262_hp_bpc_automute(codec);
11050}
11051
11052static void alc262_hp_wildwest_automute(struct hda_codec *codec)
11053{
11054 struct alc_spec *spec = codec->spec;
864f92be
WF
11055
11056 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
11057 alc262_hp_master_update(codec);
11058}
11059
11060static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
11061 unsigned int res)
11062{
11063 if ((res >> 26) != ALC880_HP_EVENT)
11064 return;
11065 alc262_hp_wildwest_automute(codec);
11066}
11067
b72519b5 11068#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
11069
11070static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
11071 struct snd_ctl_elem_value *ucontrol)
11072{
11073 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11074 struct alc_spec *spec = codec->spec;
11075 int val = !!*ucontrol->value.integer.value;
11076
11077 if (val == spec->master_sw)
11078 return 0;
11079 spec->master_sw = val;
11080 alc262_hp_master_update(codec);
11081 return 1;
11082}
11083
b72519b5
TI
11084#define ALC262_HP_MASTER_SWITCH \
11085 { \
11086 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11087 .name = "Master Playback Switch", \
11088 .info = snd_ctl_boolean_mono_info, \
11089 .get = alc262_hp_master_sw_get, \
11090 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11091 }, \
11092 { \
11093 .iface = NID_MAPPING, \
11094 .name = "Master Playback Switch", \
11095 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11096 }
11097
5b0cb1d8 11098
9c7f852e 11099static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11100 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11101 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11102 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11103 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11104 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11105 HDA_OUTPUT),
11106 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11107 HDA_OUTPUT),
9c7f852e
TI
11108 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11109 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 11110 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11111 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11112 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 11113 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11114 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11115 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11116 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11117 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11118 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11119 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11120 { } /* end */
11121};
11122
cd7509a4 11123static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11124 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11125 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11126 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11127 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11128 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11129 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11130 HDA_OUTPUT),
11131 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11132 HDA_OUTPUT),
cd7509a4
KY
11133 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11134 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 11135 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11136 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11137 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11138 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11139 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11140 { } /* end */
11141};
11142
11143static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11144 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11145 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 11146 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11147 { } /* end */
11148};
11149
66d2a9d6 11150/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11151static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11152{
11153 struct alc_spec *spec = codec->spec;
66d2a9d6 11154
a9fd4f3f 11155 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11156 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
11157}
11158
66d2a9d6 11159static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11160 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11161 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11162 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11163 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11164 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11165 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11166 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11167 { } /* end */
11168};
11169
11170static struct hda_verb alc262_hp_t5735_verbs[] = {
11171 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11172 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11173
11174 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11175 { }
11176};
11177
8c427226 11178static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11179 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11180 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11181 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11182 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11183 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11184 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11185 { } /* end */
11186};
11187
11188static struct hda_verb alc262_hp_rp5700_verbs[] = {
11189 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11190 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11191 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11192 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11193 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11194 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11195 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11196 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11197 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11198 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11199 {}
11200};
11201
11202static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11203 .num_items = 1,
11204 .items = {
11205 { "Line", 0x1 },
11206 },
11207};
11208
42171c17
TI
11209/* bind hp and internal speaker mute (with plug check) as master switch */
11210static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 11211{
42171c17
TI
11212 struct alc_spec *spec = codec->spec;
11213 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11214 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11215 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11216 unsigned int mute;
0724ea2a 11217
42171c17
TI
11218 /* HP */
11219 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11220 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11221 HDA_AMP_MUTE, mute);
11222 /* mute internal speaker per jack sense */
11223 if (spec->jack_present)
11224 mute = HDA_AMP_MUTE;
11225 if (line_nid)
11226 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11227 HDA_AMP_MUTE, mute);
11228 if (speaker_nid && speaker_nid != line_nid)
11229 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 11230 HDA_AMP_MUTE, mute);
42171c17
TI
11231}
11232
11233#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11234
11235static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11236 struct snd_ctl_elem_value *ucontrol)
11237{
11238 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11239 struct alc_spec *spec = codec->spec;
11240 int val = !!*ucontrol->value.integer.value;
11241
11242 if (val == spec->master_sw)
11243 return 0;
11244 spec->master_sw = val;
11245 alc262_hippo_master_update(codec);
11246 return 1;
11247}
11248
11249#define ALC262_HIPPO_MASTER_SWITCH \
11250 { \
11251 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11252 .name = "Master Playback Switch", \
11253 .info = snd_ctl_boolean_mono_info, \
11254 .get = alc262_hippo_master_sw_get, \
11255 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11256 }, \
11257 { \
11258 .iface = NID_MAPPING, \
11259 .name = "Master Playback Switch", \
11260 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11261 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11262 }
42171c17
TI
11263
11264static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11265 ALC262_HIPPO_MASTER_SWITCH,
11266 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11267 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11268 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11269 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11270 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11271 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11272 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11273 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11274 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11275 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11276 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11277 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11278 { } /* end */
11279};
11280
11281static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11282 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11283 ALC262_HIPPO_MASTER_SWITCH,
11284 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11285 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11286 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11287 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11288 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11289 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11290 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11291 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11292 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11293 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11294 { } /* end */
11295};
11296
11297/* mute/unmute internal speaker according to the hp jack and mute state */
11298static void alc262_hippo_automute(struct hda_codec *codec)
11299{
11300 struct alc_spec *spec = codec->spec;
11301 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 11302
864f92be 11303 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 11304 alc262_hippo_master_update(codec);
0724ea2a 11305}
5b31954e 11306
42171c17
TI
11307static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11308{
11309 if ((res >> 26) != ALC880_HP_EVENT)
11310 return;
11311 alc262_hippo_automute(codec);
11312}
11313
4f5d1706 11314static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11315{
11316 struct alc_spec *spec = codec->spec;
11317
11318 spec->autocfg.hp_pins[0] = 0x15;
11319 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11320}
11321
4f5d1706 11322static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11323{
11324 struct alc_spec *spec = codec->spec;
11325
11326 spec->autocfg.hp_pins[0] = 0x1b;
11327 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11328}
11329
11330
272a527c 11331static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11332 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11333 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11334 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11335 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11336 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11337 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11338 { } /* end */
11339};
11340
83c34218 11341static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11342 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11343 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11344 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11345 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11346 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11347 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11348 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11349 { } /* end */
11350};
272a527c 11351
ba340e82
TV
11352static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11353 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11354 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11355 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11356 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11357 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11358 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11359 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11360 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11361 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11362 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11363 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11364 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11365 { } /* end */
11366};
11367
11368static struct hda_verb alc262_tyan_verbs[] = {
11369 /* Headphone automute */
11370 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11371 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11372 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11373
11374 /* P11 AUX_IN, white 4-pin connector */
11375 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11376 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11377 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11378 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11379
11380 {}
11381};
11382
11383/* unsolicited event for HP jack sensing */
4f5d1706 11384static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11385{
a9fd4f3f 11386 struct alc_spec *spec = codec->spec;
ba340e82 11387
a9fd4f3f
TI
11388 spec->autocfg.hp_pins[0] = 0x1b;
11389 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
11390}
11391
ba340e82 11392
9c7f852e
TI
11393#define alc262_capture_mixer alc882_capture_mixer
11394#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11395
11396/*
11397 * generic initialization of ADC, input mixers and output mixers
11398 */
11399static struct hda_verb alc262_init_verbs[] = {
11400 /*
11401 * Unmute ADC0-2 and set the default input to mic-in
11402 */
11403 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11404 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11405 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11406 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11407 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11408 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11409
cb53c626 11410 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11411 * mixer widget
f12ab1e0
TI
11412 * Note: PASD motherboards uses the Line In 2 as the input for
11413 * front panel mic (mic 2)
9c7f852e
TI
11414 */
11415 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11416 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11417 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11418 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11419 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11420 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11421
11422 /*
df694daa
KY
11423 * Set up output mixers (0x0c - 0x0e)
11424 */
11425 /* set vol=0 to output mixers */
11426 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11427 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11428 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11429 /* set up input amps for analog loopback */
11430 /* Amp Indices: DAC = 0, mixer = 1 */
11431 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11432 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11433 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11434 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11435 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11436 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11437
11438 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11439 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11440 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11441 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11442 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11443 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11444
11445 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11446 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11447 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11448 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11449 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11450
df694daa
KY
11451 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11452 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11453
df694daa
KY
11454 /* FIXME: use matrix-type input source selection */
11455 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11456 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11457 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11458 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11459 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11460 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11461 /* Input mixer2 */
11462 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11463 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11464 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11465 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11466 /* Input mixer3 */
11467 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11468 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11469 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11470 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11471
11472 { }
11473};
1da177e4 11474
4e555fe5
KY
11475static struct hda_verb alc262_eapd_verbs[] = {
11476 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11477 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11478 { }
11479};
11480
ccc656ce
KY
11481static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11482 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11483 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11484 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11485
11486 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11487 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11488 {}
11489};
11490
272a527c
KY
11491static struct hda_verb alc262_sony_unsol_verbs[] = {
11492 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11493 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11494 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11495
11496 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11497 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11498 {}
272a527c
KY
11499};
11500
4e555fe5
KY
11501static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11502 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11503 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11504 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11505 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11506 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11507 { } /* end */
11508};
11509
11510static struct hda_verb alc262_toshiba_s06_verbs[] = {
11511 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11512 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11513 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11514 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11515 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11516 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11517 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11518 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11519 {}
11520};
11521
4f5d1706 11522static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11523{
a9fd4f3f
TI
11524 struct alc_spec *spec = codec->spec;
11525
11526 spec->autocfg.hp_pins[0] = 0x15;
11527 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11528 spec->ext_mic.pin = 0x18;
11529 spec->ext_mic.mux_idx = 0;
11530 spec->int_mic.pin = 0x12;
11531 spec->int_mic.mux_idx = 9;
11532 spec->auto_mic = 1;
4e555fe5
KY
11533}
11534
e8f9ae2a
PT
11535/*
11536 * nec model
11537 * 0x15 = headphone
11538 * 0x16 = internal speaker
11539 * 0x18 = external mic
11540 */
11541
11542static struct snd_kcontrol_new alc262_nec_mixer[] = {
11543 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11544 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11545
11546 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11547 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11548 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11549
11550 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11551 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11552 { } /* end */
11553};
11554
11555static struct hda_verb alc262_nec_verbs[] = {
11556 /* Unmute Speaker */
11557 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11558
11559 /* Headphone */
11560 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11561 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11562
11563 /* External mic to headphone */
11564 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11565 /* External mic to speaker */
11566 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11567 {}
11568};
11569
834be88d
TI
11570/*
11571 * fujitsu model
5d9fab2d
TV
11572 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11573 * 0x1b = port replicator headphone out
834be88d
TI
11574 */
11575
11576#define ALC_HP_EVENT 0x37
11577
11578static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11579 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11580 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11581 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11582 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11583 {}
11584};
11585
0e31daf7
J
11586static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11587 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11588 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11589 {}
11590};
11591
e2595322
DC
11592static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11593 /* Front Mic pin: input vref at 50% */
11594 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11595 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11596 {}
11597};
11598
834be88d 11599static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11600 .num_items = 3,
834be88d
TI
11601 .items = {
11602 { "Mic", 0x0 },
39d3ed38 11603 { "Int Mic", 0x1 },
834be88d
TI
11604 { "CD", 0x4 },
11605 },
11606};
11607
9c7f852e
TI
11608static struct hda_input_mux alc262_HP_capture_source = {
11609 .num_items = 5,
11610 .items = {
11611 { "Mic", 0x0 },
accbe498 11612 { "Front Mic", 0x1 },
9c7f852e
TI
11613 { "Line", 0x2 },
11614 { "CD", 0x4 },
11615 { "AUX IN", 0x6 },
11616 },
11617};
11618
accbe498 11619static struct hda_input_mux alc262_HP_D7000_capture_source = {
11620 .num_items = 4,
11621 .items = {
11622 { "Mic", 0x0 },
11623 { "Front Mic", 0x2 },
11624 { "Line", 0x1 },
11625 { "CD", 0x4 },
11626 },
11627};
11628
ebc7a406 11629/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11630static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11631{
11632 struct alc_spec *spec = codec->spec;
11633 unsigned int mute;
11634
f12ab1e0 11635 if (force || !spec->sense_updated) {
864f92be
WF
11636 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11637 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11638 spec->sense_updated = 1;
11639 }
ebc7a406
TI
11640 /* unmute internal speaker only if both HPs are unplugged and
11641 * master switch is on
11642 */
11643 if (spec->jack_present)
11644 mute = HDA_AMP_MUTE;
11645 else
834be88d 11646 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11647 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11648 HDA_AMP_MUTE, mute);
834be88d
TI
11649}
11650
11651/* unsolicited event for HP jack sensing */
11652static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11653 unsigned int res)
11654{
11655 if ((res >> 26) != ALC_HP_EVENT)
11656 return;
11657 alc262_fujitsu_automute(codec, 1);
11658}
11659
ebc7a406
TI
11660static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11661{
11662 alc262_fujitsu_automute(codec, 1);
11663}
11664
834be88d 11665/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11666static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11667 .ops = &snd_hda_bind_vol,
11668 .values = {
11669 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11670 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11671 0
11672 },
11673};
834be88d 11674
0e31daf7
J
11675/* mute/unmute internal speaker according to the hp jack and mute state */
11676static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11677{
11678 struct alc_spec *spec = codec->spec;
11679 unsigned int mute;
11680
11681 if (force || !spec->sense_updated) {
864f92be 11682 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11683 spec->sense_updated = 1;
11684 }
11685 if (spec->jack_present) {
11686 /* mute internal speaker */
11687 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11688 HDA_AMP_MUTE, HDA_AMP_MUTE);
11689 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11690 HDA_AMP_MUTE, HDA_AMP_MUTE);
11691 } else {
11692 /* unmute internal speaker if necessary */
11693 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11694 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11695 HDA_AMP_MUTE, mute);
11696 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11697 HDA_AMP_MUTE, mute);
11698 }
11699}
11700
11701/* unsolicited event for HP jack sensing */
11702static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11703 unsigned int res)
11704{
11705 if ((res >> 26) != ALC_HP_EVENT)
11706 return;
11707 alc262_lenovo_3000_automute(codec, 1);
11708}
11709
8de56b7d
TI
11710static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11711 int dir, int idx, long *valp)
11712{
11713 int i, change = 0;
11714
11715 for (i = 0; i < 2; i++, valp++)
11716 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11717 HDA_AMP_MUTE,
11718 *valp ? 0 : HDA_AMP_MUTE);
11719 return change;
11720}
11721
834be88d
TI
11722/* bind hp and internal speaker mute (with plug check) */
11723static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11724 struct snd_ctl_elem_value *ucontrol)
11725{
11726 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11727 long *valp = ucontrol->value.integer.value;
11728 int change;
11729
8de56b7d
TI
11730 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11731 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11732 if (change)
11733 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11734 return change;
11735}
11736
11737static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11738 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11739 {
11740 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11741 .name = "Master Playback Switch",
5e26dfd0 11742 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11743 .info = snd_hda_mixer_amp_switch_info,
11744 .get = snd_hda_mixer_amp_switch_get,
11745 .put = alc262_fujitsu_master_sw_put,
11746 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11747 },
5b0cb1d8
JK
11748 {
11749 .iface = NID_MAPPING,
11750 .name = "Master Playback Switch",
11751 .private_value = 0x1b,
11752 },
834be88d
TI
11753 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11754 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11755 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11756 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11757 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
11758 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11759 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11760 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11761 { } /* end */
11762};
11763
0e31daf7
J
11764/* bind hp and internal speaker mute (with plug check) */
11765static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11766 struct snd_ctl_elem_value *ucontrol)
11767{
11768 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11769 long *valp = ucontrol->value.integer.value;
11770 int change;
11771
8de56b7d 11772 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11773 if (change)
11774 alc262_lenovo_3000_automute(codec, 0);
11775 return change;
11776}
11777
11778static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11779 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11780 {
11781 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11782 .name = "Master Playback Switch",
5e26dfd0 11783 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11784 .info = snd_hda_mixer_amp_switch_info,
11785 .get = snd_hda_mixer_amp_switch_get,
11786 .put = alc262_lenovo_3000_master_sw_put,
11787 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11788 },
11789 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11790 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11791 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11792 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11793 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11794 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11795 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11796 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11797 { } /* end */
11798};
11799
9f99a638
HM
11800static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11801 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11802 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11803 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11804 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11805 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11806 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11807 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11808 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11809 { } /* end */
11810};
11811
304dcaac
TI
11812/* additional init verbs for Benq laptops */
11813static struct hda_verb alc262_EAPD_verbs[] = {
11814 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11815 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11816 {}
11817};
11818
83c34218
KY
11819static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11820 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11821 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11822
11823 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11824 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11825 {}
11826};
11827
f651b50b
TD
11828/* Samsung Q1 Ultra Vista model setup */
11829static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11830 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11831 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11832 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11833 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11834 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 11835 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
11836 { } /* end */
11837};
11838
11839static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11840 /* output mixer */
11841 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11842 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11843 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11844 /* speaker */
11845 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11846 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11847 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11848 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11849 /* HP */
f651b50b 11850 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11851 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11852 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11853 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11854 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11855 /* internal mic */
11856 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11857 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11858 /* ADC, choose mic */
11859 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11860 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11861 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11862 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11863 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11864 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11865 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11866 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11867 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11868 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
11869 {}
11870};
11871
f651b50b
TD
11872/* mute/unmute internal speaker according to the hp jack and mute state */
11873static void alc262_ultra_automute(struct hda_codec *codec)
11874{
11875 struct alc_spec *spec = codec->spec;
11876 unsigned int mute;
f651b50b 11877
bb9f76cd
TI
11878 mute = 0;
11879 /* auto-mute only when HP is used as HP */
11880 if (!spec->cur_mux[0]) {
864f92be 11881 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
11882 if (spec->jack_present)
11883 mute = HDA_AMP_MUTE;
f651b50b 11884 }
bb9f76cd
TI
11885 /* mute/unmute internal speaker */
11886 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11887 HDA_AMP_MUTE, mute);
11888 /* mute/unmute HP */
11889 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11890 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
11891}
11892
11893/* unsolicited event for HP jack sensing */
11894static void alc262_ultra_unsol_event(struct hda_codec *codec,
11895 unsigned int res)
11896{
11897 if ((res >> 26) != ALC880_HP_EVENT)
11898 return;
11899 alc262_ultra_automute(codec);
11900}
11901
bb9f76cd
TI
11902static struct hda_input_mux alc262_ultra_capture_source = {
11903 .num_items = 2,
11904 .items = {
11905 { "Mic", 0x1 },
11906 { "Headphone", 0x7 },
11907 },
11908};
11909
11910static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11911 struct snd_ctl_elem_value *ucontrol)
11912{
11913 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11914 struct alc_spec *spec = codec->spec;
11915 int ret;
11916
54cbc9ab 11917 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
11918 if (!ret)
11919 return 0;
11920 /* reprogram the HP pin as mic or HP according to the input source */
11921 snd_hda_codec_write_cache(codec, 0x15, 0,
11922 AC_VERB_SET_PIN_WIDGET_CONTROL,
11923 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11924 alc262_ultra_automute(codec); /* mute/unmute HP */
11925 return ret;
11926}
11927
11928static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11929 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11930 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11931 {
11932 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11933 .name = "Capture Source",
54cbc9ab
TI
11934 .info = alc_mux_enum_info,
11935 .get = alc_mux_enum_get,
bb9f76cd
TI
11936 .put = alc262_ultra_mux_enum_put,
11937 },
5b0cb1d8
JK
11938 {
11939 .iface = NID_MAPPING,
11940 .name = "Capture Source",
11941 .private_value = 0x15,
11942 },
bb9f76cd
TI
11943 { } /* end */
11944};
11945
c3fc1f50
TI
11946/* We use two mixers depending on the output pin; 0x16 is a mono output
11947 * and thus it's bound with a different mixer.
11948 * This function returns which mixer amp should be used.
11949 */
11950static int alc262_check_volbit(hda_nid_t nid)
11951{
11952 if (!nid)
11953 return 0;
11954 else if (nid == 0x16)
11955 return 2;
11956 else
11957 return 1;
11958}
11959
11960static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 11961 const char *pfx, int *vbits, int idx)
c3fc1f50 11962{
c3fc1f50
TI
11963 unsigned long val;
11964 int vbit;
11965
11966 vbit = alc262_check_volbit(nid);
11967 if (!vbit)
11968 return 0;
11969 if (*vbits & vbit) /* a volume control for this mixer already there */
11970 return 0;
11971 *vbits |= vbit;
c3fc1f50
TI
11972 if (vbit == 2)
11973 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11974 else
11975 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 11976 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
11977}
11978
11979static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 11980 const char *pfx, int idx)
c3fc1f50 11981{
c3fc1f50
TI
11982 unsigned long val;
11983
11984 if (!nid)
11985 return 0;
c3fc1f50
TI
11986 if (nid == 0x16)
11987 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11988 else
11989 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 11990 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
11991}
11992
df694daa 11993/* add playback controls from the parsed DAC table */
f12ab1e0
TI
11994static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11995 const struct auto_pin_cfg *cfg)
df694daa 11996{
c3fc1f50
TI
11997 const char *pfx;
11998 int vbits;
033688a5 11999 int i, err;
df694daa
KY
12000
12001 spec->multiout.num_dacs = 1; /* only use one dac */
12002 spec->multiout.dac_nids = spec->private_dac_nids;
12003 spec->multiout.dac_nids[0] = 2;
12004
c3fc1f50
TI
12005 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
12006 pfx = "Master";
12007 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
12008 pfx = "Speaker";
033688a5
TI
12009 else if (cfg->line_out_type == AUTO_PIN_HP_OUT)
12010 pfx = "Headphone";
c3fc1f50
TI
12011 else
12012 pfx = "Front";
033688a5
TI
12013 for (i = 0; i < 2; i++) {
12014 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12015 if (err < 0)
12016 return err;
12017 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12018 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12019 "Speaker", i);
12020 if (err < 0)
12021 return err;
12022 }
12023 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12024 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12025 "Headphone", i);
12026 if (err < 0)
12027 return err;
12028 }
12029 }
df694daa 12030
c3fc1f50
TI
12031 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12032 alc262_check_volbit(cfg->speaker_pins[0]) |
12033 alc262_check_volbit(cfg->hp_pins[0]);
12034 if (vbits == 1 || vbits == 2)
12035 pfx = "Master"; /* only one mixer is used */
c3fc1f50 12036 vbits = 0;
033688a5
TI
12037 for (i = 0; i < 2; i++) {
12038 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12039 &vbits, i);
12040 if (err < 0)
12041 return err;
12042 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12043 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12044 "Speaker", &vbits, i);
12045 if (err < 0)
12046 return err;
12047 }
12048 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12049 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12050 "Headphone", &vbits, i);
12051 if (err < 0)
12052 return err;
12053 }
12054 }
f12ab1e0 12055 return 0;
df694daa
KY
12056}
12057
05f5f477 12058#define alc262_auto_create_input_ctls \
eaa9b3a7 12059 alc882_auto_create_input_ctls
df694daa
KY
12060
12061/*
12062 * generic initialization of ADC, input mixers and output mixers
12063 */
12064static struct hda_verb alc262_volume_init_verbs[] = {
12065 /*
12066 * Unmute ADC0-2 and set the default input to mic-in
12067 */
12068 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12069 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12070 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12071 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12072 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12073 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12074
cb53c626 12075 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 12076 * mixer widget
f12ab1e0
TI
12077 * Note: PASD motherboards uses the Line In 2 as the input for
12078 * front panel mic (mic 2)
df694daa
KY
12079 */
12080 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12081 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12082 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12083 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12084 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12085 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
12086
12087 /*
12088 * Set up output mixers (0x0c - 0x0f)
12089 */
12090 /* set vol=0 to output mixers */
12091 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12092 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12093 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 12094
df694daa
KY
12095 /* set up input amps for analog loopback */
12096 /* Amp Indices: DAC = 0, mixer = 1 */
12097 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12098 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12099 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12100 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12101 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12102 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12103
12104 /* FIXME: use matrix-type input source selection */
12105 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12106 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12107 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12108 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12109 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12110 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12111 /* Input mixer2 */
12112 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12113 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12114 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12115 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12116 /* Input mixer3 */
12117 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12118 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12119 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12120 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12121
12122 { }
12123};
12124
9c7f852e
TI
12125static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12126 /*
12127 * Unmute ADC0-2 and set the default input to mic-in
12128 */
12129 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12130 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12131 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12132 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12133 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12134 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12135
cb53c626 12136 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12137 * mixer widget
f12ab1e0
TI
12138 * Note: PASD motherboards uses the Line In 2 as the input for
12139 * front panel mic (mic 2)
9c7f852e
TI
12140 */
12141 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12142 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12143 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12144 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12145 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12146 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12147 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12148 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12149
9c7f852e
TI
12150 /*
12151 * Set up output mixers (0x0c - 0x0e)
12152 */
12153 /* set vol=0 to output mixers */
12154 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12155 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12156 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12157
12158 /* set up input amps for analog loopback */
12159 /* Amp Indices: DAC = 0, mixer = 1 */
12160 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12161 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12162 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12163 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12164 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12165 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12166
ce875f07 12167 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12168 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12169 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12170
12171 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12172 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12173
12174 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12175 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12176
12177 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12178 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12179 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12180 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12181 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12182
0e4835c1 12183 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12184 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12185 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12186 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12187 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12188 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12189
12190
12191 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12192 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12193 /* Input mixer1: only unmute Mic */
9c7f852e 12194 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12195 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12196 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12197 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12198 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12199 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12200 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12201 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12202 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12203 /* Input mixer2 */
12204 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12205 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12206 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12207 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12208 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12209 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12210 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12211 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12212 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12213 /* Input mixer3 */
12214 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12215 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12216 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12217 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12218 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12219 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12220 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12221 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12222 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12223
ce875f07
TI
12224 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12225
9c7f852e
TI
12226 { }
12227};
12228
cd7509a4
KY
12229static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12230 /*
12231 * Unmute ADC0-2 and set the default input to mic-in
12232 */
12233 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12234 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12235 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12236 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12237 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12238 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12239
cb53c626 12240 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12241 * mixer widget
12242 * Note: PASD motherboards uses the Line In 2 as the input for front
12243 * panel mic (mic 2)
12244 */
12245 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12246 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12247 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12248 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12249 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12250 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12251 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12252 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12253 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12254 /*
12255 * Set up output mixers (0x0c - 0x0e)
12256 */
12257 /* set vol=0 to output mixers */
12258 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12259 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12260 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12261
12262 /* set up input amps for analog loopback */
12263 /* Amp Indices: DAC = 0, mixer = 1 */
12264 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12265 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12266 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12267 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12268 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12269 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12270
12271
12272 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12273 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12274 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12275 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12276 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12277 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12278 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12279
12280 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12281 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12282
12283 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12284 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12285
12286 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12287 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12288 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12289 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12290 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12291 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12292
12293 /* FIXME: use matrix-type input source selection */
12294 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12295 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12296 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12297 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12298 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12299 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12300 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12301 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12302 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12303 /* Input mixer2 */
12304 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12305 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12306 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12307 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12308 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12309 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12310 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12311 /* Input mixer3 */
12312 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12313 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12314 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12315 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12316 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12317 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12318 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12319
ce875f07
TI
12320 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12321
cd7509a4
KY
12322 { }
12323};
12324
9f99a638
HM
12325static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12326
12327 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12328 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12329 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12330
12331 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12332 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12333 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12334 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12335
12336 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12337 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12338 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12339 {}
12340};
12341
18675e42
TI
12342/*
12343 * Pin config fixes
12344 */
12345enum {
12346 PINFIX_FSC_H270,
12347};
12348
12349static const struct alc_fixup alc262_fixups[] = {
12350 [PINFIX_FSC_H270] = {
12351 .pins = (const struct alc_pincfg[]) {
12352 { 0x14, 0x99130110 }, /* speaker */
12353 { 0x15, 0x0221142f }, /* front HP */
12354 { 0x1b, 0x0121141f }, /* rear HP */
12355 { }
12356 }
12357 },
12358 [PINFIX_PB_M5210] = {
12359 .verbs = (const struct hda_verb[]) {
12360 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
12361 {}
12362 }
12363 },
12364};
12365
12366static struct snd_pci_quirk alc262_fixup_tbl[] = {
12367 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12368 {}
12369};
12370
9f99a638 12371
cb53c626
TI
12372#ifdef CONFIG_SND_HDA_POWER_SAVE
12373#define alc262_loopbacks alc880_loopbacks
12374#endif
12375
def319f9 12376/* pcm configuration: identical with ALC880 */
df694daa
KY
12377#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12378#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12379#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12380#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12381
12382/*
12383 * BIOS auto configuration
12384 */
12385static int alc262_parse_auto_config(struct hda_codec *codec)
12386{
12387 struct alc_spec *spec = codec->spec;
12388 int err;
12389 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12390
f12ab1e0
TI
12391 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12392 alc262_ignore);
12393 if (err < 0)
df694daa 12394 return err;
e64f14f4 12395 if (!spec->autocfg.line_outs) {
0852d7a6 12396 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12397 spec->multiout.max_channels = 2;
12398 spec->no_analog = 1;
12399 goto dig_only;
12400 }
df694daa 12401 return 0; /* can't find valid BIOS pin config */
e64f14f4 12402 }
f12ab1e0
TI
12403 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12404 if (err < 0)
12405 return err;
05f5f477 12406 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12407 if (err < 0)
df694daa
KY
12408 return err;
12409
12410 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12411
e64f14f4 12412 dig_only:
757899ac 12413 alc_auto_parse_digital(codec);
df694daa 12414
603c4019 12415 if (spec->kctls.list)
d88897ea 12416 add_mixer(spec, spec->kctls.list);
df694daa 12417
d88897ea 12418 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12419 spec->num_mux_defs = 1;
61b9b9b1 12420 spec->input_mux = &spec->private_imux[0];
df694daa 12421
776e184e
TI
12422 err = alc_auto_add_mic_boost(codec);
12423 if (err < 0)
12424 return err;
12425
6227cdce 12426 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12427
df694daa
KY
12428 return 1;
12429}
12430
12431#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12432#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12433#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12434#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12435
12436
12437/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12438static void alc262_auto_init(struct hda_codec *codec)
df694daa 12439{
f6c7e546 12440 struct alc_spec *spec = codec->spec;
df694daa
KY
12441 alc262_auto_init_multi_out(codec);
12442 alc262_auto_init_hp_out(codec);
12443 alc262_auto_init_analog_input(codec);
f511b01c 12444 alc262_auto_init_input_src(codec);
757899ac 12445 alc_auto_init_digital(codec);
f6c7e546 12446 if (spec->unsol_event)
7fb0d78f 12447 alc_inithook(codec);
df694daa
KY
12448}
12449
12450/*
12451 * configuration and preset
12452 */
f5fcc13c
TI
12453static const char *alc262_models[ALC262_MODEL_LAST] = {
12454 [ALC262_BASIC] = "basic",
12455 [ALC262_HIPPO] = "hippo",
12456 [ALC262_HIPPO_1] = "hippo_1",
12457 [ALC262_FUJITSU] = "fujitsu",
12458 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12459 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12460 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12461 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12462 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12463 [ALC262_BENQ_T31] = "benq-t31",
12464 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12465 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12466 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12467 [ALC262_ULTRA] = "ultra",
0e31daf7 12468 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12469 [ALC262_NEC] = "nec",
ba340e82 12470 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12471 [ALC262_AUTO] = "auto",
12472};
12473
12474static struct snd_pci_quirk alc262_cfg_tbl[] = {
12475 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12476 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12477 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12478 ALC262_HP_BPC),
12479 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12480 ALC262_HP_BPC),
53eff7e1
TI
12481 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12482 ALC262_HP_BPC),
cd7509a4 12483 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12484 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12485 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12486 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12487 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12488 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12489 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12490 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12491 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12492 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12493 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12494 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12495 ALC262_HP_TC_T5735),
8c427226 12496 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12497 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12498 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12499 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12500 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12501 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12502 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12503 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12504#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12505 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12506 ALC262_SONY_ASSAMD),
c5b5165c 12507#endif
36ca6e13 12508 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12509 ALC262_TOSHIBA_RX1),
80ffe869 12510 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12511 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12512 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12513 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12514 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12515 ALC262_ULTRA),
3e420e78 12516 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12517 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12518 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12519 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12520 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12521 {}
12522};
12523
12524static struct alc_config_preset alc262_presets[] = {
12525 [ALC262_BASIC] = {
12526 .mixers = { alc262_base_mixer },
12527 .init_verbs = { alc262_init_verbs },
12528 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12529 .dac_nids = alc262_dac_nids,
12530 .hp_nid = 0x03,
12531 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12532 .channel_mode = alc262_modes,
a3bcba38 12533 .input_mux = &alc262_capture_source,
df694daa 12534 },
ccc656ce 12535 [ALC262_HIPPO] = {
42171c17 12536 .mixers = { alc262_hippo_mixer },
6732bd0d 12537 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12538 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12539 .dac_nids = alc262_dac_nids,
12540 .hp_nid = 0x03,
12541 .dig_out_nid = ALC262_DIGOUT_NID,
12542 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12543 .channel_mode = alc262_modes,
12544 .input_mux = &alc262_capture_source,
12545 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12546 .setup = alc262_hippo_setup,
12547 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12548 },
12549 [ALC262_HIPPO_1] = {
12550 .mixers = { alc262_hippo1_mixer },
12551 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12552 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12553 .dac_nids = alc262_dac_nids,
12554 .hp_nid = 0x02,
12555 .dig_out_nid = ALC262_DIGOUT_NID,
12556 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12557 .channel_mode = alc262_modes,
12558 .input_mux = &alc262_capture_source,
42171c17 12559 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12560 .setup = alc262_hippo1_setup,
12561 .init_hook = alc262_hippo_automute,
ccc656ce 12562 },
834be88d
TI
12563 [ALC262_FUJITSU] = {
12564 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12565 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12566 alc262_fujitsu_unsol_verbs },
834be88d
TI
12567 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12568 .dac_nids = alc262_dac_nids,
12569 .hp_nid = 0x03,
12570 .dig_out_nid = ALC262_DIGOUT_NID,
12571 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12572 .channel_mode = alc262_modes,
12573 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12574 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12575 .init_hook = alc262_fujitsu_init_hook,
834be88d 12576 },
9c7f852e
TI
12577 [ALC262_HP_BPC] = {
12578 .mixers = { alc262_HP_BPC_mixer },
12579 .init_verbs = { alc262_HP_BPC_init_verbs },
12580 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12581 .dac_nids = alc262_dac_nids,
12582 .hp_nid = 0x03,
12583 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12584 .channel_mode = alc262_modes,
12585 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12586 .unsol_event = alc262_hp_bpc_unsol_event,
12587 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12588 },
cd7509a4
KY
12589 [ALC262_HP_BPC_D7000_WF] = {
12590 .mixers = { alc262_HP_BPC_WildWest_mixer },
12591 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12592 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12593 .dac_nids = alc262_dac_nids,
12594 .hp_nid = 0x03,
12595 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12596 .channel_mode = alc262_modes,
accbe498 12597 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12598 .unsol_event = alc262_hp_wildwest_unsol_event,
12599 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12600 },
cd7509a4
KY
12601 [ALC262_HP_BPC_D7000_WL] = {
12602 .mixers = { alc262_HP_BPC_WildWest_mixer,
12603 alc262_HP_BPC_WildWest_option_mixer },
12604 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12605 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12606 .dac_nids = alc262_dac_nids,
12607 .hp_nid = 0x03,
12608 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12609 .channel_mode = alc262_modes,
accbe498 12610 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12611 .unsol_event = alc262_hp_wildwest_unsol_event,
12612 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12613 },
66d2a9d6
KY
12614 [ALC262_HP_TC_T5735] = {
12615 .mixers = { alc262_hp_t5735_mixer },
12616 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12617 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12618 .dac_nids = alc262_dac_nids,
12619 .hp_nid = 0x03,
12620 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12621 .channel_mode = alc262_modes,
12622 .input_mux = &alc262_capture_source,
dc99be47 12623 .unsol_event = alc_sku_unsol_event,
4f5d1706 12624 .setup = alc262_hp_t5735_setup,
dc99be47 12625 .init_hook = alc_inithook,
8c427226
KY
12626 },
12627 [ALC262_HP_RP5700] = {
12628 .mixers = { alc262_hp_rp5700_mixer },
12629 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12630 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12631 .dac_nids = alc262_dac_nids,
12632 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12633 .channel_mode = alc262_modes,
12634 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12635 },
304dcaac
TI
12636 [ALC262_BENQ_ED8] = {
12637 .mixers = { alc262_base_mixer },
12638 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12639 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12640 .dac_nids = alc262_dac_nids,
12641 .hp_nid = 0x03,
12642 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12643 .channel_mode = alc262_modes,
12644 .input_mux = &alc262_capture_source,
f12ab1e0 12645 },
272a527c
KY
12646 [ALC262_SONY_ASSAMD] = {
12647 .mixers = { alc262_sony_mixer },
12648 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12649 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12650 .dac_nids = alc262_dac_nids,
12651 .hp_nid = 0x02,
12652 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12653 .channel_mode = alc262_modes,
12654 .input_mux = &alc262_capture_source,
12655 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12656 .setup = alc262_hippo_setup,
12657 .init_hook = alc262_hippo_automute,
83c34218
KY
12658 },
12659 [ALC262_BENQ_T31] = {
12660 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12661 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12662 alc_hp15_unsol_verbs },
83c34218
KY
12663 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12664 .dac_nids = alc262_dac_nids,
12665 .hp_nid = 0x03,
12666 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12667 .channel_mode = alc262_modes,
12668 .input_mux = &alc262_capture_source,
12669 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12670 .setup = alc262_hippo_setup,
12671 .init_hook = alc262_hippo_automute,
ea1fb29a 12672 },
f651b50b 12673 [ALC262_ULTRA] = {
f9e336f6
TI
12674 .mixers = { alc262_ultra_mixer },
12675 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12676 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12677 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12678 .dac_nids = alc262_dac_nids,
f651b50b
TD
12679 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12680 .channel_mode = alc262_modes,
12681 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12682 .adc_nids = alc262_adc_nids, /* ADC0 */
12683 .capsrc_nids = alc262_capsrc_nids,
12684 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12685 .unsol_event = alc262_ultra_unsol_event,
12686 .init_hook = alc262_ultra_automute,
12687 },
0e31daf7
J
12688 [ALC262_LENOVO_3000] = {
12689 .mixers = { alc262_lenovo_3000_mixer },
12690 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12691 alc262_lenovo_3000_unsol_verbs,
12692 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12693 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12694 .dac_nids = alc262_dac_nids,
12695 .hp_nid = 0x03,
12696 .dig_out_nid = ALC262_DIGOUT_NID,
12697 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12698 .channel_mode = alc262_modes,
12699 .input_mux = &alc262_fujitsu_capture_source,
12700 .unsol_event = alc262_lenovo_3000_unsol_event,
12701 },
e8f9ae2a
PT
12702 [ALC262_NEC] = {
12703 .mixers = { alc262_nec_mixer },
12704 .init_verbs = { alc262_nec_verbs },
12705 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12706 .dac_nids = alc262_dac_nids,
12707 .hp_nid = 0x03,
12708 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12709 .channel_mode = alc262_modes,
12710 .input_mux = &alc262_capture_source,
12711 },
4e555fe5
KY
12712 [ALC262_TOSHIBA_S06] = {
12713 .mixers = { alc262_toshiba_s06_mixer },
12714 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12715 alc262_eapd_verbs },
12716 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12717 .capsrc_nids = alc262_dmic_capsrc_nids,
12718 .dac_nids = alc262_dac_nids,
12719 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12720 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12721 .dig_out_nid = ALC262_DIGOUT_NID,
12722 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12723 .channel_mode = alc262_modes,
4f5d1706
TI
12724 .unsol_event = alc_sku_unsol_event,
12725 .setup = alc262_toshiba_s06_setup,
12726 .init_hook = alc_inithook,
4e555fe5 12727 },
9f99a638
HM
12728 [ALC262_TOSHIBA_RX1] = {
12729 .mixers = { alc262_toshiba_rx1_mixer },
12730 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12731 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12732 .dac_nids = alc262_dac_nids,
12733 .hp_nid = 0x03,
12734 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12735 .channel_mode = alc262_modes,
12736 .input_mux = &alc262_capture_source,
12737 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12738 .setup = alc262_hippo_setup,
12739 .init_hook = alc262_hippo_automute,
9f99a638 12740 },
ba340e82
TV
12741 [ALC262_TYAN] = {
12742 .mixers = { alc262_tyan_mixer },
12743 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12744 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12745 .dac_nids = alc262_dac_nids,
12746 .hp_nid = 0x02,
12747 .dig_out_nid = ALC262_DIGOUT_NID,
12748 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12749 .channel_mode = alc262_modes,
12750 .input_mux = &alc262_capture_source,
a9fd4f3f 12751 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12752 .setup = alc262_tyan_setup,
12753 .init_hook = alc_automute_amp,
ba340e82 12754 },
df694daa
KY
12755};
12756
12757static int patch_alc262(struct hda_codec *codec)
12758{
12759 struct alc_spec *spec;
12760 int board_config;
12761 int err;
12762
dc041e0b 12763 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12764 if (spec == NULL)
12765 return -ENOMEM;
12766
12767 codec->spec = spec;
12768#if 0
f12ab1e0
TI
12769 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12770 * under-run
12771 */
df694daa
KY
12772 {
12773 int tmp;
12774 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12775 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12776 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12777 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12778 }
12779#endif
da00c244 12780 alc_auto_parse_customize_define(codec);
df694daa 12781
2c3bf9ab
TI
12782 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12783
f5fcc13c
TI
12784 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12785 alc262_models,
12786 alc262_cfg_tbl);
cd7509a4 12787
f5fcc13c 12788 if (board_config < 0) {
9a11f1aa
TI
12789 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12790 codec->chip_name);
df694daa
KY
12791 board_config = ALC262_AUTO;
12792 }
12793
18675e42
TI
12794 if (board_config == ALC262_AUTO)
12795 alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 1);
12796
df694daa
KY
12797 if (board_config == ALC262_AUTO) {
12798 /* automatic parse from the BIOS config */
12799 err = alc262_parse_auto_config(codec);
12800 if (err < 0) {
12801 alc_free(codec);
12802 return err;
f12ab1e0 12803 } else if (!err) {
9c7f852e
TI
12804 printk(KERN_INFO
12805 "hda_codec: Cannot set up configuration "
12806 "from BIOS. Using base mode...\n");
df694daa
KY
12807 board_config = ALC262_BASIC;
12808 }
12809 }
12810
dc1eae25 12811 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12812 err = snd_hda_attach_beep_device(codec, 0x1);
12813 if (err < 0) {
12814 alc_free(codec);
12815 return err;
12816 }
680cd536
KK
12817 }
12818
df694daa 12819 if (board_config != ALC262_AUTO)
e9c364c0 12820 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12821
df694daa
KY
12822 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12823 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12824
df694daa
KY
12825 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12826 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12827
f12ab1e0 12828 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12829 int i;
12830 /* check whether the digital-mic has to be supported */
12831 for (i = 0; i < spec->input_mux->num_items; i++) {
12832 if (spec->input_mux->items[i].index >= 9)
12833 break;
12834 }
12835 if (i < spec->input_mux->num_items) {
12836 /* use only ADC0 */
12837 spec->adc_nids = alc262_dmic_adc_nids;
12838 spec->num_adc_nids = 1;
12839 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12840 } else {
8c927b4a
TI
12841 /* all analog inputs */
12842 /* check whether NID 0x07 is valid */
12843 unsigned int wcap = get_wcaps(codec, 0x07);
12844
12845 /* get type */
a22d543a 12846 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12847 if (wcap != AC_WID_AUD_IN) {
12848 spec->adc_nids = alc262_adc_nids_alt;
12849 spec->num_adc_nids =
12850 ARRAY_SIZE(alc262_adc_nids_alt);
12851 spec->capsrc_nids = alc262_capsrc_nids_alt;
12852 } else {
12853 spec->adc_nids = alc262_adc_nids;
12854 spec->num_adc_nids =
12855 ARRAY_SIZE(alc262_adc_nids);
12856 spec->capsrc_nids = alc262_capsrc_nids;
12857 }
df694daa
KY
12858 }
12859 }
e64f14f4 12860 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12861 set_capture_mixer(codec);
dc1eae25 12862 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 12863 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12864
18675e42
TI
12865 if (board_config == ALC262_AUTO)
12866 alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 0);
12867
2134ea4f
TI
12868 spec->vmaster_nid = 0x0c;
12869
df694daa
KY
12870 codec->patch_ops = alc_patch_ops;
12871 if (board_config == ALC262_AUTO)
ae6b813a 12872 spec->init_hook = alc262_auto_init;
cb53c626
TI
12873#ifdef CONFIG_SND_HDA_POWER_SAVE
12874 if (!spec->loopback.amplist)
12875 spec->loopback.amplist = alc262_loopbacks;
12876#endif
ea1fb29a 12877
df694daa
KY
12878 return 0;
12879}
12880
a361d84b
KY
12881/*
12882 * ALC268 channel source setting (2 channel)
12883 */
12884#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12885#define alc268_modes alc260_modes
ea1fb29a 12886
a361d84b
KY
12887static hda_nid_t alc268_dac_nids[2] = {
12888 /* front, hp */
12889 0x02, 0x03
12890};
12891
12892static hda_nid_t alc268_adc_nids[2] = {
12893 /* ADC0-1 */
12894 0x08, 0x07
12895};
12896
12897static hda_nid_t alc268_adc_nids_alt[1] = {
12898 /* ADC0 */
12899 0x08
12900};
12901
e1406348
TI
12902static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12903
a361d84b
KY
12904static struct snd_kcontrol_new alc268_base_mixer[] = {
12905 /* output mixer control */
12906 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12907 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12908 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12909 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
12910 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12911 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12912 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
12913 { }
12914};
12915
42171c17
TI
12916static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12917 /* output mixer control */
12918 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12919 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12920 ALC262_HIPPO_MASTER_SWITCH,
12921 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12922 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12923 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12924 { }
12925};
12926
aef9d318
TI
12927/* bind Beep switches of both NID 0x0f and 0x10 */
12928static struct hda_bind_ctls alc268_bind_beep_sw = {
12929 .ops = &snd_hda_bind_sw,
12930 .values = {
12931 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12932 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12933 0
12934 },
12935};
12936
12937static struct snd_kcontrol_new alc268_beep_mixer[] = {
12938 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12939 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12940 { }
12941};
12942
d1a991a6
KY
12943static struct hda_verb alc268_eapd_verbs[] = {
12944 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12945 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12946 { }
12947};
12948
d273809e 12949/* Toshiba specific */
d273809e
TI
12950static struct hda_verb alc268_toshiba_verbs[] = {
12951 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12952 { } /* end */
12953};
12954
12955/* Acer specific */
889c4395 12956/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
12957static struct hda_bind_ctls alc268_acer_bind_master_vol = {
12958 .ops = &snd_hda_bind_vol,
12959 .values = {
12960 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12961 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12962 0
12963 },
12964};
12965
889c4395
TI
12966/* mute/unmute internal speaker according to the hp jack and mute state */
12967static void alc268_acer_automute(struct hda_codec *codec, int force)
12968{
12969 struct alc_spec *spec = codec->spec;
12970 unsigned int mute;
12971
12972 if (force || !spec->sense_updated) {
864f92be 12973 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
12974 spec->sense_updated = 1;
12975 }
12976 if (spec->jack_present)
12977 mute = HDA_AMP_MUTE; /* mute internal speaker */
12978 else /* unmute internal speaker if necessary */
12979 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
12980 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12981 HDA_AMP_MUTE, mute);
12982}
12983
12984
12985/* bind hp and internal speaker mute (with plug check) */
12986static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
12987 struct snd_ctl_elem_value *ucontrol)
12988{
12989 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12990 long *valp = ucontrol->value.integer.value;
12991 int change;
12992
8de56b7d 12993 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
12994 if (change)
12995 alc268_acer_automute(codec, 0);
12996 return change;
12997}
d273809e 12998
8ef355da
KY
12999static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13000 /* output mixer control */
13001 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13002 {
13003 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13004 .name = "Master Playback Switch",
5e26dfd0 13005 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
13006 .info = snd_hda_mixer_amp_switch_info,
13007 .get = snd_hda_mixer_amp_switch_get,
13008 .put = alc268_acer_master_sw_put,
13009 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13010 },
13011 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13012 { }
13013};
13014
d273809e
TI
13015static struct snd_kcontrol_new alc268_acer_mixer[] = {
13016 /* output mixer control */
13017 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13018 {
13019 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13020 .name = "Master Playback Switch",
5e26dfd0 13021 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
13022 .info = snd_hda_mixer_amp_switch_info,
13023 .get = snd_hda_mixer_amp_switch_get,
13024 .put = alc268_acer_master_sw_put,
13025 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13026 },
33bf17ab
TI
13027 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13028 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13029 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
13030 { }
13031};
13032
c238b4f4
TI
13033static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13034 /* output mixer control */
13035 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13036 {
13037 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13038 .name = "Master Playback Switch",
5e26dfd0 13039 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
13040 .info = snd_hda_mixer_amp_switch_info,
13041 .get = snd_hda_mixer_amp_switch_get,
13042 .put = alc268_acer_master_sw_put,
13043 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13044 },
13045 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13046 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
13047 { }
13048};
13049
8ef355da
KY
13050static struct hda_verb alc268_acer_aspire_one_verbs[] = {
13051 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13052 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13053 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13054 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13055 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13056 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13057 { }
13058};
13059
d273809e 13060static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13061 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13062 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13063 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13064 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13065 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13066 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13067 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13068 { }
13069};
13070
13071/* unsolicited event for HP jack sensing */
42171c17 13072#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
13073#define alc268_toshiba_setup alc262_hippo_setup
13074#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
13075
13076static void alc268_acer_unsol_event(struct hda_codec *codec,
13077 unsigned int res)
13078{
889c4395 13079 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
13080 return;
13081 alc268_acer_automute(codec, 1);
13082}
13083
889c4395
TI
13084static void alc268_acer_init_hook(struct hda_codec *codec)
13085{
13086 alc268_acer_automute(codec, 1);
13087}
13088
8ef355da
KY
13089/* toggle speaker-output according to the hp-jack state */
13090static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
13091{
13092 unsigned int present;
13093 unsigned char bits;
13094
864f92be 13095 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13096 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 13097 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 13098 HDA_AMP_MUTE, bits);
8ef355da 13099 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 13100 HDA_AMP_MUTE, bits);
8ef355da
KY
13101}
13102
8ef355da
KY
13103static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
13104 unsigned int res)
13105{
4f5d1706
TI
13106 switch (res >> 26) {
13107 case ALC880_HP_EVENT:
8ef355da 13108 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
13109 break;
13110 case ALC880_MIC_EVENT:
13111 alc_mic_automute(codec);
13112 break;
13113 }
13114}
13115
13116static void alc268_acer_lc_setup(struct hda_codec *codec)
13117{
13118 struct alc_spec *spec = codec->spec;
13119 spec->ext_mic.pin = 0x18;
13120 spec->ext_mic.mux_idx = 0;
13121 spec->int_mic.pin = 0x12;
13122 spec->int_mic.mux_idx = 6;
13123 spec->auto_mic = 1;
8ef355da
KY
13124}
13125
13126static void alc268_acer_lc_init_hook(struct hda_codec *codec)
13127{
13128 alc268_aspire_one_speaker_automute(codec);
4f5d1706 13129 alc_mic_automute(codec);
8ef355da
KY
13130}
13131
3866f0b0
TI
13132static struct snd_kcontrol_new alc268_dell_mixer[] = {
13133 /* output mixer control */
13134 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13135 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13136 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13137 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13138 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13139 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13140 { }
13141};
13142
13143static struct hda_verb alc268_dell_verbs[] = {
13144 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13145 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13146 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 13147 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
13148 { }
13149};
13150
13151/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 13152static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 13153{
a9fd4f3f 13154 struct alc_spec *spec = codec->spec;
3866f0b0 13155
a9fd4f3f
TI
13156 spec->autocfg.hp_pins[0] = 0x15;
13157 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13158 spec->ext_mic.pin = 0x18;
13159 spec->ext_mic.mux_idx = 0;
13160 spec->int_mic.pin = 0x19;
13161 spec->int_mic.mux_idx = 1;
13162 spec->auto_mic = 1;
3866f0b0
TI
13163}
13164
eb5a6621
HRK
13165static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13166 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13167 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13168 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13169 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13170 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13171 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
13172 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13173 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13174 { }
13175};
13176
13177static struct hda_verb alc267_quanta_il1_verbs[] = {
13178 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13179 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13180 { }
13181};
13182
4f5d1706 13183static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 13184{
a9fd4f3f 13185 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
13186 spec->autocfg.hp_pins[0] = 0x15;
13187 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13188 spec->ext_mic.pin = 0x18;
13189 spec->ext_mic.mux_idx = 0;
13190 spec->int_mic.pin = 0x19;
13191 spec->int_mic.mux_idx = 1;
13192 spec->auto_mic = 1;
eb5a6621
HRK
13193}
13194
a361d84b
KY
13195/*
13196 * generic initialization of ADC, input mixers and output mixers
13197 */
13198static struct hda_verb alc268_base_init_verbs[] = {
13199 /* Unmute DAC0-1 and set vol = 0 */
13200 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 13201 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13202
13203 /*
13204 * Set up output mixers (0x0c - 0x0e)
13205 */
13206 /* set vol=0 to output mixers */
13207 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13208 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13209
13210 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13211 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13212
13213 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13214 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13215 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13216 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13217 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13218 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13219 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13220 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13221
13222 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13223 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13224 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13225 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13226 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13227
13228 /* set PCBEEP vol = 0, mute connections */
13229 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13230 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13231 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13232
a9b3aa8a 13233 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13234
a9b3aa8a
JZ
13235 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13236 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13237 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13238 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13239
a361d84b
KY
13240 { }
13241};
13242
13243/*
13244 * generic initialization of ADC, input mixers and output mixers
13245 */
13246static struct hda_verb alc268_volume_init_verbs[] = {
13247 /* set output DAC */
4cfb91c6
TI
13248 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13249 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13250
13251 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13252 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13253 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13254 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13255 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13256
a361d84b 13257 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13258 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13259 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13260
13261 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13262 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13263
aef9d318
TI
13264 /* set PCBEEP vol = 0, mute connections */
13265 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13266 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13267 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13268
13269 { }
13270};
13271
fdbc6626
TI
13272static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13273 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13274 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13275 { } /* end */
13276};
13277
a361d84b
KY
13278static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13279 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13280 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13281 _DEFINE_CAPSRC(1),
a361d84b
KY
13282 { } /* end */
13283};
13284
13285static struct snd_kcontrol_new alc268_capture_mixer[] = {
13286 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13287 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13288 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13289 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13290 _DEFINE_CAPSRC(2),
a361d84b
KY
13291 { } /* end */
13292};
13293
13294static struct hda_input_mux alc268_capture_source = {
13295 .num_items = 4,
13296 .items = {
13297 { "Mic", 0x0 },
13298 { "Front Mic", 0x1 },
13299 { "Line", 0x2 },
13300 { "CD", 0x3 },
13301 },
13302};
13303
0ccb541c 13304static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13305 .num_items = 3,
13306 .items = {
13307 { "Mic", 0x0 },
13308 { "Internal Mic", 0x1 },
13309 { "Line", 0x2 },
13310 },
13311};
13312
13313static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13314 .num_items = 3,
13315 .items = {
13316 { "Mic", 0x0 },
13317 { "Internal Mic", 0x6 },
13318 { "Line", 0x2 },
13319 },
13320};
13321
86c53bd2
JW
13322#ifdef CONFIG_SND_DEBUG
13323static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13324 /* Volume widgets */
13325 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13326 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13327 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13328 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13329 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13330 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13331 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13332 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13333 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13334 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13335 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13336 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13337 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13338 /* The below appears problematic on some hardwares */
13339 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13340 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13341 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13342 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13343 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13344
13345 /* Modes for retasking pin widgets */
13346 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13347 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13348 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13349 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13350
13351 /* Controls for GPIO pins, assuming they are configured as outputs */
13352 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13353 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13354 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13355 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13356
13357 /* Switches to allow the digital SPDIF output pin to be enabled.
13358 * The ALC268 does not have an SPDIF input.
13359 */
13360 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13361
13362 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13363 * this output to turn on an external amplifier.
13364 */
13365 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13366 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13367
13368 { } /* end */
13369};
13370#endif
13371
a361d84b
KY
13372/* create input playback/capture controls for the given pin */
13373static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13374 const char *ctlname, int idx)
13375{
3f3b7c1a 13376 hda_nid_t dac;
a361d84b
KY
13377 int err;
13378
3f3b7c1a
TI
13379 switch (nid) {
13380 case 0x14:
13381 case 0x16:
13382 dac = 0x02;
13383 break;
13384 case 0x15:
b08b1637
TI
13385 case 0x1a: /* ALC259/269 only */
13386 case 0x1b: /* ALC259/269 only */
531d8791 13387 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13388 dac = 0x03;
13389 break;
13390 default:
c7a9434d
TI
13391 snd_printd(KERN_WARNING "hda_codec: "
13392 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13393 return 0;
13394 }
13395 if (spec->multiout.dac_nids[0] != dac &&
13396 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13397 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13398 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13399 HDA_OUTPUT));
13400 if (err < 0)
13401 return err;
3f3b7c1a
TI
13402 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13403 }
13404
3f3b7c1a 13405 if (nid != 0x16)
0afe5f89 13406 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13407 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13408 else /* mono */
0afe5f89 13409 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13410 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13411 if (err < 0)
13412 return err;
13413 return 0;
13414}
13415
13416/* add playback controls from the parsed DAC table */
13417static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13418 const struct auto_pin_cfg *cfg)
13419{
13420 hda_nid_t nid;
13421 int err;
13422
a361d84b 13423 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13424
13425 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13426 if (nid) {
13427 const char *name;
13428 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13429 name = "Speaker";
13430 else
13431 name = "Front";
13432 err = alc268_new_analog_output(spec, nid, name, 0);
13433 if (err < 0)
13434 return err;
13435 }
a361d84b
KY
13436
13437 nid = cfg->speaker_pins[0];
13438 if (nid == 0x1d) {
0afe5f89 13439 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13440 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13441 if (err < 0)
13442 return err;
7bfb9c03 13443 } else if (nid) {
3f3b7c1a
TI
13444 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13445 if (err < 0)
13446 return err;
a361d84b
KY
13447 }
13448 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13449 if (nid) {
13450 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13451 if (err < 0)
13452 return err;
13453 }
a361d84b
KY
13454
13455 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13456 if (nid == 0x16) {
0afe5f89 13457 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13458 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13459 if (err < 0)
13460 return err;
13461 }
ea1fb29a 13462 return 0;
a361d84b
KY
13463}
13464
13465/* create playback/capture controls for input pins */
05f5f477 13466static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13467 const struct auto_pin_cfg *cfg)
13468{
05f5f477 13469 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13470}
13471
e9af4f36
TI
13472static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13473 hda_nid_t nid, int pin_type)
13474{
13475 int idx;
13476
13477 alc_set_pin_output(codec, nid, pin_type);
13478 if (nid == 0x14 || nid == 0x16)
13479 idx = 0;
13480 else
13481 idx = 1;
13482 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13483}
13484
13485static void alc268_auto_init_multi_out(struct hda_codec *codec)
13486{
13487 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13488 int i;
13489
13490 for (i = 0; i < spec->autocfg.line_outs; i++) {
13491 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13492 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13493 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13494 }
13495}
13496
13497static void alc268_auto_init_hp_out(struct hda_codec *codec)
13498{
13499 struct alc_spec *spec = codec->spec;
13500 hda_nid_t pin;
e1ca7b4e 13501 int i;
e9af4f36 13502
e1ca7b4e
TI
13503 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13504 pin = spec->autocfg.hp_pins[i];
e9af4f36 13505 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13506 }
13507 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13508 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13509 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13510 }
13511 if (spec->autocfg.mono_out_pin)
13512 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13513 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36
TI
13514}
13515
a361d84b
KY
13516static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13517{
13518 struct alc_spec *spec = codec->spec;
13519 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13520 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13521 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13522 unsigned int dac_vol1, dac_vol2;
13523
e9af4f36 13524 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13525 snd_hda_codec_write(codec, speaker_nid, 0,
13526 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13527 /* mute mixer inputs from 0x1d */
a361d84b
KY
13528 snd_hda_codec_write(codec, 0x0f, 0,
13529 AC_VERB_SET_AMP_GAIN_MUTE,
13530 AMP_IN_UNMUTE(1));
13531 snd_hda_codec_write(codec, 0x10, 0,
13532 AC_VERB_SET_AMP_GAIN_MUTE,
13533 AMP_IN_UNMUTE(1));
13534 } else {
e9af4f36 13535 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13536 snd_hda_codec_write(codec, 0x0f, 0,
13537 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13538 snd_hda_codec_write(codec, 0x10, 0,
13539 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13540 }
13541
13542 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13543 if (line_nid == 0x14)
a361d84b
KY
13544 dac_vol2 = AMP_OUT_ZERO;
13545 else if (line_nid == 0x15)
13546 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13547 if (hp_nid == 0x14)
a361d84b
KY
13548 dac_vol2 = AMP_OUT_ZERO;
13549 else if (hp_nid == 0x15)
13550 dac_vol1 = AMP_OUT_ZERO;
13551 if (line_nid != 0x16 || hp_nid != 0x16 ||
13552 spec->autocfg.line_out_pins[1] != 0x16 ||
13553 spec->autocfg.line_out_pins[2] != 0x16)
13554 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13555
13556 snd_hda_codec_write(codec, 0x02, 0,
13557 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13558 snd_hda_codec_write(codec, 0x03, 0,
13559 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13560}
13561
def319f9 13562/* pcm configuration: identical with ALC880 */
a361d84b
KY
13563#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13564#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13565#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13566#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13567
13568/*
13569 * BIOS auto configuration
13570 */
13571static int alc268_parse_auto_config(struct hda_codec *codec)
13572{
13573 struct alc_spec *spec = codec->spec;
13574 int err;
13575 static hda_nid_t alc268_ignore[] = { 0 };
13576
13577 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13578 alc268_ignore);
13579 if (err < 0)
13580 return err;
7e0e44d4
TI
13581 if (!spec->autocfg.line_outs) {
13582 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13583 spec->multiout.max_channels = 2;
13584 spec->no_analog = 1;
13585 goto dig_only;
13586 }
a361d84b 13587 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13588 }
a361d84b
KY
13589 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13590 if (err < 0)
13591 return err;
05f5f477 13592 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13593 if (err < 0)
13594 return err;
13595
13596 spec->multiout.max_channels = 2;
13597
7e0e44d4 13598 dig_only:
a361d84b 13599 /* digital only support output */
757899ac 13600 alc_auto_parse_digital(codec);
603c4019 13601 if (spec->kctls.list)
d88897ea 13602 add_mixer(spec, spec->kctls.list);
a361d84b 13603
892981ff 13604 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13605 add_mixer(spec, alc268_beep_mixer);
aef9d318 13606
d88897ea 13607 add_verb(spec, alc268_volume_init_verbs);
5908589f 13608 spec->num_mux_defs = 2;
61b9b9b1 13609 spec->input_mux = &spec->private_imux[0];
a361d84b 13610
776e184e
TI
13611 err = alc_auto_add_mic_boost(codec);
13612 if (err < 0)
13613 return err;
13614
6227cdce 13615 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13616
a361d84b
KY
13617 return 1;
13618}
13619
a361d84b
KY
13620#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13621
13622/* init callback for auto-configuration model -- overriding the default init */
13623static void alc268_auto_init(struct hda_codec *codec)
13624{
f6c7e546 13625 struct alc_spec *spec = codec->spec;
a361d84b
KY
13626 alc268_auto_init_multi_out(codec);
13627 alc268_auto_init_hp_out(codec);
13628 alc268_auto_init_mono_speaker_out(codec);
13629 alc268_auto_init_analog_input(codec);
757899ac 13630 alc_auto_init_digital(codec);
f6c7e546 13631 if (spec->unsol_event)
7fb0d78f 13632 alc_inithook(codec);
a361d84b
KY
13633}
13634
13635/*
13636 * configuration and preset
13637 */
13638static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13639 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13640 [ALC268_3ST] = "3stack",
983f8ae4 13641 [ALC268_TOSHIBA] = "toshiba",
d273809e 13642 [ALC268_ACER] = "acer",
c238b4f4 13643 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13644 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13645 [ALC268_DELL] = "dell",
f12462c5 13646 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13647#ifdef CONFIG_SND_DEBUG
13648 [ALC268_TEST] = "test",
13649#endif
a361d84b
KY
13650 [ALC268_AUTO] = "auto",
13651};
13652
13653static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13654 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13655 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13656 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13657 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13658 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13659 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13660 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13661 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13662 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13663 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13664 /* almost compatible with toshiba but with optional digital outs;
13665 * auto-probing seems working fine
13666 */
8871e5b9 13667 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13668 ALC268_AUTO),
a361d84b 13669 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13670 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13671 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13672 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13673 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13674 {}
13675};
13676
3abf2f36
TI
13677/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13678static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13679 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13680 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13681 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13682 ALC268_TOSHIBA),
13683 {}
13684};
13685
a361d84b 13686static struct alc_config_preset alc268_presets[] = {
eb5a6621 13687 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13688 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13689 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13690 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13691 alc267_quanta_il1_verbs },
13692 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13693 .dac_nids = alc268_dac_nids,
13694 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13695 .adc_nids = alc268_adc_nids_alt,
13696 .hp_nid = 0x03,
13697 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13698 .channel_mode = alc268_modes,
4f5d1706
TI
13699 .unsol_event = alc_sku_unsol_event,
13700 .setup = alc267_quanta_il1_setup,
13701 .init_hook = alc_inithook,
eb5a6621 13702 },
a361d84b 13703 [ALC268_3ST] = {
aef9d318
TI
13704 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13705 alc268_beep_mixer },
a361d84b
KY
13706 .init_verbs = { alc268_base_init_verbs },
13707 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13708 .dac_nids = alc268_dac_nids,
13709 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13710 .adc_nids = alc268_adc_nids_alt,
e1406348 13711 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13712 .hp_nid = 0x03,
13713 .dig_out_nid = ALC268_DIGOUT_NID,
13714 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13715 .channel_mode = alc268_modes,
13716 .input_mux = &alc268_capture_source,
13717 },
d1a991a6 13718 [ALC268_TOSHIBA] = {
42171c17 13719 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13720 alc268_beep_mixer },
d273809e
TI
13721 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13722 alc268_toshiba_verbs },
d1a991a6
KY
13723 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13724 .dac_nids = alc268_dac_nids,
13725 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13726 .adc_nids = alc268_adc_nids_alt,
e1406348 13727 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13728 .hp_nid = 0x03,
13729 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13730 .channel_mode = alc268_modes,
13731 .input_mux = &alc268_capture_source,
d273809e 13732 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13733 .setup = alc268_toshiba_setup,
13734 .init_hook = alc268_toshiba_automute,
d273809e
TI
13735 },
13736 [ALC268_ACER] = {
432fd133 13737 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13738 alc268_beep_mixer },
d273809e
TI
13739 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13740 alc268_acer_verbs },
13741 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13742 .dac_nids = alc268_dac_nids,
13743 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13744 .adc_nids = alc268_adc_nids_alt,
e1406348 13745 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13746 .hp_nid = 0x02,
13747 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13748 .channel_mode = alc268_modes,
0ccb541c 13749 .input_mux = &alc268_acer_capture_source,
d273809e 13750 .unsol_event = alc268_acer_unsol_event,
889c4395 13751 .init_hook = alc268_acer_init_hook,
d1a991a6 13752 },
c238b4f4
TI
13753 [ALC268_ACER_DMIC] = {
13754 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13755 alc268_beep_mixer },
13756 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13757 alc268_acer_verbs },
13758 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13759 .dac_nids = alc268_dac_nids,
13760 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13761 .adc_nids = alc268_adc_nids_alt,
13762 .capsrc_nids = alc268_capsrc_nids,
13763 .hp_nid = 0x02,
13764 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13765 .channel_mode = alc268_modes,
13766 .input_mux = &alc268_acer_dmic_capture_source,
13767 .unsol_event = alc268_acer_unsol_event,
13768 .init_hook = alc268_acer_init_hook,
13769 },
8ef355da
KY
13770 [ALC268_ACER_ASPIRE_ONE] = {
13771 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13772 alc268_beep_mixer,
fdbc6626 13773 alc268_capture_nosrc_mixer },
8ef355da
KY
13774 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13775 alc268_acer_aspire_one_verbs },
13776 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13777 .dac_nids = alc268_dac_nids,
13778 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13779 .adc_nids = alc268_adc_nids_alt,
13780 .capsrc_nids = alc268_capsrc_nids,
13781 .hp_nid = 0x03,
13782 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13783 .channel_mode = alc268_modes,
8ef355da 13784 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13785 .setup = alc268_acer_lc_setup,
8ef355da
KY
13786 .init_hook = alc268_acer_lc_init_hook,
13787 },
3866f0b0 13788 [ALC268_DELL] = {
fdbc6626
TI
13789 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13790 alc268_capture_nosrc_mixer },
3866f0b0
TI
13791 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13792 alc268_dell_verbs },
13793 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13794 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13795 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13796 .adc_nids = alc268_adc_nids_alt,
13797 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13798 .hp_nid = 0x02,
13799 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13800 .channel_mode = alc268_modes,
a9fd4f3f 13801 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13802 .setup = alc268_dell_setup,
13803 .init_hook = alc_inithook,
3866f0b0 13804 },
f12462c5 13805 [ALC268_ZEPTO] = {
aef9d318
TI
13806 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13807 alc268_beep_mixer },
f12462c5
MT
13808 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13809 alc268_toshiba_verbs },
13810 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13811 .dac_nids = alc268_dac_nids,
13812 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13813 .adc_nids = alc268_adc_nids_alt,
e1406348 13814 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13815 .hp_nid = 0x03,
13816 .dig_out_nid = ALC268_DIGOUT_NID,
13817 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13818 .channel_mode = alc268_modes,
13819 .input_mux = &alc268_capture_source,
4f5d1706
TI
13820 .setup = alc268_toshiba_setup,
13821 .init_hook = alc268_toshiba_automute,
f12462c5 13822 },
86c53bd2
JW
13823#ifdef CONFIG_SND_DEBUG
13824 [ALC268_TEST] = {
13825 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13826 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13827 alc268_volume_init_verbs },
13828 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13829 .dac_nids = alc268_dac_nids,
13830 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13831 .adc_nids = alc268_adc_nids_alt,
e1406348 13832 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13833 .hp_nid = 0x03,
13834 .dig_out_nid = ALC268_DIGOUT_NID,
13835 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13836 .channel_mode = alc268_modes,
13837 .input_mux = &alc268_capture_source,
13838 },
13839#endif
a361d84b
KY
13840};
13841
13842static int patch_alc268(struct hda_codec *codec)
13843{
13844 struct alc_spec *spec;
13845 int board_config;
22971e3a 13846 int i, has_beep, err;
a361d84b 13847
ef86f581 13848 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13849 if (spec == NULL)
13850 return -ENOMEM;
13851
13852 codec->spec = spec;
13853
13854 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13855 alc268_models,
13856 alc268_cfg_tbl);
13857
3abf2f36
TI
13858 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13859 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13860 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13861
a361d84b 13862 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13863 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13864 codec->chip_name);
a361d84b
KY
13865 board_config = ALC268_AUTO;
13866 }
13867
13868 if (board_config == ALC268_AUTO) {
13869 /* automatic parse from the BIOS config */
13870 err = alc268_parse_auto_config(codec);
13871 if (err < 0) {
13872 alc_free(codec);
13873 return err;
13874 } else if (!err) {
13875 printk(KERN_INFO
13876 "hda_codec: Cannot set up configuration "
13877 "from BIOS. Using base mode...\n");
13878 board_config = ALC268_3ST;
13879 }
13880 }
13881
13882 if (board_config != ALC268_AUTO)
e9c364c0 13883 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 13884
a361d84b
KY
13885 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13886 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 13887 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 13888
a361d84b
KY
13889 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13890
22971e3a
TI
13891 has_beep = 0;
13892 for (i = 0; i < spec->num_mixers; i++) {
13893 if (spec->mixers[i] == alc268_beep_mixer) {
13894 has_beep = 1;
13895 break;
13896 }
13897 }
13898
13899 if (has_beep) {
13900 err = snd_hda_attach_beep_device(codec, 0x1);
13901 if (err < 0) {
13902 alc_free(codec);
13903 return err;
13904 }
13905 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13906 /* override the amp caps for beep generator */
13907 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
13908 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13909 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13910 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13911 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 13912 }
aef9d318 13913
7e0e44d4 13914 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
13915 /* check whether NID 0x07 is valid */
13916 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 13917 int i;
3866f0b0 13918
defb5ab2 13919 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 13920 /* get type */
a22d543a 13921 wcap = get_wcaps_type(wcap);
fdbc6626
TI
13922 if (spec->auto_mic ||
13923 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
13924 spec->adc_nids = alc268_adc_nids_alt;
13925 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
13926 if (spec->auto_mic)
13927 fixup_automic_adc(codec);
fdbc6626
TI
13928 if (spec->auto_mic || spec->input_mux->num_items == 1)
13929 add_mixer(spec, alc268_capture_nosrc_mixer);
13930 else
13931 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
13932 } else {
13933 spec->adc_nids = alc268_adc_nids;
13934 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 13935 add_mixer(spec, alc268_capture_mixer);
a361d84b 13936 }
85860c06
TI
13937 /* set default input source */
13938 for (i = 0; i < spec->num_adc_nids; i++)
13939 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
13940 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
13941 i < spec->num_mux_defs ?
13942 spec->input_mux[i].items[0].index :
85860c06 13943 spec->input_mux->items[0].index);
a361d84b 13944 }
2134ea4f
TI
13945
13946 spec->vmaster_nid = 0x02;
13947
a361d84b
KY
13948 codec->patch_ops = alc_patch_ops;
13949 if (board_config == ALC268_AUTO)
13950 spec->init_hook = alc268_auto_init;
ea1fb29a 13951
a361d84b
KY
13952 return 0;
13953}
13954
f6a92248
KY
13955/*
13956 * ALC269 channel source setting (2 channel)
13957 */
13958#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13959
13960#define alc269_dac_nids alc260_dac_nids
13961
13962static hda_nid_t alc269_adc_nids[1] = {
13963 /* ADC1 */
f53281e6
KY
13964 0x08,
13965};
13966
e01bf509
TI
13967static hda_nid_t alc269_capsrc_nids[1] = {
13968 0x23,
13969};
13970
84898e87
KY
13971static hda_nid_t alc269vb_adc_nids[1] = {
13972 /* ADC1 */
13973 0x09,
13974};
13975
13976static hda_nid_t alc269vb_capsrc_nids[1] = {
13977 0x22,
13978};
13979
6694635d
TI
13980static hda_nid_t alc269_adc_candidates[] = {
13981 0x08, 0x09, 0x07,
13982};
e01bf509 13983
f6a92248
KY
13984#define alc269_modes alc260_modes
13985#define alc269_capture_source alc880_lg_lw_capture_source
13986
13987static struct snd_kcontrol_new alc269_base_mixer[] = {
13988 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13989 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13990 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13991 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13992 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13993 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13994 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13995 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13996 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13997 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13998 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13999 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14000 { } /* end */
14001};
14002
60db6b53
KY
14003static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14004 /* output mixer control */
14005 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14006 {
14007 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14008 .name = "Master Playback Switch",
5e26dfd0 14009 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
14010 .info = snd_hda_mixer_amp_switch_info,
14011 .get = snd_hda_mixer_amp_switch_get,
14012 .put = alc268_acer_master_sw_put,
14013 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14014 },
14015 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14016 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14017 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14018 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14019 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14020 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
60db6b53
KY
14021 { }
14022};
14023
64154835
TV
14024static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14025 /* output mixer control */
14026 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14027 {
14028 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14029 .name = "Master Playback Switch",
5e26dfd0 14030 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14031 .info = snd_hda_mixer_amp_switch_info,
14032 .get = snd_hda_mixer_amp_switch_get,
14033 .put = alc268_acer_master_sw_put,
14034 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14035 },
14036 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14037 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14038 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14039 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14040 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14041 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
14042 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14043 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
14044 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
64154835
TV
14045 { }
14046};
14047
84898e87 14048static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14049 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14050 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14051 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14052 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14053 { } /* end */
14054};
14055
84898e87
KY
14056static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14057 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14058 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14059 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14060 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14061 { } /* end */
14062};
14063
fe3eb0a7
KY
14064static struct snd_kcontrol_new alc269_asus_mixer[] = {
14065 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14066 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14067 { } /* end */
14068};
14069
f53281e6 14070/* capture mixer elements */
84898e87
KY
14071static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14072 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14073 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14074 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14075 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
14076 { } /* end */
14077};
14078
14079static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14080 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14081 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
26f5df26
TI
14082 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14083 { } /* end */
14084};
14085
84898e87
KY
14086static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14087 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14088 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14089 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14090 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
14091 { } /* end */
14092};
14093
14094static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14095 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14096 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14097 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14098 { } /* end */
14099};
14100
26f5df26 14101/* FSC amilo */
84898e87 14102#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14103
60db6b53
KY
14104static struct hda_verb alc269_quanta_fl1_verbs[] = {
14105 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14106 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14107 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14108 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14109 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14110 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14111 { }
14112};
f6a92248 14113
64154835
TV
14114static struct hda_verb alc269_lifebook_verbs[] = {
14115 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14116 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14117 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14118 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14119 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14120 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14121 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14122 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14123 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14124 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14125 { }
14126};
14127
60db6b53
KY
14128/* toggle speaker-output according to the hp-jack state */
14129static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14130{
14131 unsigned int present;
14132 unsigned char bits;
f6a92248 14133
864f92be 14134 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 14135 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 14136 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14137 HDA_AMP_MUTE, bits);
60db6b53 14138 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14139 HDA_AMP_MUTE, bits);
f6a92248 14140
60db6b53
KY
14141 snd_hda_codec_write(codec, 0x20, 0,
14142 AC_VERB_SET_COEF_INDEX, 0x0c);
14143 snd_hda_codec_write(codec, 0x20, 0,
14144 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 14145
60db6b53
KY
14146 snd_hda_codec_write(codec, 0x20, 0,
14147 AC_VERB_SET_COEF_INDEX, 0x0c);
14148 snd_hda_codec_write(codec, 0x20, 0,
14149 AC_VERB_SET_PROC_COEF, 0x480);
14150}
f6a92248 14151
64154835
TV
14152/* toggle speaker-output according to the hp-jacks state */
14153static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
14154{
14155 unsigned int present;
14156 unsigned char bits;
14157
14158 /* Check laptop headphone socket */
864f92be 14159 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
14160
14161 /* Check port replicator headphone socket */
864f92be 14162 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 14163
5dbd5ec6 14164 bits = present ? HDA_AMP_MUTE : 0;
64154835 14165 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14166 HDA_AMP_MUTE, bits);
64154835 14167 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14168 HDA_AMP_MUTE, bits);
64154835
TV
14169
14170 snd_hda_codec_write(codec, 0x20, 0,
14171 AC_VERB_SET_COEF_INDEX, 0x0c);
14172 snd_hda_codec_write(codec, 0x20, 0,
14173 AC_VERB_SET_PROC_COEF, 0x680);
14174
14175 snd_hda_codec_write(codec, 0x20, 0,
14176 AC_VERB_SET_COEF_INDEX, 0x0c);
14177 snd_hda_codec_write(codec, 0x20, 0,
14178 AC_VERB_SET_PROC_COEF, 0x480);
14179}
14180
64154835
TV
14181static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14182{
14183 unsigned int present_laptop;
14184 unsigned int present_dock;
14185
864f92be
WF
14186 present_laptop = snd_hda_jack_detect(codec, 0x18);
14187 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14188
14189 /* Laptop mic port overrides dock mic port, design decision */
14190 if (present_dock)
14191 snd_hda_codec_write(codec, 0x23, 0,
14192 AC_VERB_SET_CONNECT_SEL, 0x3);
14193 if (present_laptop)
14194 snd_hda_codec_write(codec, 0x23, 0,
14195 AC_VERB_SET_CONNECT_SEL, 0x0);
14196 if (!present_dock && !present_laptop)
14197 snd_hda_codec_write(codec, 0x23, 0,
14198 AC_VERB_SET_CONNECT_SEL, 0x1);
14199}
14200
60db6b53
KY
14201static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14202 unsigned int res)
14203{
4f5d1706
TI
14204 switch (res >> 26) {
14205 case ALC880_HP_EVENT:
60db6b53 14206 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14207 break;
14208 case ALC880_MIC_EVENT:
14209 alc_mic_automute(codec);
14210 break;
14211 }
60db6b53 14212}
f6a92248 14213
64154835
TV
14214static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14215 unsigned int res)
14216{
14217 if ((res >> 26) == ALC880_HP_EVENT)
14218 alc269_lifebook_speaker_automute(codec);
14219 if ((res >> 26) == ALC880_MIC_EVENT)
14220 alc269_lifebook_mic_autoswitch(codec);
14221}
14222
4f5d1706
TI
14223static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14224{
14225 struct alc_spec *spec = codec->spec;
20645d70
TI
14226 spec->autocfg.hp_pins[0] = 0x15;
14227 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14228 spec->ext_mic.pin = 0x18;
14229 spec->ext_mic.mux_idx = 0;
14230 spec->int_mic.pin = 0x19;
14231 spec->int_mic.mux_idx = 1;
14232 spec->auto_mic = 1;
14233}
14234
60db6b53
KY
14235static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14236{
14237 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14238 alc_mic_automute(codec);
60db6b53 14239}
f6a92248 14240
64154835
TV
14241static void alc269_lifebook_init_hook(struct hda_codec *codec)
14242{
14243 alc269_lifebook_speaker_automute(codec);
14244 alc269_lifebook_mic_autoswitch(codec);
14245}
14246
84898e87 14247static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14248 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14249 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14250 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14251 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14252 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14253 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14254 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14255 {}
14256};
14257
84898e87 14258static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14259 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14260 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14261 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14262 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14263 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14264 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14265 {}
14266};
14267
84898e87
KY
14268static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14269 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14270 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14271 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14272 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14273 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14274 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14275 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14276 {}
14277};
14278
14279static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14280 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14281 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14282 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14283 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14284 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14285 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14286 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14287 {}
14288};
14289
fe3eb0a7
KY
14290static struct hda_verb alc271_acer_dmic_verbs[] = {
14291 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14292 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14293 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14294 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14295 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14296 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14297 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14298 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14299 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14300 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14301 { }
14302};
14303
f53281e6
KY
14304/* toggle speaker-output according to the hp-jack state */
14305static void alc269_speaker_automute(struct hda_codec *codec)
14306{
ebb83eeb
KY
14307 struct alc_spec *spec = codec->spec;
14308 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 14309 unsigned int present;
60db6b53 14310 unsigned char bits;
f53281e6 14311
ebb83eeb 14312 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 14313 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 14314 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14315 HDA_AMP_MUTE, bits);
f53281e6 14316 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14317 HDA_AMP_MUTE, bits);
f53281e6
KY
14318}
14319
f53281e6 14320/* unsolicited event for HP jack sensing */
84898e87 14321static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 14322 unsigned int res)
f53281e6 14323{
4f5d1706
TI
14324 switch (res >> 26) {
14325 case ALC880_HP_EVENT:
f53281e6 14326 alc269_speaker_automute(codec);
4f5d1706
TI
14327 break;
14328 case ALC880_MIC_EVENT:
14329 alc_mic_automute(codec);
14330 break;
14331 }
f53281e6
KY
14332}
14333
226b1ec8 14334static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14335{
4f5d1706 14336 struct alc_spec *spec = codec->spec;
20645d70
TI
14337 spec->autocfg.hp_pins[0] = 0x15;
14338 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14339 spec->ext_mic.pin = 0x18;
14340 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14341 spec->int_mic.pin = 0x19;
14342 spec->int_mic.mux_idx = 1;
4f5d1706 14343 spec->auto_mic = 1;
f53281e6
KY
14344}
14345
226b1ec8 14346static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14347{
14348 struct alc_spec *spec = codec->spec;
20645d70
TI
14349 spec->autocfg.hp_pins[0] = 0x15;
14350 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
14351 spec->ext_mic.pin = 0x18;
14352 spec->ext_mic.mux_idx = 0;
14353 spec->int_mic.pin = 0x12;
226b1ec8 14354 spec->int_mic.mux_idx = 5;
84898e87
KY
14355 spec->auto_mic = 1;
14356}
14357
226b1ec8 14358static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14359{
4f5d1706 14360 struct alc_spec *spec = codec->spec;
226b1ec8 14361 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14362 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14363 spec->ext_mic.pin = 0x18;
14364 spec->ext_mic.mux_idx = 0;
14365 spec->int_mic.pin = 0x19;
14366 spec->int_mic.mux_idx = 1;
14367 spec->auto_mic = 1;
f53281e6
KY
14368}
14369
226b1ec8
KY
14370static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14371{
14372 struct alc_spec *spec = codec->spec;
14373 spec->autocfg.hp_pins[0] = 0x21;
14374 spec->autocfg.speaker_pins[0] = 0x14;
14375 spec->ext_mic.pin = 0x18;
14376 spec->ext_mic.mux_idx = 0;
14377 spec->int_mic.pin = 0x12;
14378 spec->int_mic.mux_idx = 6;
14379 spec->auto_mic = 1;
14380}
14381
84898e87 14382static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
14383{
14384 alc269_speaker_automute(codec);
4f5d1706 14385 alc_mic_automute(codec);
f53281e6
KY
14386}
14387
60db6b53
KY
14388/*
14389 * generic initialization of ADC, input mixers and output mixers
14390 */
14391static struct hda_verb alc269_init_verbs[] = {
14392 /*
14393 * Unmute ADC0 and set the default input to mic-in
14394 */
84898e87 14395 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14396
14397 /*
84898e87 14398 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14399 */
14400 /* set vol=0 to output mixers */
14401 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14402 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14403
14404 /* set up input amps for analog loopback */
14405 /* Amp Indices: DAC = 0, mixer = 1 */
14406 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14407 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14408 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14409 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14410 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14411 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14412
14413 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14414 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14415 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14416 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14417 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14418 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14419 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14420
14421 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14422 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14423
84898e87
KY
14424 /* FIXME: use Mux-type input source selection */
14425 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14426 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14427 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14428
84898e87
KY
14429 /* set EAPD */
14430 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14431 { }
14432};
14433
14434static struct hda_verb alc269vb_init_verbs[] = {
14435 /*
14436 * Unmute ADC0 and set the default input to mic-in
14437 */
14438 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14439
14440 /*
14441 * Set up output mixers (0x02 - 0x03)
14442 */
14443 /* set vol=0 to output mixers */
14444 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14445 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14446
14447 /* set up input amps for analog loopback */
14448 /* Amp Indices: DAC = 0, mixer = 1 */
14449 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14450 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14451 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14452 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14453 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14454 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14455
14456 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14457 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14458 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14459 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14460 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14461 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14462 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14463
14464 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14465 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14466
14467 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14468 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14469 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14470 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14471
14472 /* set EAPD */
14473 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14474 { }
14475};
14476
9d0b71b1
TI
14477#define alc269_auto_create_multi_out_ctls \
14478 alc268_auto_create_multi_out_ctls
05f5f477
TI
14479#define alc269_auto_create_input_ctls \
14480 alc268_auto_create_input_ctls
f6a92248
KY
14481
14482#ifdef CONFIG_SND_HDA_POWER_SAVE
14483#define alc269_loopbacks alc880_loopbacks
14484#endif
14485
def319f9 14486/* pcm configuration: identical with ALC880 */
f6a92248
KY
14487#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14488#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14489#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14490#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14491
f03d3115
TI
14492static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14493 .substreams = 1,
14494 .channels_min = 2,
14495 .channels_max = 8,
14496 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14497 /* NID is set in alc_build_pcms */
14498 .ops = {
14499 .open = alc880_playback_pcm_open,
14500 .prepare = alc880_playback_pcm_prepare,
14501 .cleanup = alc880_playback_pcm_cleanup
14502 },
14503};
14504
14505static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14506 .substreams = 1,
14507 .channels_min = 2,
14508 .channels_max = 2,
14509 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14510 /* NID is set in alc_build_pcms */
14511};
14512
ad35879a
TI
14513#ifdef CONFIG_SND_HDA_POWER_SAVE
14514static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14515{
14516 switch (codec->subsystem_id) {
14517 case 0x103c1586:
14518 return 1;
14519 }
14520 return 0;
14521}
14522
14523static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14524{
14525 /* update mute-LED according to the speaker mute state */
14526 if (nid == 0x01 || nid == 0x14) {
14527 int pinval;
14528 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14529 HDA_AMP_MUTE)
14530 pinval = 0x24;
14531 else
14532 pinval = 0x20;
14533 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14534 snd_hda_codec_update_cache(codec, 0x19, 0,
14535 AC_VERB_SET_PIN_WIDGET_CONTROL,
14536 pinval);
ad35879a
TI
14537 }
14538 return alc_check_power_status(codec, nid);
14539}
14540#endif /* CONFIG_SND_HDA_POWER_SAVE */
14541
840b64c0
TI
14542static int alc275_setup_dual_adc(struct hda_codec *codec)
14543{
14544 struct alc_spec *spec = codec->spec;
14545
14546 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14547 return 0;
14548 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14549 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14550 if (spec->ext_mic.pin <= 0x12) {
14551 spec->private_adc_nids[0] = 0x08;
14552 spec->private_adc_nids[1] = 0x11;
14553 spec->private_capsrc_nids[0] = 0x23;
14554 spec->private_capsrc_nids[1] = 0x22;
14555 } else {
14556 spec->private_adc_nids[0] = 0x11;
14557 spec->private_adc_nids[1] = 0x08;
14558 spec->private_capsrc_nids[0] = 0x22;
14559 spec->private_capsrc_nids[1] = 0x23;
14560 }
14561 spec->adc_nids = spec->private_adc_nids;
14562 spec->capsrc_nids = spec->private_capsrc_nids;
14563 spec->num_adc_nids = 2;
14564 spec->dual_adc_switch = 1;
14565 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14566 spec->adc_nids[0], spec->adc_nids[1]);
14567 return 1;
14568 }
14569 return 0;
14570}
14571
d433a678
TI
14572/* different alc269-variants */
14573enum {
14574 ALC269_TYPE_NORMAL,
14575 ALC269_TYPE_ALC259,
14576 ALC269_TYPE_ALC271X,
14577};
14578
f6a92248
KY
14579/*
14580 * BIOS auto configuration
14581 */
14582static int alc269_parse_auto_config(struct hda_codec *codec)
14583{
14584 struct alc_spec *spec = codec->spec;
cfb9fb55 14585 int err;
f6a92248
KY
14586 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14587
14588 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14589 alc269_ignore);
14590 if (err < 0)
14591 return err;
14592
14593 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14594 if (err < 0)
14595 return err;
f3550d1b
TI
14596 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14597 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14598 else
14599 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14600 0x22, 0);
f6a92248
KY
14601 if (err < 0)
14602 return err;
14603
14604 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14605
757899ac 14606 alc_auto_parse_digital(codec);
f6a92248 14607
603c4019 14608 if (spec->kctls.list)
d88897ea 14609 add_mixer(spec, spec->kctls.list);
f6a92248 14610
d433a678 14611 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
84898e87 14612 add_verb(spec, alc269vb_init_verbs);
6227cdce 14613 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14614 } else {
14615 add_verb(spec, alc269_init_verbs);
6227cdce 14616 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14617 }
14618
f6a92248 14619 spec->num_mux_defs = 1;
61b9b9b1 14620 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14621
14622 if (!alc275_setup_dual_adc(codec))
14623 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14624 sizeof(alc269_adc_candidates));
6694635d 14625
e01bf509 14626 /* set default input source */
840b64c0 14627 if (!spec->dual_adc_switch)
748cce43
TI
14628 select_or_unmute_capsrc(codec, spec->capsrc_nids[0],
14629 spec->input_mux->items[0].index);
f6a92248
KY
14630
14631 err = alc_auto_add_mic_boost(codec);
14632 if (err < 0)
14633 return err;
14634
7e0e44d4 14635 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14636 set_capture_mixer(codec);
f53281e6 14637
f6a92248
KY
14638 return 1;
14639}
14640
e9af4f36
TI
14641#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14642#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14643#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14644
14645
14646/* init callback for auto-configuration model -- overriding the default init */
14647static void alc269_auto_init(struct hda_codec *codec)
14648{
f6c7e546 14649 struct alc_spec *spec = codec->spec;
f6a92248
KY
14650 alc269_auto_init_multi_out(codec);
14651 alc269_auto_init_hp_out(codec);
14652 alc269_auto_init_analog_input(codec);
757899ac 14653 alc_auto_init_digital(codec);
9ad0e496 14654 alc_init_jacks(codec);
f6c7e546 14655 if (spec->unsol_event)
7fb0d78f 14656 alc_inithook(codec);
f6a92248
KY
14657}
14658
977ddd6b
KY
14659#ifdef CONFIG_SND_HDA_POWER_SAVE
14660static int alc269_suspend(struct hda_codec *codec, pm_message_t state)
14661{
14662 struct alc_spec *spec = codec->spec;
14663 int val;
14664
14665 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14666 val = alc_read_coef_idx(codec, 0x04);
14667 /* Power down output pin */
14668 alc_write_coef_idx(codec, 0x04, val & ~(1<<11));
14669 }
14670
14671 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14672 val = alc_read_coef_idx(codec, 0x04);
14673 /* Power down output pin */
14674 alc_write_coef_idx(codec, 0x04, val & ~(1<<11));
14675 msleep(150);
14676 }
14677
14678 alc_shutup(codec);
14679 if (spec && spec->power_hook)
14680 spec->power_hook(codec);
14681 return 0;
14682}
14683#endif
14684#ifdef SND_HDA_NEEDS_RESUME
14685static int alc269_resume(struct hda_codec *codec)
14686{
14687 int val;
14688
14689 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14690 val = alc_read_coef_idx(codec, 0x04);
14691 /* Power down output pin */
14692 alc_write_coef_idx(codec, 0x04, val & ~(1<<11));
14693 msleep(150);
14694 }
14695
14696 codec->patch_ops.init(codec);
14697
14698 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14699 val = alc_read_coef_idx(codec, 0x04);
14700 /* Power up output pin */
14701 alc_write_coef_idx(codec, 0x04, val | (1<<11));
14702 msleep(200);
14703 }
14704
14705 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14706 val = alc_read_coef_idx(codec, 0x04);
14707 /* Power up output pin */
14708 alc_write_coef_idx(codec, 0x04, val | (1<<11));
14709 }
14710
14711 snd_hda_codec_resume_amp(codec);
14712 snd_hda_codec_resume_cache(codec);
14713#ifdef CONFIG_SND_HDA_POWER_SAVE
14714 if (codec->patch_ops.check_power_status)
14715 codec->patch_ops.check_power_status(codec, 0x01);
14716#endif
14717 return 0;
14718}
14719#endif
14720
ff818c24
TI
14721enum {
14722 ALC269_FIXUP_SONY_VAIO,
14723};
14724
ff818c24
TI
14725static const struct alc_fixup alc269_fixups[] = {
14726 [ALC269_FIXUP_SONY_VAIO] = {
73413b12
TI
14727 .verbs = (const struct hda_verb[]) {
14728 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14729 {}
14730 }
ff818c24
TI
14731 },
14732};
14733
14734static struct snd_pci_quirk alc269_fixup_tbl[] = {
14735 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
dbbcbc07 14736 SND_PCI_QUIRK(0x104d, 0x9077, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
ff818c24
TI
14737 {}
14738};
14739
14740
f6a92248
KY
14741/*
14742 * configuration and preset
14743 */
14744static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14745 [ALC269_BASIC] = "basic",
2922c9af 14746 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14747 [ALC269_AMIC] = "laptop-amic",
14748 [ALC269_DMIC] = "laptop-dmic",
64154835 14749 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14750 [ALC269_LIFEBOOK] = "lifebook",
14751 [ALC269_AUTO] = "auto",
f6a92248
KY
14752};
14753
14754static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14755 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14756 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14757 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14758 ALC269_AMIC),
14759 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14760 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14761 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14762 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14763 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14764 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14765 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14766 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14767 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14768 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14769 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14770 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14771 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14772 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14773 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14774 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14775 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14776 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14777 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14778 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14779 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14780 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14781 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14782 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14783 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14784 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14785 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14786 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14787 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14788 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14789 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14790 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14791 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14792 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14793 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14794 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14795 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14796 ALC269_DMIC),
60db6b53 14797 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14798 ALC269_DMIC),
14799 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14800 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14801 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14802 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14803 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14804 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14805 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14806 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14807 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14808 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14809 {}
14810};
14811
14812static struct alc_config_preset alc269_presets[] = {
14813 [ALC269_BASIC] = {
f9e336f6 14814 .mixers = { alc269_base_mixer },
f6a92248
KY
14815 .init_verbs = { alc269_init_verbs },
14816 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14817 .dac_nids = alc269_dac_nids,
14818 .hp_nid = 0x03,
14819 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14820 .channel_mode = alc269_modes,
14821 .input_mux = &alc269_capture_source,
14822 },
60db6b53
KY
14823 [ALC269_QUANTA_FL1] = {
14824 .mixers = { alc269_quanta_fl1_mixer },
14825 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14826 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14827 .dac_nids = alc269_dac_nids,
14828 .hp_nid = 0x03,
14829 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14830 .channel_mode = alc269_modes,
14831 .input_mux = &alc269_capture_source,
14832 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 14833 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
14834 .init_hook = alc269_quanta_fl1_init_hook,
14835 },
84898e87
KY
14836 [ALC269_AMIC] = {
14837 .mixers = { alc269_laptop_mixer },
14838 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 14839 .init_verbs = { alc269_init_verbs,
84898e87 14840 alc269_laptop_amic_init_verbs },
f53281e6
KY
14841 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14842 .dac_nids = alc269_dac_nids,
14843 .hp_nid = 0x03,
14844 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14845 .channel_mode = alc269_modes,
84898e87
KY
14846 .unsol_event = alc269_laptop_unsol_event,
14847 .setup = alc269_laptop_amic_setup,
14848 .init_hook = alc269_laptop_inithook,
f53281e6 14849 },
84898e87
KY
14850 [ALC269_DMIC] = {
14851 .mixers = { alc269_laptop_mixer },
14852 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 14853 .init_verbs = { alc269_init_verbs,
84898e87
KY
14854 alc269_laptop_dmic_init_verbs },
14855 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14856 .dac_nids = alc269_dac_nids,
14857 .hp_nid = 0x03,
14858 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14859 .channel_mode = alc269_modes,
14860 .unsol_event = alc269_laptop_unsol_event,
14861 .setup = alc269_laptop_dmic_setup,
14862 .init_hook = alc269_laptop_inithook,
14863 },
14864 [ALC269VB_AMIC] = {
14865 .mixers = { alc269vb_laptop_mixer },
14866 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14867 .init_verbs = { alc269vb_init_verbs,
14868 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
14869 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14870 .dac_nids = alc269_dac_nids,
14871 .hp_nid = 0x03,
14872 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14873 .channel_mode = alc269_modes,
84898e87 14874 .unsol_event = alc269_laptop_unsol_event,
226b1ec8 14875 .setup = alc269vb_laptop_amic_setup,
84898e87
KY
14876 .init_hook = alc269_laptop_inithook,
14877 },
14878 [ALC269VB_DMIC] = {
14879 .mixers = { alc269vb_laptop_mixer },
14880 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14881 .init_verbs = { alc269vb_init_verbs,
14882 alc269vb_laptop_dmic_init_verbs },
14883 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14884 .dac_nids = alc269_dac_nids,
14885 .hp_nid = 0x03,
14886 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14887 .channel_mode = alc269_modes,
14888 .unsol_event = alc269_laptop_unsol_event,
14889 .setup = alc269vb_laptop_dmic_setup,
14890 .init_hook = alc269_laptop_inithook,
f53281e6 14891 },
26f5df26 14892 [ALC269_FUJITSU] = {
45bdd1c1 14893 .mixers = { alc269_fujitsu_mixer },
84898e87 14894 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 14895 .init_verbs = { alc269_init_verbs,
84898e87 14896 alc269_laptop_dmic_init_verbs },
26f5df26
TI
14897 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14898 .dac_nids = alc269_dac_nids,
14899 .hp_nid = 0x03,
14900 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14901 .channel_mode = alc269_modes,
84898e87
KY
14902 .unsol_event = alc269_laptop_unsol_event,
14903 .setup = alc269_laptop_dmic_setup,
14904 .init_hook = alc269_laptop_inithook,
26f5df26 14905 },
64154835
TV
14906 [ALC269_LIFEBOOK] = {
14907 .mixers = { alc269_lifebook_mixer },
14908 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14909 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14910 .dac_nids = alc269_dac_nids,
14911 .hp_nid = 0x03,
14912 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14913 .channel_mode = alc269_modes,
14914 .input_mux = &alc269_capture_source,
14915 .unsol_event = alc269_lifebook_unsol_event,
14916 .init_hook = alc269_lifebook_init_hook,
14917 },
fe3eb0a7
KY
14918 [ALC271_ACER] = {
14919 .mixers = { alc269_asus_mixer },
14920 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14921 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
14922 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14923 .dac_nids = alc269_dac_nids,
14924 .adc_nids = alc262_dmic_adc_nids,
14925 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
14926 .capsrc_nids = alc262_dmic_capsrc_nids,
14927 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14928 .channel_mode = alc269_modes,
14929 .input_mux = &alc269_capture_source,
14930 .dig_out_nid = ALC880_DIGOUT_NID,
14931 .unsol_event = alc_sku_unsol_event,
14932 .setup = alc269vb_laptop_dmic_setup,
14933 .init_hook = alc_inithook,
14934 },
f6a92248
KY
14935};
14936
977ddd6b
KY
14937static int alc269_fill_coef(struct hda_codec *codec)
14938{
14939 int val;
14940
14941 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
14942 alc_write_coef_idx(codec, 0xf, 0x960b);
14943 alc_write_coef_idx(codec, 0xe, 0x8817);
14944 }
14945
14946 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
14947 alc_write_coef_idx(codec, 0xf, 0x960b);
14948 alc_write_coef_idx(codec, 0xe, 0x8814);
14949 }
14950
14951 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14952 val = alc_read_coef_idx(codec, 0x04);
14953 /* Power up output pin */
14954 alc_write_coef_idx(codec, 0x04, val | (1<<11));
14955 }
14956
14957 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14958 val = alc_read_coef_idx(codec, 0xd);
14959 if ((val & 0x0c00) >> 10 != 0x1) {
14960 /* Capless ramp up clock control */
14961 alc_write_coef_idx(codec, 0xd, val | 1<<10);
14962 }
14963 val = alc_read_coef_idx(codec, 0x17);
14964 if ((val & 0x01c0) >> 6 != 0x4) {
14965 /* Class D power on reset */
14966 alc_write_coef_idx(codec, 0x17, val | 1<<7);
14967 }
14968 }
14969 return 0;
14970}
14971
f6a92248
KY
14972static int patch_alc269(struct hda_codec *codec)
14973{
14974 struct alc_spec *spec;
14975 int board_config;
14976 int err;
14977
14978 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14979 if (spec == NULL)
14980 return -ENOMEM;
14981
14982 codec->spec = spec;
14983
da00c244
KY
14984 alc_auto_parse_customize_define(codec);
14985
274693f3 14986 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
c027ddcd 14987 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
d433a678 14988 spec->cdefine.platform_type == 1) {
c027ddcd 14989 alc_codec_rename(codec, "ALC271X");
d433a678
TI
14990 spec->codec_variant = ALC269_TYPE_ALC271X;
14991 } else {
c027ddcd 14992 alc_codec_rename(codec, "ALC259");
d433a678
TI
14993 spec->codec_variant = ALC269_TYPE_ALC259;
14994 }
c027ddcd
KY
14995 } else
14996 alc_fix_pll_init(codec, 0x20, 0x04, 15);
274693f3 14997
977ddd6b
KY
14998 alc269_fill_coef(codec);
14999
f6a92248
KY
15000 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15001 alc269_models,
15002 alc269_cfg_tbl);
15003
15004 if (board_config < 0) {
9a11f1aa
TI
15005 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15006 codec->chip_name);
f6a92248
KY
15007 board_config = ALC269_AUTO;
15008 }
15009
ff818c24
TI
15010 if (board_config == ALC269_AUTO)
15011 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
15012
f6a92248
KY
15013 if (board_config == ALC269_AUTO) {
15014 /* automatic parse from the BIOS config */
15015 err = alc269_parse_auto_config(codec);
15016 if (err < 0) {
15017 alc_free(codec);
15018 return err;
15019 } else if (!err) {
15020 printk(KERN_INFO
15021 "hda_codec: Cannot set up configuration "
15022 "from BIOS. Using base mode...\n");
15023 board_config = ALC269_BASIC;
15024 }
15025 }
15026
dc1eae25 15027 if (has_cdefine_beep(codec)) {
8af2591d
TI
15028 err = snd_hda_attach_beep_device(codec, 0x1);
15029 if (err < 0) {
15030 alc_free(codec);
15031 return err;
15032 }
680cd536
KK
15033 }
15034
f6a92248 15035 if (board_config != ALC269_AUTO)
e9c364c0 15036 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15037
84898e87 15038 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15039 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15040 * fix the sample rate of analog I/O to 44.1kHz
15041 */
15042 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15043 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15044 } else if (spec->dual_adc_switch) {
15045 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15046 /* switch ADC dynamically */
15047 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15048 } else {
15049 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15050 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15051 }
f6a92248
KY
15052 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15053 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15054
6694635d 15055 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
d433a678 15056 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
6694635d
TI
15057 spec->adc_nids = alc269_adc_nids;
15058 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15059 spec->capsrc_nids = alc269_capsrc_nids;
15060 } else {
15061 spec->adc_nids = alc269vb_adc_nids;
15062 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15063 spec->capsrc_nids = alc269vb_capsrc_nids;
15064 }
84898e87
KY
15065 }
15066
f9e336f6 15067 if (!spec->cap_mixer)
b59bdf3b 15068 set_capture_mixer(codec);
dc1eae25 15069 if (has_cdefine_beep(codec))
da00c244 15070 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15071
ff818c24
TI
15072 if (board_config == ALC269_AUTO)
15073 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
15074
100d5eb3
TI
15075 spec->vmaster_nid = 0x02;
15076
f6a92248 15077 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15078#ifdef CONFIG_SND_HDA_POWER_SAVE
15079 codec->patch_ops.suspend = alc269_suspend;
15080#endif
15081#ifdef SND_HDA_NEEDS_RESUME
15082 codec->patch_ops.resume = alc269_resume;
15083#endif
f6a92248
KY
15084 if (board_config == ALC269_AUTO)
15085 spec->init_hook = alc269_auto_init;
15086#ifdef CONFIG_SND_HDA_POWER_SAVE
15087 if (!spec->loopback.amplist)
15088 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15089 if (alc269_mic2_for_mute_led(codec))
15090 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15091#endif
15092
15093 return 0;
15094}
15095
df694daa
KY
15096/*
15097 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15098 */
15099
15100/*
15101 * set the path ways for 2 channel output
15102 * need to set the codec line out and mic 1 pin widgets to inputs
15103 */
15104static struct hda_verb alc861_threestack_ch2_init[] = {
15105 /* set pin widget 1Ah (line in) for input */
15106 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15107 /* set pin widget 18h (mic1/2) for input, for mic also enable
15108 * the vref
15109 */
df694daa
KY
15110 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15111
9c7f852e
TI
15112 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15113#if 0
15114 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15115 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15116#endif
df694daa
KY
15117 { } /* end */
15118};
15119/*
15120 * 6ch mode
15121 * need to set the codec line out and mic 1 pin widgets to outputs
15122 */
15123static struct hda_verb alc861_threestack_ch6_init[] = {
15124 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15125 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15126 /* set pin widget 18h (mic1) for output (CLFE)*/
15127 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15128
15129 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15130 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15131
9c7f852e
TI
15132 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15133#if 0
15134 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15135 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15136#endif
df694daa
KY
15137 { } /* end */
15138};
15139
15140static struct hda_channel_mode alc861_threestack_modes[2] = {
15141 { 2, alc861_threestack_ch2_init },
15142 { 6, alc861_threestack_ch6_init },
15143};
22309c3e
TI
15144/* Set mic1 as input and unmute the mixer */
15145static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15146 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15147 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15148 { } /* end */
15149};
15150/* Set mic1 as output and mute mixer */
15151static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15152 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15153 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15154 { } /* end */
15155};
15156
15157static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15158 { 2, alc861_uniwill_m31_ch2_init },
15159 { 4, alc861_uniwill_m31_ch4_init },
15160};
df694daa 15161
7cdbff94
MD
15162/* Set mic1 and line-in as input and unmute the mixer */
15163static struct hda_verb alc861_asus_ch2_init[] = {
15164 /* set pin widget 1Ah (line in) for input */
15165 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15166 /* set pin widget 18h (mic1/2) for input, for mic also enable
15167 * the vref
15168 */
7cdbff94
MD
15169 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15170
15171 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15172#if 0
15173 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15174 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15175#endif
15176 { } /* end */
15177};
15178/* Set mic1 nad line-in as output and mute mixer */
15179static struct hda_verb alc861_asus_ch6_init[] = {
15180 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15181 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15182 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15183 /* set pin widget 18h (mic1) for output (CLFE)*/
15184 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15185 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15186 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15187 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15188
15189 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15190#if 0
15191 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15192 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15193#endif
15194 { } /* end */
15195};
15196
15197static struct hda_channel_mode alc861_asus_modes[2] = {
15198 { 2, alc861_asus_ch2_init },
15199 { 6, alc861_asus_ch6_init },
15200};
15201
df694daa
KY
15202/* patch-ALC861 */
15203
15204static struct snd_kcontrol_new alc861_base_mixer[] = {
15205 /* output mixer control */
15206 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15207 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15208 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15209 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15210 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15211
15212 /*Input mixer control */
15213 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15214 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15215 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15216 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15217 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15218 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15219 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15220 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15221 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15222 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15223
df694daa
KY
15224 { } /* end */
15225};
15226
15227static struct snd_kcontrol_new alc861_3ST_mixer[] = {
15228 /* output mixer control */
15229 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15230 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15231 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15232 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15233 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15234
15235 /* Input mixer control */
15236 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15237 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15238 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15239 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15240 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15241 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15242 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15243 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15244 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15245 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15246
df694daa
KY
15247 {
15248 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15249 .name = "Channel Mode",
15250 .info = alc_ch_mode_info,
15251 .get = alc_ch_mode_get,
15252 .put = alc_ch_mode_put,
15253 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15254 },
15255 { } /* end */
a53d1aec
TD
15256};
15257
d1d985f0 15258static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15259 /* output mixer control */
15260 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15261 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15262 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15263
a53d1aec 15264 { } /* end */
f12ab1e0 15265};
a53d1aec 15266
22309c3e
TI
15267static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15268 /* output mixer control */
15269 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15270 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15271 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15272 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15273 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15274
15275 /* Input mixer control */
15276 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15277 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15278 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15279 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15280 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15281 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15282 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15283 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15284 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15285 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15286
22309c3e
TI
15287 {
15288 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15289 .name = "Channel Mode",
15290 .info = alc_ch_mode_info,
15291 .get = alc_ch_mode_get,
15292 .put = alc_ch_mode_put,
15293 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15294 },
15295 { } /* end */
f12ab1e0 15296};
7cdbff94
MD
15297
15298static struct snd_kcontrol_new alc861_asus_mixer[] = {
15299 /* output mixer control */
15300 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15301 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15302 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15303 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15304 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15305
15306 /* Input mixer control */
15307 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15308 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15309 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15310 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15311 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15312 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15313 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15314 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15315 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15316 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15317
7cdbff94
MD
15318 {
15319 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15320 .name = "Channel Mode",
15321 .info = alc_ch_mode_info,
15322 .get = alc_ch_mode_get,
15323 .put = alc_ch_mode_put,
15324 .private_value = ARRAY_SIZE(alc861_asus_modes),
15325 },
15326 { }
56bb0cab
TI
15327};
15328
15329/* additional mixer */
d1d985f0 15330static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15331 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15332 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15333 { }
15334};
7cdbff94 15335
df694daa
KY
15336/*
15337 * generic initialization of ADC, input mixers and output mixers
15338 */
15339static struct hda_verb alc861_base_init_verbs[] = {
15340 /*
15341 * Unmute ADC0 and set the default input to mic-in
15342 */
15343 /* port-A for surround (rear panel) */
15344 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15345 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15346 /* port-B for mic-in (rear panel) with vref */
15347 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15348 /* port-C for line-in (rear panel) */
15349 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15350 /* port-D for Front */
15351 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15352 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15353 /* port-E for HP out (front panel) */
15354 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15355 /* route front PCM to HP */
9dece1d7 15356 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15357 /* port-F for mic-in (front panel) with vref */
15358 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15359 /* port-G for CLFE (rear panel) */
15360 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15361 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15362 /* port-H for side (rear panel) */
15363 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15364 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15365 /* CD-in */
15366 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15367 /* route front mic to ADC1*/
15368 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15369 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15370
df694daa
KY
15371 /* Unmute DAC0~3 & spdif out*/
15372 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15373 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15374 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15375 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15376 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15377
df694daa
KY
15378 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15379 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15380 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15381 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15382 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15383
df694daa
KY
15384 /* Unmute Stereo Mixer 15 */
15385 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15386 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15387 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15388 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15389
15390 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15391 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15392 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15393 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15394 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15395 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15396 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15397 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15398 /* hp used DAC 3 (Front) */
15399 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15400 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15401
15402 { }
15403};
15404
15405static struct hda_verb alc861_threestack_init_verbs[] = {
15406 /*
15407 * Unmute ADC0 and set the default input to mic-in
15408 */
15409 /* port-A for surround (rear panel) */
15410 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15411 /* port-B for mic-in (rear panel) with vref */
15412 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15413 /* port-C for line-in (rear panel) */
15414 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15415 /* port-D for Front */
15416 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15417 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15418 /* port-E for HP out (front panel) */
15419 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15420 /* route front PCM to HP */
9dece1d7 15421 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15422 /* port-F for mic-in (front panel) with vref */
15423 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15424 /* port-G for CLFE (rear panel) */
15425 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15426 /* port-H for side (rear panel) */
15427 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15428 /* CD-in */
15429 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15430 /* route front mic to ADC1*/
15431 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15432 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15433 /* Unmute DAC0~3 & spdif out*/
15434 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15435 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15436 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15437 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15438 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15439
df694daa
KY
15440 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15441 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15442 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15443 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15444 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15445
df694daa
KY
15446 /* Unmute Stereo Mixer 15 */
15447 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15448 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15449 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15450 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15451
15452 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15453 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15454 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15455 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15456 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15457 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15458 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15459 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15460 /* hp used DAC 3 (Front) */
15461 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15462 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15463 { }
15464};
22309c3e
TI
15465
15466static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15467 /*
15468 * Unmute ADC0 and set the default input to mic-in
15469 */
15470 /* port-A for surround (rear panel) */
15471 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15472 /* port-B for mic-in (rear panel) with vref */
15473 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15474 /* port-C for line-in (rear panel) */
15475 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15476 /* port-D for Front */
15477 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15478 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15479 /* port-E for HP out (front panel) */
f12ab1e0
TI
15480 /* this has to be set to VREF80 */
15481 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15482 /* route front PCM to HP */
9dece1d7 15483 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15484 /* port-F for mic-in (front panel) with vref */
15485 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15486 /* port-G for CLFE (rear panel) */
15487 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15488 /* port-H for side (rear panel) */
15489 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15490 /* CD-in */
15491 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15492 /* route front mic to ADC1*/
15493 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15494 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15495 /* Unmute DAC0~3 & spdif out*/
15496 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15497 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15498 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15499 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15500 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15501
22309c3e
TI
15502 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15503 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15504 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15505 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15506 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15507
22309c3e
TI
15508 /* Unmute Stereo Mixer 15 */
15509 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15510 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15511 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15512 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15513
15514 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15515 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15516 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15517 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15518 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15519 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15520 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15521 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15522 /* hp used DAC 3 (Front) */
15523 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15524 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15525 { }
15526};
15527
7cdbff94
MD
15528static struct hda_verb alc861_asus_init_verbs[] = {
15529 /*
15530 * Unmute ADC0 and set the default input to mic-in
15531 */
f12ab1e0
TI
15532 /* port-A for surround (rear panel)
15533 * according to codec#0 this is the HP jack
15534 */
7cdbff94
MD
15535 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15536 /* route front PCM to HP */
15537 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15538 /* port-B for mic-in (rear panel) with vref */
15539 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15540 /* port-C for line-in (rear panel) */
15541 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15542 /* port-D for Front */
15543 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15544 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15545 /* port-E for HP out (front panel) */
f12ab1e0
TI
15546 /* this has to be set to VREF80 */
15547 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15548 /* route front PCM to HP */
9dece1d7 15549 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15550 /* port-F for mic-in (front panel) with vref */
15551 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15552 /* port-G for CLFE (rear panel) */
15553 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15554 /* port-H for side (rear panel) */
15555 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15556 /* CD-in */
15557 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15558 /* route front mic to ADC1*/
15559 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15560 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15561 /* Unmute DAC0~3 & spdif out*/
15562 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15563 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15564 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15565 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15566 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15567 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15568 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15569 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15570 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15571 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15572
7cdbff94
MD
15573 /* Unmute Stereo Mixer 15 */
15574 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15575 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15576 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15577 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15578
15579 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15580 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15581 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15582 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15583 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15584 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15585 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15586 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15587 /* hp used DAC 3 (Front) */
15588 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15589 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15590 { }
15591};
15592
56bb0cab
TI
15593/* additional init verbs for ASUS laptops */
15594static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15595 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15596 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15597 { }
15598};
7cdbff94 15599
df694daa
KY
15600/*
15601 * generic initialization of ADC, input mixers and output mixers
15602 */
15603static struct hda_verb alc861_auto_init_verbs[] = {
15604 /*
15605 * Unmute ADC0 and set the default input to mic-in
15606 */
f12ab1e0 15607 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15608 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15609
df694daa
KY
15610 /* Unmute DAC0~3 & spdif out*/
15611 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15612 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15613 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15614 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15615 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15616
df694daa
KY
15617 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15618 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15619 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15620 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15621 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15622
df694daa
KY
15623 /* Unmute Stereo Mixer 15 */
15624 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15625 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15626 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15627 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15628
1c20930a
TI
15629 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15630 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15631 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15632 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15633 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15634 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15635 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15636 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15637
15638 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15639 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15640 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15641 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15642 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15643 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15644 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15645 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15646
f12ab1e0 15647 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15648
15649 { }
15650};
15651
a53d1aec
TD
15652static struct hda_verb alc861_toshiba_init_verbs[] = {
15653 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15654
a53d1aec
TD
15655 { }
15656};
15657
15658/* toggle speaker-output according to the hp-jack state */
15659static void alc861_toshiba_automute(struct hda_codec *codec)
15660{
864f92be 15661 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15662
47fd830a
TI
15663 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15664 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15665 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15666 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15667}
15668
15669static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15670 unsigned int res)
15671{
a53d1aec
TD
15672 if ((res >> 26) == ALC880_HP_EVENT)
15673 alc861_toshiba_automute(codec);
15674}
15675
def319f9 15676/* pcm configuration: identical with ALC880 */
df694daa
KY
15677#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15678#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15679#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15680#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15681
15682
15683#define ALC861_DIGOUT_NID 0x07
15684
15685static struct hda_channel_mode alc861_8ch_modes[1] = {
15686 { 8, NULL }
15687};
15688
15689static hda_nid_t alc861_dac_nids[4] = {
15690 /* front, surround, clfe, side */
15691 0x03, 0x06, 0x05, 0x04
15692};
15693
9c7f852e
TI
15694static hda_nid_t alc660_dac_nids[3] = {
15695 /* front, clfe, surround */
15696 0x03, 0x05, 0x06
15697};
15698
df694daa
KY
15699static hda_nid_t alc861_adc_nids[1] = {
15700 /* ADC0-2 */
15701 0x08,
15702};
15703
15704static struct hda_input_mux alc861_capture_source = {
15705 .num_items = 5,
15706 .items = {
15707 { "Mic", 0x0 },
15708 { "Front Mic", 0x3 },
15709 { "Line", 0x1 },
15710 { "CD", 0x4 },
15711 { "Mixer", 0x5 },
15712 },
15713};
15714
1c20930a
TI
15715static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15716{
15717 struct alc_spec *spec = codec->spec;
15718 hda_nid_t mix, srcs[5];
15719 int i, j, num;
15720
15721 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15722 return 0;
15723 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15724 if (num < 0)
15725 return 0;
15726 for (i = 0; i < num; i++) {
15727 unsigned int type;
a22d543a 15728 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15729 if (type != AC_WID_AUD_OUT)
15730 continue;
15731 for (j = 0; j < spec->multiout.num_dacs; j++)
15732 if (spec->multiout.dac_nids[j] == srcs[i])
15733 break;
15734 if (j >= spec->multiout.num_dacs)
15735 return srcs[i];
15736 }
15737 return 0;
15738}
15739
df694daa 15740/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15741static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15742 const struct auto_pin_cfg *cfg)
df694daa 15743{
1c20930a 15744 struct alc_spec *spec = codec->spec;
df694daa 15745 int i;
1c20930a 15746 hda_nid_t nid, dac;
df694daa
KY
15747
15748 spec->multiout.dac_nids = spec->private_dac_nids;
15749 for (i = 0; i < cfg->line_outs; i++) {
15750 nid = cfg->line_out_pins[i];
1c20930a
TI
15751 dac = alc861_look_for_dac(codec, nid);
15752 if (!dac)
15753 continue;
15754 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15755 }
df694daa
KY
15756 return 0;
15757}
15758
1c20930a
TI
15759static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15760 hda_nid_t nid, unsigned int chs)
15761{
0afe5f89 15762 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
1c20930a
TI
15763 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15764}
15765
df694daa 15766/* add playback controls from the parsed DAC table */
1c20930a 15767static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15768 const struct auto_pin_cfg *cfg)
15769{
1c20930a 15770 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
15771 static const char *chname[4] = {
15772 "Front", "Surround", NULL /*CLFE*/, "Side"
15773 };
df694daa 15774 hda_nid_t nid;
1c20930a
TI
15775 int i, err;
15776
15777 if (cfg->line_outs == 1) {
15778 const char *pfx = NULL;
15779 if (!cfg->hp_outs)
15780 pfx = "Master";
15781 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15782 pfx = "Speaker";
15783 if (pfx) {
15784 nid = spec->multiout.dac_nids[0];
15785 return alc861_create_out_sw(codec, pfx, nid, 3);
15786 }
15787 }
df694daa
KY
15788
15789 for (i = 0; i < cfg->line_outs; i++) {
15790 nid = spec->multiout.dac_nids[i];
f12ab1e0 15791 if (!nid)
df694daa 15792 continue;
1c20930a 15793 if (i == 2) {
df694daa 15794 /* Center/LFE */
1c20930a 15795 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15796 if (err < 0)
df694daa 15797 return err;
1c20930a 15798 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15799 if (err < 0)
df694daa
KY
15800 return err;
15801 } else {
1c20930a 15802 err = alc861_create_out_sw(codec, chname[i], nid, 3);
f12ab1e0 15803 if (err < 0)
df694daa
KY
15804 return err;
15805 }
15806 }
15807 return 0;
15808}
15809
1c20930a 15810static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 15811{
1c20930a 15812 struct alc_spec *spec = codec->spec;
df694daa
KY
15813 int err;
15814 hda_nid_t nid;
15815
f12ab1e0 15816 if (!pin)
df694daa
KY
15817 return 0;
15818
15819 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
15820 nid = alc861_look_for_dac(codec, pin);
15821 if (nid) {
15822 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15823 if (err < 0)
15824 return err;
15825 spec->multiout.hp_nid = nid;
15826 }
df694daa
KY
15827 }
15828 return 0;
15829}
15830
15831/* create playback/capture controls for input pins */
05f5f477 15832static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 15833 const struct auto_pin_cfg *cfg)
df694daa 15834{
05f5f477 15835 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
15836}
15837
f12ab1e0
TI
15838static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15839 hda_nid_t nid,
1c20930a 15840 int pin_type, hda_nid_t dac)
df694daa 15841{
1c20930a
TI
15842 hda_nid_t mix, srcs[5];
15843 int i, num;
15844
564c5bea
JL
15845 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15846 pin_type);
1c20930a 15847 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 15848 AMP_OUT_UNMUTE);
1c20930a
TI
15849 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15850 return;
15851 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15852 if (num < 0)
15853 return;
15854 for (i = 0; i < num; i++) {
15855 unsigned int mute;
15856 if (srcs[i] == dac || srcs[i] == 0x15)
15857 mute = AMP_IN_UNMUTE(i);
15858 else
15859 mute = AMP_IN_MUTE(i);
15860 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15861 mute);
15862 }
df694daa
KY
15863}
15864
15865static void alc861_auto_init_multi_out(struct hda_codec *codec)
15866{
15867 struct alc_spec *spec = codec->spec;
15868 int i;
15869
15870 for (i = 0; i < spec->autocfg.line_outs; i++) {
15871 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 15872 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 15873 if (nid)
baba8ee9 15874 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 15875 spec->multiout.dac_nids[i]);
df694daa
KY
15876 }
15877}
15878
15879static void alc861_auto_init_hp_out(struct hda_codec *codec)
15880{
15881 struct alc_spec *spec = codec->spec;
df694daa 15882
15870f05
TI
15883 if (spec->autocfg.hp_outs)
15884 alc861_auto_set_output_and_unmute(codec,
15885 spec->autocfg.hp_pins[0],
15886 PIN_HP,
1c20930a 15887 spec->multiout.hp_nid);
15870f05
TI
15888 if (spec->autocfg.speaker_outs)
15889 alc861_auto_set_output_and_unmute(codec,
15890 spec->autocfg.speaker_pins[0],
15891 PIN_OUT,
1c20930a 15892 spec->multiout.dac_nids[0]);
df694daa
KY
15893}
15894
15895static void alc861_auto_init_analog_input(struct hda_codec *codec)
15896{
15897 struct alc_spec *spec = codec->spec;
66ceeb6b 15898 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
15899 int i;
15900
66ceeb6b
TI
15901 for (i = 0; i < cfg->num_inputs; i++) {
15902 hda_nid_t nid = cfg->inputs[i].pin;
23f0c048 15903 if (nid >= 0x0c && nid <= 0x11)
30ea098f 15904 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
df694daa
KY
15905 }
15906}
15907
15908/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
15909/* return 1 if successful, 0 if the proper config is not found,
15910 * or a negative error code
15911 */
df694daa
KY
15912static int alc861_parse_auto_config(struct hda_codec *codec)
15913{
15914 struct alc_spec *spec = codec->spec;
15915 int err;
15916 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
15917
f12ab1e0
TI
15918 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15919 alc861_ignore);
15920 if (err < 0)
df694daa 15921 return err;
f12ab1e0 15922 if (!spec->autocfg.line_outs)
df694daa
KY
15923 return 0; /* can't find valid BIOS pin config */
15924
1c20930a 15925 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
15926 if (err < 0)
15927 return err;
1c20930a 15928 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
15929 if (err < 0)
15930 return err;
1c20930a 15931 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
15932 if (err < 0)
15933 return err;
05f5f477 15934 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 15935 if (err < 0)
df694daa
KY
15936 return err;
15937
15938 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15939
757899ac 15940 alc_auto_parse_digital(codec);
df694daa 15941
603c4019 15942 if (spec->kctls.list)
d88897ea 15943 add_mixer(spec, spec->kctls.list);
df694daa 15944
d88897ea 15945 add_verb(spec, alc861_auto_init_verbs);
df694daa 15946
a1e8d2da 15947 spec->num_mux_defs = 1;
61b9b9b1 15948 spec->input_mux = &spec->private_imux[0];
df694daa
KY
15949
15950 spec->adc_nids = alc861_adc_nids;
15951 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 15952 set_capture_mixer(codec);
df694daa 15953
6227cdce 15954 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 15955
df694daa
KY
15956 return 1;
15957}
15958
ae6b813a
TI
15959/* additional initialization for auto-configuration model */
15960static void alc861_auto_init(struct hda_codec *codec)
df694daa 15961{
f6c7e546 15962 struct alc_spec *spec = codec->spec;
df694daa
KY
15963 alc861_auto_init_multi_out(codec);
15964 alc861_auto_init_hp_out(codec);
15965 alc861_auto_init_analog_input(codec);
757899ac 15966 alc_auto_init_digital(codec);
f6c7e546 15967 if (spec->unsol_event)
7fb0d78f 15968 alc_inithook(codec);
df694daa
KY
15969}
15970
cb53c626
TI
15971#ifdef CONFIG_SND_HDA_POWER_SAVE
15972static struct hda_amp_list alc861_loopbacks[] = {
15973 { 0x15, HDA_INPUT, 0 },
15974 { 0x15, HDA_INPUT, 1 },
15975 { 0x15, HDA_INPUT, 2 },
15976 { 0x15, HDA_INPUT, 3 },
15977 { } /* end */
15978};
15979#endif
15980
df694daa
KY
15981
15982/*
15983 * configuration and preset
15984 */
f5fcc13c
TI
15985static const char *alc861_models[ALC861_MODEL_LAST] = {
15986 [ALC861_3ST] = "3stack",
15987 [ALC660_3ST] = "3stack-660",
15988 [ALC861_3ST_DIG] = "3stack-dig",
15989 [ALC861_6ST_DIG] = "6stack-dig",
15990 [ALC861_UNIWILL_M31] = "uniwill-m31",
15991 [ALC861_TOSHIBA] = "toshiba",
15992 [ALC861_ASUS] = "asus",
15993 [ALC861_ASUS_LAPTOP] = "asus-laptop",
15994 [ALC861_AUTO] = "auto",
15995};
15996
15997static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 15998 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
15999 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16000 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16001 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 16002 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 16003 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16004 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16005 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16006 * Any other models that need this preset?
16007 */
16008 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16009 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16010 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16011 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16012 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16013 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16014 /* FIXME: the below seems conflict */
16015 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16016 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16017 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16018 {}
16019};
16020
16021static struct alc_config_preset alc861_presets[] = {
16022 [ALC861_3ST] = {
16023 .mixers = { alc861_3ST_mixer },
16024 .init_verbs = { alc861_threestack_init_verbs },
16025 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16026 .dac_nids = alc861_dac_nids,
16027 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16028 .channel_mode = alc861_threestack_modes,
4e195a7b 16029 .need_dac_fix = 1,
df694daa
KY
16030 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16031 .adc_nids = alc861_adc_nids,
16032 .input_mux = &alc861_capture_source,
16033 },
16034 [ALC861_3ST_DIG] = {
16035 .mixers = { alc861_base_mixer },
16036 .init_verbs = { alc861_threestack_init_verbs },
16037 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16038 .dac_nids = alc861_dac_nids,
16039 .dig_out_nid = ALC861_DIGOUT_NID,
16040 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16041 .channel_mode = alc861_threestack_modes,
4e195a7b 16042 .need_dac_fix = 1,
df694daa
KY
16043 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16044 .adc_nids = alc861_adc_nids,
16045 .input_mux = &alc861_capture_source,
16046 },
16047 [ALC861_6ST_DIG] = {
16048 .mixers = { alc861_base_mixer },
16049 .init_verbs = { alc861_base_init_verbs },
16050 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16051 .dac_nids = alc861_dac_nids,
16052 .dig_out_nid = ALC861_DIGOUT_NID,
16053 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16054 .channel_mode = alc861_8ch_modes,
16055 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16056 .adc_nids = alc861_adc_nids,
16057 .input_mux = &alc861_capture_source,
16058 },
9c7f852e
TI
16059 [ALC660_3ST] = {
16060 .mixers = { alc861_3ST_mixer },
16061 .init_verbs = { alc861_threestack_init_verbs },
16062 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16063 .dac_nids = alc660_dac_nids,
16064 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16065 .channel_mode = alc861_threestack_modes,
4e195a7b 16066 .need_dac_fix = 1,
9c7f852e
TI
16067 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16068 .adc_nids = alc861_adc_nids,
16069 .input_mux = &alc861_capture_source,
16070 },
22309c3e
TI
16071 [ALC861_UNIWILL_M31] = {
16072 .mixers = { alc861_uniwill_m31_mixer },
16073 .init_verbs = { alc861_uniwill_m31_init_verbs },
16074 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16075 .dac_nids = alc861_dac_nids,
16076 .dig_out_nid = ALC861_DIGOUT_NID,
16077 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16078 .channel_mode = alc861_uniwill_m31_modes,
16079 .need_dac_fix = 1,
16080 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16081 .adc_nids = alc861_adc_nids,
16082 .input_mux = &alc861_capture_source,
16083 },
a53d1aec
TD
16084 [ALC861_TOSHIBA] = {
16085 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16086 .init_verbs = { alc861_base_init_verbs,
16087 alc861_toshiba_init_verbs },
a53d1aec
TD
16088 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16089 .dac_nids = alc861_dac_nids,
16090 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16091 .channel_mode = alc883_3ST_2ch_modes,
16092 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16093 .adc_nids = alc861_adc_nids,
16094 .input_mux = &alc861_capture_source,
16095 .unsol_event = alc861_toshiba_unsol_event,
16096 .init_hook = alc861_toshiba_automute,
16097 },
7cdbff94
MD
16098 [ALC861_ASUS] = {
16099 .mixers = { alc861_asus_mixer },
16100 .init_verbs = { alc861_asus_init_verbs },
16101 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16102 .dac_nids = alc861_dac_nids,
16103 .dig_out_nid = ALC861_DIGOUT_NID,
16104 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16105 .channel_mode = alc861_asus_modes,
16106 .need_dac_fix = 1,
16107 .hp_nid = 0x06,
16108 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16109 .adc_nids = alc861_adc_nids,
16110 .input_mux = &alc861_capture_source,
16111 },
56bb0cab
TI
16112 [ALC861_ASUS_LAPTOP] = {
16113 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16114 .init_verbs = { alc861_asus_init_verbs,
16115 alc861_asus_laptop_init_verbs },
16116 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16117 .dac_nids = alc861_dac_nids,
16118 .dig_out_nid = ALC861_DIGOUT_NID,
16119 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16120 .channel_mode = alc883_3ST_2ch_modes,
16121 .need_dac_fix = 1,
16122 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16123 .adc_nids = alc861_adc_nids,
16124 .input_mux = &alc861_capture_source,
16125 },
16126};
df694daa 16127
cfc9b06f
TI
16128/* Pin config fixes */
16129enum {
16130 PINFIX_FSC_AMILO_PI1505,
16131};
16132
cfc9b06f
TI
16133static const struct alc_fixup alc861_fixups[] = {
16134 [PINFIX_FSC_AMILO_PI1505] = {
73413b12
TI
16135 .pins = (const struct alc_pincfg[]) {
16136 { 0x0b, 0x0221101f }, /* HP */
16137 { 0x0f, 0x90170310 }, /* speaker */
16138 { }
16139 }
cfc9b06f
TI
16140 },
16141};
16142
16143static struct snd_pci_quirk alc861_fixup_tbl[] = {
16144 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16145 {}
16146};
df694daa
KY
16147
16148static int patch_alc861(struct hda_codec *codec)
16149{
16150 struct alc_spec *spec;
16151 int board_config;
16152 int err;
16153
dc041e0b 16154 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16155 if (spec == NULL)
16156 return -ENOMEM;
16157
f12ab1e0 16158 codec->spec = spec;
df694daa 16159
f5fcc13c
TI
16160 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16161 alc861_models,
16162 alc861_cfg_tbl);
9c7f852e 16163
f5fcc13c 16164 if (board_config < 0) {
9a11f1aa
TI
16165 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16166 codec->chip_name);
df694daa
KY
16167 board_config = ALC861_AUTO;
16168 }
16169
7fa90e87
TI
16170 if (board_config == ALC861_AUTO)
16171 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
cfc9b06f 16172
df694daa
KY
16173 if (board_config == ALC861_AUTO) {
16174 /* automatic parse from the BIOS config */
16175 err = alc861_parse_auto_config(codec);
16176 if (err < 0) {
16177 alc_free(codec);
16178 return err;
f12ab1e0 16179 } else if (!err) {
9c7f852e
TI
16180 printk(KERN_INFO
16181 "hda_codec: Cannot set up configuration "
16182 "from BIOS. Using base mode...\n");
df694daa
KY
16183 board_config = ALC861_3ST_DIG;
16184 }
16185 }
16186
680cd536
KK
16187 err = snd_hda_attach_beep_device(codec, 0x23);
16188 if (err < 0) {
16189 alc_free(codec);
16190 return err;
16191 }
16192
df694daa 16193 if (board_config != ALC861_AUTO)
e9c364c0 16194 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16195
df694daa
KY
16196 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16197 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16198
df694daa
KY
16199 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16200 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16201
c7a8eb10
TI
16202 if (!spec->cap_mixer)
16203 set_capture_mixer(codec);
45bdd1c1
TI
16204 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16205
2134ea4f
TI
16206 spec->vmaster_nid = 0x03;
16207
7fa90e87
TI
16208 if (board_config == ALC861_AUTO)
16209 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
16210
df694daa 16211 codec->patch_ops = alc_patch_ops;
c97259df 16212 if (board_config == ALC861_AUTO) {
ae6b813a 16213 spec->init_hook = alc861_auto_init;
c97259df
DC
16214#ifdef CONFIG_SND_HDA_POWER_SAVE
16215 spec->power_hook = alc_power_eapd;
16216#endif
16217 }
cb53c626
TI
16218#ifdef CONFIG_SND_HDA_POWER_SAVE
16219 if (!spec->loopback.amplist)
16220 spec->loopback.amplist = alc861_loopbacks;
16221#endif
ea1fb29a 16222
1da177e4
LT
16223 return 0;
16224}
16225
f32610ed
JS
16226/*
16227 * ALC861-VD support
16228 *
16229 * Based on ALC882
16230 *
16231 * In addition, an independent DAC
16232 */
16233#define ALC861VD_DIGOUT_NID 0x06
16234
16235static hda_nid_t alc861vd_dac_nids[4] = {
16236 /* front, surr, clfe, side surr */
16237 0x02, 0x03, 0x04, 0x05
16238};
16239
16240/* dac_nids for ALC660vd are in a different order - according to
16241 * Realtek's driver.
def319f9 16242 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16243 * of ALC660vd codecs, but for now there is only 3stack mixer
16244 * - and it is the same as in 861vd.
16245 * adc_nids in ALC660vd are (is) the same as in 861vd
16246 */
16247static hda_nid_t alc660vd_dac_nids[3] = {
16248 /* front, rear, clfe, rear_surr */
16249 0x02, 0x04, 0x03
16250};
16251
16252static hda_nid_t alc861vd_adc_nids[1] = {
16253 /* ADC0 */
16254 0x09,
16255};
16256
e1406348
TI
16257static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16258
f32610ed
JS
16259/* input MUX */
16260/* FIXME: should be a matrix-type input source selection */
16261static struct hda_input_mux alc861vd_capture_source = {
16262 .num_items = 4,
16263 .items = {
16264 { "Mic", 0x0 },
16265 { "Front Mic", 0x1 },
16266 { "Line", 0x2 },
16267 { "CD", 0x4 },
16268 },
16269};
16270
272a527c 16271static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16272 .num_items = 2,
272a527c 16273 .items = {
b419f346
TD
16274 { "Ext Mic", 0x0 },
16275 { "Int Mic", 0x1 },
272a527c
KY
16276 },
16277};
16278
d1a991a6
KY
16279static struct hda_input_mux alc861vd_hp_capture_source = {
16280 .num_items = 2,
16281 .items = {
16282 { "Front Mic", 0x0 },
16283 { "ATAPI Mic", 0x1 },
16284 },
16285};
16286
f32610ed
JS
16287/*
16288 * 2ch mode
16289 */
16290static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16291 { 2, NULL }
16292};
16293
16294/*
16295 * 6ch mode
16296 */
16297static struct hda_verb alc861vd_6stack_ch6_init[] = {
16298 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16299 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16300 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16301 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16302 { } /* end */
16303};
16304
16305/*
16306 * 8ch mode
16307 */
16308static struct hda_verb alc861vd_6stack_ch8_init[] = {
16309 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16310 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16311 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16312 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16313 { } /* end */
16314};
16315
16316static struct hda_channel_mode alc861vd_6stack_modes[2] = {
16317 { 6, alc861vd_6stack_ch6_init },
16318 { 8, alc861vd_6stack_ch8_init },
16319};
16320
16321static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16322 {
16323 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16324 .name = "Channel Mode",
16325 .info = alc_ch_mode_info,
16326 .get = alc_ch_mode_get,
16327 .put = alc_ch_mode_put,
16328 },
16329 { } /* end */
16330};
16331
f32610ed
JS
16332/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16333 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16334 */
16335static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16336 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16337 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16338
16339 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16340 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16341
16342 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16343 HDA_OUTPUT),
16344 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16345 HDA_OUTPUT),
16346 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16347 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16348
16349 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16350 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16351
16352 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16353
16354 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
16355 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16356 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16357
16358 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
16359 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16360 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16361
16362 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16363 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16364
16365 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16366 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16367
f32610ed
JS
16368 { } /* end */
16369};
16370
16371static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16372 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16373 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16374
16375 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16376
16377 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
16378 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16379 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16380
16381 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
16382 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16383 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16384
16385 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16386 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16387
16388 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16389 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16390
f32610ed
JS
16391 { } /* end */
16392};
16393
bdd148a3
KY
16394static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16395 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16396 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16397 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16398
16399 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16400
16401 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
16402 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16403 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16404
16405 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
16406 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16407 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16408
16409 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16410 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16411
16412 { } /* end */
16413};
16414
b419f346
TD
16415/* Pin assignment: Speaker=0x14, HP = 0x15,
16416 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
16417 */
16418static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16419 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16420 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16421 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16422 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
16423 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16424 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16425 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16426 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16427 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16428 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16429 { } /* end */
16430};
16431
d1a991a6
KY
16432/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16433 * Front Mic=0x18, ATAPI Mic = 0x19,
16434 */
16435static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16436 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16437 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16438 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16439 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16440 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16441 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16442 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16443 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16444
d1a991a6
KY
16445 { } /* end */
16446};
16447
f32610ed
JS
16448/*
16449 * generic initialization of ADC, input mixers and output mixers
16450 */
16451static struct hda_verb alc861vd_volume_init_verbs[] = {
16452 /*
16453 * Unmute ADC0 and set the default input to mic-in
16454 */
16455 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16456 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16457
16458 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16459 * the analog-loopback mixer widget
16460 */
16461 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16462 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16463 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16464 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16465 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16466 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16467
16468 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16469 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16470 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16471 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16472 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16473
16474 /*
16475 * Set up output mixers (0x02 - 0x05)
16476 */
16477 /* set vol=0 to output mixers */
16478 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16479 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16480 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16481 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16482
16483 /* set up input amps for analog loopback */
16484 /* Amp Indices: DAC = 0, mixer = 1 */
16485 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16486 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16487 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16488 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16489 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16490 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16491 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16492 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16493
16494 { }
16495};
16496
16497/*
16498 * 3-stack pin configuration:
16499 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16500 */
16501static struct hda_verb alc861vd_3stack_init_verbs[] = {
16502 /*
16503 * Set pin mode and muting
16504 */
16505 /* set front pin widgets 0x14 for output */
16506 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16507 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16508 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16509
16510 /* Mic (rear) pin: input vref at 80% */
16511 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16512 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16513 /* Front Mic pin: input vref at 80% */
16514 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16515 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16516 /* Line In pin: input */
16517 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16518 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16519 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16520 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16521 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16522 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16523 /* CD pin widget for input */
16524 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16525
16526 { }
16527};
16528
16529/*
16530 * 6-stack pin configuration:
16531 */
16532static struct hda_verb alc861vd_6stack_init_verbs[] = {
16533 /*
16534 * Set pin mode and muting
16535 */
16536 /* set front pin widgets 0x14 for output */
16537 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16538 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16539 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16540
16541 /* Rear Pin: output 1 (0x0d) */
16542 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16543 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16544 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16545 /* CLFE Pin: output 2 (0x0e) */
16546 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16547 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16548 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16549 /* Side Pin: output 3 (0x0f) */
16550 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16551 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16552 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16553
16554 /* Mic (rear) pin: input vref at 80% */
16555 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16556 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16557 /* Front Mic pin: input vref at 80% */
16558 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16559 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16560 /* Line In pin: input */
16561 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16562 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16563 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16564 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16565 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16566 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16567 /* CD pin widget for input */
16568 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16569
16570 { }
16571};
16572
bdd148a3
KY
16573static struct hda_verb alc861vd_eapd_verbs[] = {
16574 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16575 { }
16576};
16577
f9423e7a
KY
16578static struct hda_verb alc660vd_eapd_verbs[] = {
16579 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16580 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16581 { }
16582};
16583
bdd148a3
KY
16584static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16585 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16586 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16587 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16588 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16589 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16590 {}
16591};
16592
bdd148a3
KY
16593static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
16594{
16595 unsigned int present;
16596 unsigned char bits;
16597
864f92be 16598 present = snd_hda_jack_detect(codec, 0x18);
47fd830a 16599 bits = present ? HDA_AMP_MUTE : 0;
864f92be 16600
47fd830a
TI
16601 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
16602 HDA_AMP_MUTE, bits);
bdd148a3
KY
16603}
16604
4f5d1706 16605static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16606{
a9fd4f3f 16607 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16608 spec->autocfg.hp_pins[0] = 0x1b;
16609 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
16610}
16611
16612static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16613{
a9fd4f3f 16614 alc_automute_amp(codec);
bdd148a3
KY
16615 alc861vd_lenovo_mic_automute(codec);
16616}
16617
16618static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16619 unsigned int res)
16620{
16621 switch (res >> 26) {
bdd148a3
KY
16622 case ALC880_MIC_EVENT:
16623 alc861vd_lenovo_mic_automute(codec);
16624 break;
a9fd4f3f
TI
16625 default:
16626 alc_automute_amp_unsol_event(codec, res);
16627 break;
bdd148a3
KY
16628 }
16629}
16630
272a527c
KY
16631static struct hda_verb alc861vd_dallas_verbs[] = {
16632 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16633 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16634 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16635 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16636
16637 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16638 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16639 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16640 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16641 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16642 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16643 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16644 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16645
272a527c
KY
16646 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16647 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16648 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16649 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16650 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16651 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16652 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16653 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16654
16655 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16656 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16657 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16658 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16659 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16660 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16661 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16662 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16663
16664 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16665 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16666 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16667 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16668
16669 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16670 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16671 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16672
16673 { } /* end */
16674};
16675
16676/* toggle speaker-output according to the hp-jack state */
4f5d1706 16677static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16678{
a9fd4f3f 16679 struct alc_spec *spec = codec->spec;
272a527c 16680
a9fd4f3f
TI
16681 spec->autocfg.hp_pins[0] = 0x15;
16682 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
16683}
16684
cb53c626
TI
16685#ifdef CONFIG_SND_HDA_POWER_SAVE
16686#define alc861vd_loopbacks alc880_loopbacks
16687#endif
16688
def319f9 16689/* pcm configuration: identical with ALC880 */
f32610ed
JS
16690#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16691#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16692#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16693#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16694
16695/*
16696 * configuration and preset
16697 */
16698static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
16699 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16700 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16701 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16702 [ALC861VD_3ST] = "3stack",
16703 [ALC861VD_3ST_DIG] = "3stack-digout",
16704 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16705 [ALC861VD_LENOVO] = "lenovo",
272a527c 16706 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16707 [ALC861VD_HP] = "hp",
f32610ed
JS
16708 [ALC861VD_AUTO] = "auto",
16709};
16710
16711static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16712 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16713 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16714 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16715 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16716 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16717 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16718 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16719 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16720 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16721 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16722 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16723 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16724 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16725 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16726 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16727 {}
16728};
16729
16730static struct alc_config_preset alc861vd_presets[] = {
16731 [ALC660VD_3ST] = {
16732 .mixers = { alc861vd_3st_mixer },
16733 .init_verbs = { alc861vd_volume_init_verbs,
16734 alc861vd_3stack_init_verbs },
16735 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16736 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16737 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16738 .channel_mode = alc861vd_3stack_2ch_modes,
16739 .input_mux = &alc861vd_capture_source,
16740 },
6963f84c
MC
16741 [ALC660VD_3ST_DIG] = {
16742 .mixers = { alc861vd_3st_mixer },
16743 .init_verbs = { alc861vd_volume_init_verbs,
16744 alc861vd_3stack_init_verbs },
16745 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16746 .dac_nids = alc660vd_dac_nids,
16747 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16748 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16749 .channel_mode = alc861vd_3stack_2ch_modes,
16750 .input_mux = &alc861vd_capture_source,
16751 },
f32610ed
JS
16752 [ALC861VD_3ST] = {
16753 .mixers = { alc861vd_3st_mixer },
16754 .init_verbs = { alc861vd_volume_init_verbs,
16755 alc861vd_3stack_init_verbs },
16756 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16757 .dac_nids = alc861vd_dac_nids,
16758 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16759 .channel_mode = alc861vd_3stack_2ch_modes,
16760 .input_mux = &alc861vd_capture_source,
16761 },
16762 [ALC861VD_3ST_DIG] = {
16763 .mixers = { alc861vd_3st_mixer },
16764 .init_verbs = { alc861vd_volume_init_verbs,
16765 alc861vd_3stack_init_verbs },
16766 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16767 .dac_nids = alc861vd_dac_nids,
16768 .dig_out_nid = ALC861VD_DIGOUT_NID,
16769 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16770 .channel_mode = alc861vd_3stack_2ch_modes,
16771 .input_mux = &alc861vd_capture_source,
16772 },
16773 [ALC861VD_6ST_DIG] = {
16774 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16775 .init_verbs = { alc861vd_volume_init_verbs,
16776 alc861vd_6stack_init_verbs },
16777 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16778 .dac_nids = alc861vd_dac_nids,
16779 .dig_out_nid = ALC861VD_DIGOUT_NID,
16780 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16781 .channel_mode = alc861vd_6stack_modes,
16782 .input_mux = &alc861vd_capture_source,
16783 },
bdd148a3
KY
16784 [ALC861VD_LENOVO] = {
16785 .mixers = { alc861vd_lenovo_mixer },
16786 .init_verbs = { alc861vd_volume_init_verbs,
16787 alc861vd_3stack_init_verbs,
16788 alc861vd_eapd_verbs,
16789 alc861vd_lenovo_unsol_verbs },
16790 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16791 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16792 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16793 .channel_mode = alc861vd_3stack_2ch_modes,
16794 .input_mux = &alc861vd_capture_source,
16795 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16796 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16797 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16798 },
272a527c
KY
16799 [ALC861VD_DALLAS] = {
16800 .mixers = { alc861vd_dallas_mixer },
16801 .init_verbs = { alc861vd_dallas_verbs },
16802 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16803 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16804 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16805 .channel_mode = alc861vd_3stack_2ch_modes,
16806 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 16807 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16808 .setup = alc861vd_dallas_setup,
16809 .init_hook = alc_automute_amp,
d1a991a6
KY
16810 },
16811 [ALC861VD_HP] = {
16812 .mixers = { alc861vd_hp_mixer },
16813 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16814 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16815 .dac_nids = alc861vd_dac_nids,
d1a991a6 16816 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
16817 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16818 .channel_mode = alc861vd_3stack_2ch_modes,
16819 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 16820 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16821 .setup = alc861vd_dallas_setup,
16822 .init_hook = alc_automute_amp,
ea1fb29a 16823 },
13c94744
TI
16824 [ALC660VD_ASUS_V1S] = {
16825 .mixers = { alc861vd_lenovo_mixer },
16826 .init_verbs = { alc861vd_volume_init_verbs,
16827 alc861vd_3stack_init_verbs,
16828 alc861vd_eapd_verbs,
16829 alc861vd_lenovo_unsol_verbs },
16830 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16831 .dac_nids = alc660vd_dac_nids,
16832 .dig_out_nid = ALC861VD_DIGOUT_NID,
16833 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16834 .channel_mode = alc861vd_3stack_2ch_modes,
16835 .input_mux = &alc861vd_capture_source,
16836 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16837 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16838 .init_hook = alc861vd_lenovo_init_hook,
13c94744 16839 },
f32610ed
JS
16840};
16841
16842/*
16843 * BIOS auto configuration
16844 */
05f5f477
TI
16845static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16846 const struct auto_pin_cfg *cfg)
16847{
6227cdce 16848 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
05f5f477
TI
16849}
16850
16851
f32610ed
JS
16852static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
16853 hda_nid_t nid, int pin_type, int dac_idx)
16854{
f6c7e546 16855 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
16856}
16857
16858static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
16859{
16860 struct alc_spec *spec = codec->spec;
16861 int i;
16862
16863 for (i = 0; i <= HDA_SIDE; i++) {
16864 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16865 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
16866 if (nid)
16867 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 16868 pin_type, i);
f32610ed
JS
16869 }
16870}
16871
16872
16873static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
16874{
16875 struct alc_spec *spec = codec->spec;
16876 hda_nid_t pin;
16877
16878 pin = spec->autocfg.hp_pins[0];
def319f9 16879 if (pin) /* connect to front and use dac 0 */
f32610ed 16880 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
16881 pin = spec->autocfg.speaker_pins[0];
16882 if (pin)
16883 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
16884}
16885
f32610ed
JS
16886#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
16887
16888static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
16889{
16890 struct alc_spec *spec = codec->spec;
66ceeb6b 16891 struct auto_pin_cfg *cfg = &spec->autocfg;
f32610ed
JS
16892 int i;
16893
66ceeb6b
TI
16894 for (i = 0; i < cfg->num_inputs; i++) {
16895 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 16896 if (alc_is_input_pin(codec, nid)) {
30ea098f 16897 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
16898 if (nid != ALC861VD_PIN_CD_NID &&
16899 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
16900 snd_hda_codec_write(codec, nid, 0,
16901 AC_VERB_SET_AMP_GAIN_MUTE,
16902 AMP_OUT_MUTE);
16903 }
16904 }
16905}
16906
f511b01c
TI
16907#define alc861vd_auto_init_input_src alc882_auto_init_input_src
16908
f32610ed
JS
16909#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16910#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16911
16912/* add playback controls from the parsed DAC table */
16913/* Based on ALC880 version. But ALC861VD has separate,
16914 * different NIDs for mute/unmute switch and volume control */
16915static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16916 const struct auto_pin_cfg *cfg)
16917{
f32610ed
JS
16918 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
16919 hda_nid_t nid_v, nid_s;
16920 int i, err;
16921
16922 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 16923 if (!spec->multiout.dac_nids[i])
f32610ed
JS
16924 continue;
16925 nid_v = alc861vd_idx_to_mixer_vol(
16926 alc880_dac_to_idx(
16927 spec->multiout.dac_nids[i]));
16928 nid_s = alc861vd_idx_to_mixer_switch(
16929 alc880_dac_to_idx(
16930 spec->multiout.dac_nids[i]));
16931
16932 if (i == 2) {
16933 /* Center/LFE */
0afe5f89
TI
16934 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16935 "Center",
f12ab1e0
TI
16936 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16937 HDA_OUTPUT));
16938 if (err < 0)
f32610ed 16939 return err;
0afe5f89
TI
16940 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16941 "LFE",
f12ab1e0
TI
16942 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16943 HDA_OUTPUT));
16944 if (err < 0)
f32610ed 16945 return err;
0afe5f89
TI
16946 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16947 "Center",
f12ab1e0
TI
16948 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
16949 HDA_INPUT));
16950 if (err < 0)
f32610ed 16951 return err;
0afe5f89
TI
16952 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16953 "LFE",
f12ab1e0
TI
16954 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
16955 HDA_INPUT));
16956 if (err < 0)
f32610ed
JS
16957 return err;
16958 } else {
a4fcd491
TI
16959 const char *pfx;
16960 if (cfg->line_outs == 1 &&
16961 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
16962 if (!cfg->hp_pins)
16963 pfx = "Speaker";
16964 else
16965 pfx = "PCM";
16966 } else
16967 pfx = chname[i];
0afe5f89 16968 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16969 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16970 HDA_OUTPUT));
16971 if (err < 0)
f32610ed 16972 return err;
a4fcd491
TI
16973 if (cfg->line_outs == 1 &&
16974 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
16975 pfx = "Speaker";
0afe5f89 16976 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
bdd148a3 16977 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
16978 HDA_INPUT));
16979 if (err < 0)
f32610ed
JS
16980 return err;
16981 }
16982 }
16983 return 0;
16984}
16985
16986/* add playback controls for speaker and HP outputs */
16987/* Based on ALC880 version. But ALC861VD has separate,
16988 * different NIDs for mute/unmute switch and volume control */
16989static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16990 hda_nid_t pin, const char *pfx)
16991{
16992 hda_nid_t nid_v, nid_s;
16993 int err;
f32610ed 16994
f12ab1e0 16995 if (!pin)
f32610ed
JS
16996 return 0;
16997
16998 if (alc880_is_fixed_pin(pin)) {
16999 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17000 /* specify the DAC as the extra output */
f12ab1e0 17001 if (!spec->multiout.hp_nid)
f32610ed
JS
17002 spec->multiout.hp_nid = nid_v;
17003 else
17004 spec->multiout.extra_out_nid[0] = nid_v;
17005 /* control HP volume/switch on the output mixer amp */
17006 nid_v = alc861vd_idx_to_mixer_vol(
17007 alc880_fixed_pin_idx(pin));
17008 nid_s = alc861vd_idx_to_mixer_switch(
17009 alc880_fixed_pin_idx(pin));
17010
0afe5f89 17011 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17012 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17013 if (err < 0)
f32610ed 17014 return err;
0afe5f89 17015 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17016 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17017 if (err < 0)
f32610ed
JS
17018 return err;
17019 } else if (alc880_is_multi_pin(pin)) {
17020 /* set manual connection */
17021 /* we have only a switch on HP-out PIN */
0afe5f89 17022 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17023 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17024 if (err < 0)
f32610ed
JS
17025 return err;
17026 }
17027 return 0;
17028}
17029
17030/* parse the BIOS configuration and set up the alc_spec
17031 * return 1 if successful, 0 if the proper config is not found,
17032 * or a negative error code
17033 * Based on ALC880 version - had to change it to override
17034 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17035static int alc861vd_parse_auto_config(struct hda_codec *codec)
17036{
17037 struct alc_spec *spec = codec->spec;
17038 int err;
17039 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17040
f12ab1e0
TI
17041 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17042 alc861vd_ignore);
17043 if (err < 0)
f32610ed 17044 return err;
f12ab1e0 17045 if (!spec->autocfg.line_outs)
f32610ed
JS
17046 return 0; /* can't find valid BIOS pin config */
17047
f12ab1e0
TI
17048 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17049 if (err < 0)
17050 return err;
17051 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17052 if (err < 0)
17053 return err;
17054 err = alc861vd_auto_create_extra_out(spec,
17055 spec->autocfg.speaker_pins[0],
17056 "Speaker");
17057 if (err < 0)
17058 return err;
17059 err = alc861vd_auto_create_extra_out(spec,
17060 spec->autocfg.hp_pins[0],
17061 "Headphone");
17062 if (err < 0)
17063 return err;
05f5f477 17064 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17065 if (err < 0)
f32610ed
JS
17066 return err;
17067
17068 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17069
757899ac 17070 alc_auto_parse_digital(codec);
f32610ed 17071
603c4019 17072 if (spec->kctls.list)
d88897ea 17073 add_mixer(spec, spec->kctls.list);
f32610ed 17074
d88897ea 17075 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
17076
17077 spec->num_mux_defs = 1;
61b9b9b1 17078 spec->input_mux = &spec->private_imux[0];
f32610ed 17079
776e184e
TI
17080 err = alc_auto_add_mic_boost(codec);
17081 if (err < 0)
17082 return err;
17083
6227cdce 17084 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17085
f32610ed
JS
17086 return 1;
17087}
17088
17089/* additional initialization for auto-configuration model */
17090static void alc861vd_auto_init(struct hda_codec *codec)
17091{
f6c7e546 17092 struct alc_spec *spec = codec->spec;
f32610ed
JS
17093 alc861vd_auto_init_multi_out(codec);
17094 alc861vd_auto_init_hp_out(codec);
17095 alc861vd_auto_init_analog_input(codec);
f511b01c 17096 alc861vd_auto_init_input_src(codec);
757899ac 17097 alc_auto_init_digital(codec);
f6c7e546 17098 if (spec->unsol_event)
7fb0d78f 17099 alc_inithook(codec);
f32610ed
JS
17100}
17101
f8f25ba3
TI
17102enum {
17103 ALC660VD_FIX_ASUS_GPIO1
17104};
17105
17106/* reset GPIO1 */
f8f25ba3
TI
17107static const struct alc_fixup alc861vd_fixups[] = {
17108 [ALC660VD_FIX_ASUS_GPIO1] = {
73413b12
TI
17109 .verbs = (const struct hda_verb[]) {
17110 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17111 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17112 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17113 { }
17114 }
f8f25ba3
TI
17115 },
17116};
17117
17118static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17119 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17120 {}
17121};
17122
f32610ed
JS
17123static int patch_alc861vd(struct hda_codec *codec)
17124{
17125 struct alc_spec *spec;
17126 int err, board_config;
17127
17128 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17129 if (spec == NULL)
17130 return -ENOMEM;
17131
17132 codec->spec = spec;
17133
17134 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17135 alc861vd_models,
17136 alc861vd_cfg_tbl);
17137
17138 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17139 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17140 codec->chip_name);
f32610ed
JS
17141 board_config = ALC861VD_AUTO;
17142 }
17143
7fa90e87
TI
17144 if (board_config == ALC861VD_AUTO)
17145 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
f8f25ba3 17146
f32610ed
JS
17147 if (board_config == ALC861VD_AUTO) {
17148 /* automatic parse from the BIOS config */
17149 err = alc861vd_parse_auto_config(codec);
17150 if (err < 0) {
17151 alc_free(codec);
17152 return err;
f12ab1e0 17153 } else if (!err) {
f32610ed
JS
17154 printk(KERN_INFO
17155 "hda_codec: Cannot set up configuration "
17156 "from BIOS. Using base mode...\n");
17157 board_config = ALC861VD_3ST;
17158 }
17159 }
17160
680cd536
KK
17161 err = snd_hda_attach_beep_device(codec, 0x23);
17162 if (err < 0) {
17163 alc_free(codec);
17164 return err;
17165 }
17166
f32610ed 17167 if (board_config != ALC861VD_AUTO)
e9c364c0 17168 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17169
2f893286 17170 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17171 /* always turn on EAPD */
d88897ea 17172 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17173 }
17174
f32610ed
JS
17175 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17176 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17177
f32610ed
JS
17178 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17179 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17180
dd704698
TI
17181 if (!spec->adc_nids) {
17182 spec->adc_nids = alc861vd_adc_nids;
17183 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17184 }
17185 if (!spec->capsrc_nids)
17186 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17187
b59bdf3b 17188 set_capture_mixer(codec);
45bdd1c1 17189 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17190
2134ea4f
TI
17191 spec->vmaster_nid = 0x02;
17192
7fa90e87
TI
17193 if (board_config == ALC861VD_AUTO)
17194 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
17195
f32610ed
JS
17196 codec->patch_ops = alc_patch_ops;
17197
17198 if (board_config == ALC861VD_AUTO)
17199 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
17200#ifdef CONFIG_SND_HDA_POWER_SAVE
17201 if (!spec->loopback.amplist)
17202 spec->loopback.amplist = alc861vd_loopbacks;
17203#endif
f32610ed
JS
17204
17205 return 0;
17206}
17207
bc9f98a9
KY
17208/*
17209 * ALC662 support
17210 *
17211 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17212 * configuration. Each pin widget can choose any input DACs and a mixer.
17213 * Each ADC is connected from a mixer of all inputs. This makes possible
17214 * 6-channel independent captures.
17215 *
17216 * In addition, an independent DAC for the multi-playback (not used in this
17217 * driver yet).
17218 */
17219#define ALC662_DIGOUT_NID 0x06
17220#define ALC662_DIGIN_NID 0x0a
17221
17222static hda_nid_t alc662_dac_nids[4] = {
17223 /* front, rear, clfe, rear_surr */
17224 0x02, 0x03, 0x04
17225};
17226
622e84cd
KY
17227static hda_nid_t alc272_dac_nids[2] = {
17228 0x02, 0x03
17229};
17230
b59bdf3b 17231static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17232 /* ADC1-2 */
b59bdf3b 17233 0x09, 0x08
bc9f98a9 17234};
e1406348 17235
622e84cd
KY
17236static hda_nid_t alc272_adc_nids[1] = {
17237 /* ADC1-2 */
17238 0x08,
17239};
17240
b59bdf3b 17241static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
17242static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17243
e1406348 17244
bc9f98a9
KY
17245/* input MUX */
17246/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
17247static struct hda_input_mux alc662_capture_source = {
17248 .num_items = 4,
17249 .items = {
17250 { "Mic", 0x0 },
17251 { "Front Mic", 0x1 },
17252 { "Line", 0x2 },
17253 { "CD", 0x4 },
17254 },
17255};
17256
17257static struct hda_input_mux alc662_lenovo_101e_capture_source = {
17258 .num_items = 2,
17259 .items = {
17260 { "Mic", 0x1 },
17261 { "Line", 0x2 },
17262 },
17263};
291702f0 17264
6dda9f4a
KY
17265static struct hda_input_mux alc663_capture_source = {
17266 .num_items = 3,
17267 .items = {
17268 { "Mic", 0x0 },
17269 { "Front Mic", 0x1 },
17270 { "Line", 0x2 },
17271 },
17272};
17273
4f5d1706 17274#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
17275static struct hda_input_mux alc272_nc10_capture_source = {
17276 .num_items = 16,
17277 .items = {
17278 { "Autoselect Mic", 0x0 },
17279 { "Internal Mic", 0x1 },
17280 { "In-0x02", 0x2 },
17281 { "In-0x03", 0x3 },
17282 { "In-0x04", 0x4 },
17283 { "In-0x05", 0x5 },
17284 { "In-0x06", 0x6 },
17285 { "In-0x07", 0x7 },
17286 { "In-0x08", 0x8 },
17287 { "In-0x09", 0x9 },
17288 { "In-0x0a", 0x0a },
17289 { "In-0x0b", 0x0b },
17290 { "In-0x0c", 0x0c },
17291 { "In-0x0d", 0x0d },
17292 { "In-0x0e", 0x0e },
17293 { "In-0x0f", 0x0f },
17294 },
17295};
17296#endif
17297
bc9f98a9
KY
17298/*
17299 * 2ch mode
17300 */
17301static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17302 { 2, NULL }
17303};
17304
17305/*
17306 * 2ch mode
17307 */
17308static struct hda_verb alc662_3ST_ch2_init[] = {
17309 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17310 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17311 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17312 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17313 { } /* end */
17314};
17315
17316/*
17317 * 6ch mode
17318 */
17319static struct hda_verb alc662_3ST_ch6_init[] = {
17320 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17321 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17322 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17323 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17324 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17325 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17326 { } /* end */
17327};
17328
17329static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17330 { 2, alc662_3ST_ch2_init },
17331 { 6, alc662_3ST_ch6_init },
17332};
17333
17334/*
17335 * 2ch mode
17336 */
17337static struct hda_verb alc662_sixstack_ch6_init[] = {
17338 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17339 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17340 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17341 { } /* end */
17342};
17343
17344/*
17345 * 6ch mode
17346 */
17347static struct hda_verb alc662_sixstack_ch8_init[] = {
17348 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17349 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17350 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17351 { } /* end */
17352};
17353
17354static struct hda_channel_mode alc662_5stack_modes[2] = {
17355 { 2, alc662_sixstack_ch6_init },
17356 { 6, alc662_sixstack_ch8_init },
17357};
17358
17359/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17360 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17361 */
17362
17363static struct snd_kcontrol_new alc662_base_mixer[] = {
17364 /* output mixer control */
17365 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17366 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17367 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17368 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17369 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17370 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17371 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17372 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17373 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17374
17375 /*Input mixer control */
17376 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17377 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17378 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17379 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17380 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17381 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17382 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17383 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17384 { } /* end */
17385};
17386
17387static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17388 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17389 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17390 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17391 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17392 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17393 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17394 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17395 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17396 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17397 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17398 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17399 { } /* end */
17400};
17401
17402static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17403 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17404 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17405 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17406 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17407 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17408 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17409 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17410 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17411 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17412 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17413 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17414 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17415 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17416 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17417 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17418 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17419 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17420 { } /* end */
17421};
17422
17423static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17424 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17425 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17426 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17427 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17428 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17429 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17430 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17431 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17432 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17433 { } /* end */
17434};
17435
291702f0 17436static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17437 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17438 ALC262_HIPPO_MASTER_SWITCH,
291702f0
KY
17439
17440 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
17441 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17442 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17443
17444 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
17445 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17446 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17447 { } /* end */
17448};
17449
8c427226 17450static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17451 ALC262_HIPPO_MASTER_SWITCH,
17452 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17453 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17454 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17455 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17456 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17457 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17458 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17459 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17460 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17461 { } /* end */
17462};
17463
f1d4e28b
KY
17464static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17465 .ops = &snd_hda_bind_vol,
17466 .values = {
17467 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17468 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17469 0
17470 },
17471};
17472
17473static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17474 .ops = &snd_hda_bind_sw,
17475 .values = {
17476 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17477 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17478 0
17479 },
17480};
17481
6dda9f4a 17482static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17483 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17484 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17485 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17486 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17487 { } /* end */
17488};
17489
17490static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17491 .ops = &snd_hda_bind_sw,
17492 .values = {
17493 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17494 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17495 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17496 0
17497 },
17498};
17499
17500static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17501 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17502 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17503 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17504 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17505 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17506 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17507
17508 { } /* end */
17509};
17510
17511static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17512 .ops = &snd_hda_bind_sw,
17513 .values = {
17514 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17515 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17516 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17517 0
17518 },
17519};
17520
17521static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17522 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17523 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17524 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17525 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17526 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17527 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17528 { } /* end */
17529};
17530
17531static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17532 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17533 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17534 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17535 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17536 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17537 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17538 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17539 { } /* end */
17540};
17541
17542static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17543 .ops = &snd_hda_bind_vol,
17544 .values = {
17545 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17546 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17547 0
17548 },
17549};
17550
17551static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17552 .ops = &snd_hda_bind_sw,
17553 .values = {
17554 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17555 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17556 0
17557 },
17558};
17559
17560static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17561 HDA_BIND_VOL("Master Playback Volume",
17562 &alc663_asus_two_bind_master_vol),
17563 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17564 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17565 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17566 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17567 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17568 { } /* end */
17569};
17570
17571static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17572 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17573 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17574 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17575 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17576 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17577 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17578 { } /* end */
17579};
17580
17581static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17582 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17583 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17584 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17585 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17586 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17587
17588 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17589 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17590 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17591 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17592 { } /* end */
17593};
17594
17595static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17596 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17597 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17598 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17599
17600 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17601 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17602 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17603 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17604 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17605 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17606 { } /* end */
17607};
17608
ebb83eeb
KY
17609static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17610 .ops = &snd_hda_bind_sw,
17611 .values = {
17612 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17613 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17614 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17615 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17616 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17617 0
17618 },
17619};
17620
17621static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17622 .ops = &snd_hda_bind_sw,
17623 .values = {
17624 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17625 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17626 0
17627 },
17628};
17629
17630static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17631 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17632 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17633 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17634 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17635 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17636 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17637 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17638 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17639 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17640 { } /* end */
17641};
17642
17643static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17644 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17645 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17646 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17647 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17648 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17649 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17650 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17651 { } /* end */
17652};
17653
17654
bc9f98a9
KY
17655static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17656 {
17657 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17658 .name = "Channel Mode",
17659 .info = alc_ch_mode_info,
17660 .get = alc_ch_mode_get,
17661 .put = alc_ch_mode_put,
17662 },
17663 { } /* end */
17664};
17665
17666static struct hda_verb alc662_init_verbs[] = {
17667 /* ADC: mute amp left and right */
17668 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17669 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17670
b60dd394
KY
17671 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17672 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17673 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17674 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17675 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17676 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17677
17678 /* Front Pin: output 0 (0x0c) */
17679 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17680 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17681
17682 /* Rear Pin: output 1 (0x0d) */
17683 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17684 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17685
17686 /* CLFE Pin: output 2 (0x0e) */
17687 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17688 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17689
17690 /* Mic (rear) pin: input vref at 80% */
17691 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17692 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17693 /* Front Mic pin: input vref at 80% */
17694 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17695 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17696 /* Line In pin: input */
17697 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17698 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17699 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17700 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17701 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17702 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17703 /* CD pin widget for input */
17704 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17705
17706 /* FIXME: use matrix-type input source selection */
17707 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17708 /* Input mixer */
17709 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17710 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
17711
17712 /* always trun on EAPD */
17713 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17714 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17715
bc9f98a9
KY
17716 { }
17717};
17718
cec27c89
KY
17719static struct hda_verb alc663_init_verbs[] = {
17720 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17721 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17722 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17723 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17724 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17725 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17726 { }
17727};
17728
17729static struct hda_verb alc272_init_verbs[] = {
17730 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17731 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17732 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17733 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17734 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17735 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17736 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17737 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17738 { }
17739};
17740
bc9f98a9
KY
17741static struct hda_verb alc662_sue_init_verbs[] = {
17742 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17743 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17744 {}
17745};
17746
17747static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17748 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17749 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17750 {}
bc9f98a9
KY
17751};
17752
8c427226
KY
17753/* Set Unsolicited Event*/
17754static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17755 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17756 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17757 {}
17758};
17759
6dda9f4a 17760static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17761 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17762 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17763 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17764 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17765 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17766 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17767 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17768 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17769 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17770 {}
17771};
17772
17773static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17774 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17775 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17776 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17777 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17778 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17779 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17780 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17781 {}
17782};
17783
17784static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17785 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17786 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17787 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17788 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17789 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17790 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17791 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17792 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17793 {}
17794};
6dda9f4a 17795
f1d4e28b
KY
17796static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17797 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17798 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17799 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17800 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17801 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17802 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17803 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17804 {}
17805};
6dda9f4a 17806
f1d4e28b
KY
17807static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17808 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17809 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17810 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17811 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17812 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17813 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17814 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17815 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17816 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
17817 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17818 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
17819 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17820 {}
17821};
17822
17823static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17824 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17825 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17826 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17827 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17828 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17829 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17830 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17831 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17832 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17833 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17834 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17835 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
17836 {}
17837};
17838
17839static struct hda_verb alc663_g71v_init_verbs[] = {
17840 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17841 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17842 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17843
17844 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17845 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17846 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17847
17848 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17849 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17850 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17851 {}
17852};
17853
17854static struct hda_verb alc663_g50v_init_verbs[] = {
17855 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17856 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17857 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17858
17859 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17860 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17861 {}
17862};
17863
f1d4e28b
KY
17864static struct hda_verb alc662_ecs_init_verbs[] = {
17865 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17866 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17867 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17868 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17869 {}
17870};
17871
622e84cd
KY
17872static struct hda_verb alc272_dell_zm1_init_verbs[] = {
17873 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17874 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17875 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17876 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17877 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17878 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17879 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17880 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17881 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17882 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17883 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17884 {}
17885};
17886
17887static struct hda_verb alc272_dell_init_verbs[] = {
17888 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17889 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17890 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17891 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17892 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17893 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17894 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17895 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17896 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17897 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17898 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17899 {}
17900};
17901
ebb83eeb
KY
17902static struct hda_verb alc663_mode7_init_verbs[] = {
17903 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17904 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17905 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17906 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17907 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17908 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17909 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17910 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17911 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17912 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17913 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17914 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17915 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17916 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17917 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17918 {}
17919};
17920
17921static struct hda_verb alc663_mode8_init_verbs[] = {
17922 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17923 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17924 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17925 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17926 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17927 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17928 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17929 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17930 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17931 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17932 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17933 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17934 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17935 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17936 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17937 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17938 {}
17939};
17940
f1d4e28b
KY
17941static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17942 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17943 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17944 { } /* end */
17945};
17946
622e84cd
KY
17947static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17948 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17949 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17950 { } /* end */
17951};
17952
bc9f98a9
KY
17953static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
17954{
17955 unsigned int present;
f12ab1e0 17956 unsigned char bits;
bc9f98a9 17957
864f92be 17958 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 17959 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17960
47fd830a
TI
17961 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17962 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17963}
17964
17965static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
17966{
17967 unsigned int present;
f12ab1e0 17968 unsigned char bits;
bc9f98a9 17969
864f92be 17970 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 17971 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17972
47fd830a
TI
17973 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17974 HDA_AMP_MUTE, bits);
17975 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17976 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17977}
17978
17979static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
17980 unsigned int res)
17981{
17982 if ((res >> 26) == ALC880_HP_EVENT)
17983 alc662_lenovo_101e_all_automute(codec);
17984 if ((res >> 26) == ALC880_FRONT_EVENT)
17985 alc662_lenovo_101e_ispeaker_automute(codec);
17986}
17987
291702f0
KY
17988/* unsolicited event for HP jack sensing */
17989static void alc662_eeepc_unsol_event(struct hda_codec *codec,
17990 unsigned int res)
17991{
291702f0 17992 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 17993 alc_mic_automute(codec);
42171c17
TI
17994 else
17995 alc262_hippo_unsol_event(codec, res);
291702f0
KY
17996}
17997
4f5d1706
TI
17998static void alc662_eeepc_setup(struct hda_codec *codec)
17999{
18000 struct alc_spec *spec = codec->spec;
18001
18002 alc262_hippo1_setup(codec);
18003 spec->ext_mic.pin = 0x18;
18004 spec->ext_mic.mux_idx = 0;
18005 spec->int_mic.pin = 0x19;
18006 spec->int_mic.mux_idx = 1;
18007 spec->auto_mic = 1;
18008}
18009
291702f0
KY
18010static void alc662_eeepc_inithook(struct hda_codec *codec)
18011{
4f5d1706
TI
18012 alc262_hippo_automute(codec);
18013 alc_mic_automute(codec);
291702f0
KY
18014}
18015
4f5d1706 18016static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18017{
42171c17
TI
18018 struct alc_spec *spec = codec->spec;
18019
18020 spec->autocfg.hp_pins[0] = 0x14;
18021 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
18022}
18023
4f5d1706
TI
18024#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
18025
6dda9f4a
KY
18026static void alc663_m51va_speaker_automute(struct hda_codec *codec)
18027{
18028 unsigned int present;
18029 unsigned char bits;
18030
864f92be 18031 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 18032 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 18033 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18034 HDA_AMP_MUTE, bits);
f1d4e28b 18035 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18036 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18037}
18038
18039static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
18040{
18041 unsigned int present;
18042 unsigned char bits;
18043
864f92be 18044 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
18045 bits = present ? HDA_AMP_MUTE : 0;
18046 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18047 HDA_AMP_MUTE, bits);
f1d4e28b 18048 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18049 HDA_AMP_MUTE, bits);
f1d4e28b 18050 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18051 HDA_AMP_MUTE, bits);
f1d4e28b 18052 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18053 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18054}
18055
18056static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
18057{
18058 unsigned int present;
18059 unsigned char bits;
18060
864f92be 18061 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18062 bits = present ? HDA_AMP_MUTE : 0;
18063 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18064 HDA_AMP_MUTE, bits);
f1d4e28b 18065 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18066 HDA_AMP_MUTE, bits);
f1d4e28b 18067 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 18068 HDA_AMP_MUTE, bits);
f1d4e28b 18069 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 18070 HDA_AMP_MUTE, bits);
f1d4e28b
KY
18071}
18072
18073static void alc662_f5z_speaker_automute(struct hda_codec *codec)
18074{
18075 unsigned int present;
18076 unsigned char bits;
18077
864f92be 18078 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
18079 bits = present ? 0 : PIN_OUT;
18080 snd_hda_codec_write(codec, 0x14, 0,
18081 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
18082}
18083
18084static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
18085{
18086 unsigned int present1, present2;
18087
864f92be
WF
18088 present1 = snd_hda_jack_detect(codec, 0x21);
18089 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18090
18091 if (present1 || present2) {
18092 snd_hda_codec_write_cache(codec, 0x14, 0,
18093 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18094 } else {
18095 snd_hda_codec_write_cache(codec, 0x14, 0,
18096 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18097 }
18098}
18099
18100static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
18101{
18102 unsigned int present1, present2;
18103
864f92be
WF
18104 present1 = snd_hda_jack_detect(codec, 0x1b);
18105 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
18106
18107 if (present1 || present2) {
18108 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18109 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 18110 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18111 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
18112 } else {
18113 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 18114 HDA_AMP_MUTE, 0);
f1d4e28b 18115 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 18116 HDA_AMP_MUTE, 0);
f1d4e28b 18117 }
6dda9f4a
KY
18118}
18119
ebb83eeb
KY
18120static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
18121{
18122 unsigned int present1, present2;
18123
18124 present1 = snd_hda_codec_read(codec, 0x1b, 0,
18125 AC_VERB_GET_PIN_SENSE, 0)
18126 & AC_PINSENSE_PRESENCE;
18127 present2 = snd_hda_codec_read(codec, 0x21, 0,
18128 AC_VERB_GET_PIN_SENSE, 0)
18129 & AC_PINSENSE_PRESENCE;
18130
18131 if (present1 || present2) {
18132 snd_hda_codec_write_cache(codec, 0x14, 0,
18133 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18134 snd_hda_codec_write_cache(codec, 0x17, 0,
18135 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18136 } else {
18137 snd_hda_codec_write_cache(codec, 0x14, 0,
18138 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18139 snd_hda_codec_write_cache(codec, 0x17, 0,
18140 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18141 }
18142}
18143
18144static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
18145{
18146 unsigned int present1, present2;
18147
18148 present1 = snd_hda_codec_read(codec, 0x21, 0,
18149 AC_VERB_GET_PIN_SENSE, 0)
18150 & AC_PINSENSE_PRESENCE;
18151 present2 = snd_hda_codec_read(codec, 0x15, 0,
18152 AC_VERB_GET_PIN_SENSE, 0)
18153 & AC_PINSENSE_PRESENCE;
18154
18155 if (present1 || present2) {
18156 snd_hda_codec_write_cache(codec, 0x14, 0,
18157 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18158 snd_hda_codec_write_cache(codec, 0x17, 0,
18159 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18160 } else {
18161 snd_hda_codec_write_cache(codec, 0x14, 0,
18162 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18163 snd_hda_codec_write_cache(codec, 0x17, 0,
18164 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18165 }
18166}
18167
6dda9f4a
KY
18168static void alc663_m51va_unsol_event(struct hda_codec *codec,
18169 unsigned int res)
18170{
18171 switch (res >> 26) {
18172 case ALC880_HP_EVENT:
18173 alc663_m51va_speaker_automute(codec);
18174 break;
18175 case ALC880_MIC_EVENT:
4f5d1706 18176 alc_mic_automute(codec);
6dda9f4a
KY
18177 break;
18178 }
18179}
18180
4f5d1706
TI
18181static void alc663_m51va_setup(struct hda_codec *codec)
18182{
18183 struct alc_spec *spec = codec->spec;
18184 spec->ext_mic.pin = 0x18;
18185 spec->ext_mic.mux_idx = 0;
18186 spec->int_mic.pin = 0x12;
ebb83eeb 18187 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18188 spec->auto_mic = 1;
18189}
18190
6dda9f4a
KY
18191static void alc663_m51va_inithook(struct hda_codec *codec)
18192{
18193 alc663_m51va_speaker_automute(codec);
4f5d1706 18194 alc_mic_automute(codec);
6dda9f4a
KY
18195}
18196
f1d4e28b 18197/* ***************** Mode1 ******************************/
4f5d1706 18198#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
18199
18200static void alc663_mode1_setup(struct hda_codec *codec)
18201{
18202 struct alc_spec *spec = codec->spec;
18203 spec->ext_mic.pin = 0x18;
18204 spec->ext_mic.mux_idx = 0;
18205 spec->int_mic.pin = 0x19;
18206 spec->int_mic.mux_idx = 1;
18207 spec->auto_mic = 1;
18208}
18209
4f5d1706 18210#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 18211
f1d4e28b
KY
18212/* ***************** Mode2 ******************************/
18213static void alc662_mode2_unsol_event(struct hda_codec *codec,
18214 unsigned int res)
18215{
18216 switch (res >> 26) {
18217 case ALC880_HP_EVENT:
18218 alc662_f5z_speaker_automute(codec);
18219 break;
18220 case ALC880_MIC_EVENT:
4f5d1706 18221 alc_mic_automute(codec);
f1d4e28b
KY
18222 break;
18223 }
18224}
18225
ebb83eeb 18226#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 18227
f1d4e28b
KY
18228static void alc662_mode2_inithook(struct hda_codec *codec)
18229{
18230 alc662_f5z_speaker_automute(codec);
4f5d1706 18231 alc_mic_automute(codec);
f1d4e28b
KY
18232}
18233/* ***************** Mode3 ******************************/
18234static void alc663_mode3_unsol_event(struct hda_codec *codec,
18235 unsigned int res)
18236{
18237 switch (res >> 26) {
18238 case ALC880_HP_EVENT:
18239 alc663_two_hp_m1_speaker_automute(codec);
18240 break;
18241 case ALC880_MIC_EVENT:
4f5d1706 18242 alc_mic_automute(codec);
f1d4e28b
KY
18243 break;
18244 }
18245}
18246
ebb83eeb 18247#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 18248
f1d4e28b
KY
18249static void alc663_mode3_inithook(struct hda_codec *codec)
18250{
18251 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 18252 alc_mic_automute(codec);
f1d4e28b
KY
18253}
18254/* ***************** Mode4 ******************************/
18255static void alc663_mode4_unsol_event(struct hda_codec *codec,
18256 unsigned int res)
18257{
18258 switch (res >> 26) {
18259 case ALC880_HP_EVENT:
18260 alc663_21jd_two_speaker_automute(codec);
18261 break;
18262 case ALC880_MIC_EVENT:
4f5d1706 18263 alc_mic_automute(codec);
f1d4e28b
KY
18264 break;
18265 }
18266}
18267
ebb83eeb 18268#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 18269
f1d4e28b
KY
18270static void alc663_mode4_inithook(struct hda_codec *codec)
18271{
18272 alc663_21jd_two_speaker_automute(codec);
4f5d1706 18273 alc_mic_automute(codec);
f1d4e28b
KY
18274}
18275/* ***************** Mode5 ******************************/
18276static void alc663_mode5_unsol_event(struct hda_codec *codec,
18277 unsigned int res)
18278{
18279 switch (res >> 26) {
18280 case ALC880_HP_EVENT:
18281 alc663_15jd_two_speaker_automute(codec);
18282 break;
18283 case ALC880_MIC_EVENT:
4f5d1706 18284 alc_mic_automute(codec);
f1d4e28b
KY
18285 break;
18286 }
18287}
18288
ebb83eeb 18289#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 18290
f1d4e28b
KY
18291static void alc663_mode5_inithook(struct hda_codec *codec)
18292{
18293 alc663_15jd_two_speaker_automute(codec);
4f5d1706 18294 alc_mic_automute(codec);
f1d4e28b
KY
18295}
18296/* ***************** Mode6 ******************************/
18297static void alc663_mode6_unsol_event(struct hda_codec *codec,
18298 unsigned int res)
18299{
18300 switch (res >> 26) {
18301 case ALC880_HP_EVENT:
18302 alc663_two_hp_m2_speaker_automute(codec);
18303 break;
18304 case ALC880_MIC_EVENT:
4f5d1706 18305 alc_mic_automute(codec);
f1d4e28b
KY
18306 break;
18307 }
18308}
18309
ebb83eeb 18310#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 18311
f1d4e28b
KY
18312static void alc663_mode6_inithook(struct hda_codec *codec)
18313{
18314 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 18315 alc_mic_automute(codec);
f1d4e28b
KY
18316}
18317
ebb83eeb
KY
18318/* ***************** Mode7 ******************************/
18319static void alc663_mode7_unsol_event(struct hda_codec *codec,
18320 unsigned int res)
18321{
18322 switch (res >> 26) {
18323 case ALC880_HP_EVENT:
18324 alc663_two_hp_m7_speaker_automute(codec);
18325 break;
18326 case ALC880_MIC_EVENT:
18327 alc_mic_automute(codec);
18328 break;
18329 }
18330}
18331
18332#define alc663_mode7_setup alc663_mode1_setup
18333
18334static void alc663_mode7_inithook(struct hda_codec *codec)
18335{
18336 alc663_two_hp_m7_speaker_automute(codec);
18337 alc_mic_automute(codec);
18338}
18339
18340/* ***************** Mode8 ******************************/
18341static void alc663_mode8_unsol_event(struct hda_codec *codec,
18342 unsigned int res)
18343{
18344 switch (res >> 26) {
18345 case ALC880_HP_EVENT:
18346 alc663_two_hp_m8_speaker_automute(codec);
18347 break;
18348 case ALC880_MIC_EVENT:
18349 alc_mic_automute(codec);
18350 break;
18351 }
18352}
18353
18354#define alc663_mode8_setup alc663_m51va_setup
18355
18356static void alc663_mode8_inithook(struct hda_codec *codec)
18357{
18358 alc663_two_hp_m8_speaker_automute(codec);
18359 alc_mic_automute(codec);
18360}
18361
6dda9f4a
KY
18362static void alc663_g71v_hp_automute(struct hda_codec *codec)
18363{
18364 unsigned int present;
18365 unsigned char bits;
18366
864f92be 18367 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
18368 bits = present ? HDA_AMP_MUTE : 0;
18369 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18370 HDA_AMP_MUTE, bits);
18371 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18372 HDA_AMP_MUTE, bits);
18373}
18374
18375static void alc663_g71v_front_automute(struct hda_codec *codec)
18376{
18377 unsigned int present;
18378 unsigned char bits;
18379
864f92be 18380 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
18381 bits = present ? HDA_AMP_MUTE : 0;
18382 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18383 HDA_AMP_MUTE, bits);
18384}
18385
18386static void alc663_g71v_unsol_event(struct hda_codec *codec,
18387 unsigned int res)
18388{
18389 switch (res >> 26) {
18390 case ALC880_HP_EVENT:
18391 alc663_g71v_hp_automute(codec);
18392 break;
18393 case ALC880_FRONT_EVENT:
18394 alc663_g71v_front_automute(codec);
18395 break;
18396 case ALC880_MIC_EVENT:
4f5d1706 18397 alc_mic_automute(codec);
6dda9f4a
KY
18398 break;
18399 }
18400}
18401
4f5d1706
TI
18402#define alc663_g71v_setup alc663_m51va_setup
18403
6dda9f4a
KY
18404static void alc663_g71v_inithook(struct hda_codec *codec)
18405{
18406 alc663_g71v_front_automute(codec);
18407 alc663_g71v_hp_automute(codec);
4f5d1706 18408 alc_mic_automute(codec);
6dda9f4a
KY
18409}
18410
18411static void alc663_g50v_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
18424#define alc663_g50v_setup alc663_m51va_setup
18425
6dda9f4a
KY
18426static void alc663_g50v_inithook(struct hda_codec *codec)
18427{
18428 alc663_m51va_speaker_automute(codec);
4f5d1706 18429 alc_mic_automute(codec);
6dda9f4a
KY
18430}
18431
f1d4e28b
KY
18432static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18433 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18434 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b
KY
18435
18436 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
18437 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18438 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18439
18440 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
18441 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18442 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18443 { } /* end */
18444};
18445
9541ba1d
CP
18446static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18447 /* Master Playback automatically created from Speaker and Headphone */
18448 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18449 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18450 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18451 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18452
18453 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18454 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18455 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
18456
18457 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18458 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18459 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
18460 { } /* end */
18461};
18462
cb53c626
TI
18463#ifdef CONFIG_SND_HDA_POWER_SAVE
18464#define alc662_loopbacks alc880_loopbacks
18465#endif
18466
bc9f98a9 18467
def319f9 18468/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18469#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18470#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18471#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18472#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18473
18474/*
18475 * configuration and preset
18476 */
18477static const char *alc662_models[ALC662_MODEL_LAST] = {
18478 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18479 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18480 [ALC662_3ST_6ch] = "3stack-6ch",
18481 [ALC662_5ST_DIG] = "6stack-dig",
18482 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18483 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18484 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18485 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18486 [ALC663_ASUS_M51VA] = "m51va",
18487 [ALC663_ASUS_G71V] = "g71v",
18488 [ALC663_ASUS_H13] = "h13",
18489 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18490 [ALC663_ASUS_MODE1] = "asus-mode1",
18491 [ALC662_ASUS_MODE2] = "asus-mode2",
18492 [ALC663_ASUS_MODE3] = "asus-mode3",
18493 [ALC663_ASUS_MODE4] = "asus-mode4",
18494 [ALC663_ASUS_MODE5] = "asus-mode5",
18495 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18496 [ALC663_ASUS_MODE7] = "asus-mode7",
18497 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18498 [ALC272_DELL] = "dell",
18499 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18500 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18501 [ALC662_AUTO] = "auto",
18502};
18503
18504static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18505 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18506 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18507 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18508 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18509 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18510 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18511 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18512 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18513 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18514 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18515 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18516 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18517 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18518 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18519 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18520 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18521 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18522 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18523 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18524 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18525 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18526 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18527 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18528 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18529 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18530 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18531 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18532 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18533 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18534 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18535 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18536 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18537 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18538 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18539 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18540 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18541 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18542 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18543 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18544 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18545 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18546 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18547 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18548 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18549 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18550 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18551 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18552 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18553 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18554 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18555 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18556 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18557 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18558 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18559 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18560 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18561 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18562 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18563 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18564 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18565 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18566 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18567 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18568 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18569 ALC662_3ST_6ch_DIG),
4dee8baa 18570 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18571 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
18572 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18573 ALC662_3ST_6ch_DIG),
6227cdce 18574 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18575 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18576 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18577 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18578 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18579 ALC662_3ST_6ch_DIG),
dea0a509
TI
18580 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18581 ALC663_ASUS_H13),
bc9f98a9
KY
18582 {}
18583};
18584
18585static struct alc_config_preset alc662_presets[] = {
18586 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18587 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
18588 .init_verbs = { alc662_init_verbs },
18589 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18590 .dac_nids = alc662_dac_nids,
18591 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18592 .dig_in_nid = ALC662_DIGIN_NID,
18593 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18594 .channel_mode = alc662_3ST_2ch_modes,
18595 .input_mux = &alc662_capture_source,
18596 },
18597 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18598 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18599 .init_verbs = { alc662_init_verbs },
18600 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18601 .dac_nids = alc662_dac_nids,
18602 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18603 .dig_in_nid = ALC662_DIGIN_NID,
18604 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18605 .channel_mode = alc662_3ST_6ch_modes,
18606 .need_dac_fix = 1,
18607 .input_mux = &alc662_capture_source,
f12ab1e0 18608 },
bc9f98a9 18609 [ALC662_3ST_6ch] = {
f9e336f6 18610 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18611 .init_verbs = { alc662_init_verbs },
18612 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18613 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18614 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18615 .channel_mode = alc662_3ST_6ch_modes,
18616 .need_dac_fix = 1,
18617 .input_mux = &alc662_capture_source,
f12ab1e0 18618 },
bc9f98a9 18619 [ALC662_5ST_DIG] = {
f9e336f6 18620 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18621 .init_verbs = { alc662_init_verbs },
18622 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18623 .dac_nids = alc662_dac_nids,
18624 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18625 .dig_in_nid = ALC662_DIGIN_NID,
18626 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18627 .channel_mode = alc662_5stack_modes,
18628 .input_mux = &alc662_capture_source,
18629 },
18630 [ALC662_LENOVO_101E] = {
f9e336f6 18631 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
18632 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18633 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18634 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18635 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18636 .channel_mode = alc662_3ST_2ch_modes,
18637 .input_mux = &alc662_lenovo_101e_capture_source,
18638 .unsol_event = alc662_lenovo_101e_unsol_event,
18639 .init_hook = alc662_lenovo_101e_all_automute,
18640 },
291702f0 18641 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18642 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
18643 .init_verbs = { alc662_init_verbs,
18644 alc662_eeepc_sue_init_verbs },
18645 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18646 .dac_nids = alc662_dac_nids,
291702f0
KY
18647 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18648 .channel_mode = alc662_3ST_2ch_modes,
291702f0 18649 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18650 .setup = alc662_eeepc_setup,
291702f0
KY
18651 .init_hook = alc662_eeepc_inithook,
18652 },
8c427226 18653 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18654 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18655 alc662_chmode_mixer },
18656 .init_verbs = { alc662_init_verbs,
18657 alc662_eeepc_ep20_sue_init_verbs },
18658 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18659 .dac_nids = alc662_dac_nids,
8c427226
KY
18660 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18661 .channel_mode = alc662_3ST_6ch_modes,
18662 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 18663 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18664 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
18665 .init_hook = alc662_eeepc_ep20_inithook,
18666 },
f1d4e28b 18667 [ALC662_ECS] = {
f9e336f6 18668 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
18669 .init_verbs = { alc662_init_verbs,
18670 alc662_ecs_init_verbs },
18671 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18672 .dac_nids = alc662_dac_nids,
18673 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18674 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18675 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18676 .setup = alc662_eeepc_setup,
f1d4e28b
KY
18677 .init_hook = alc662_eeepc_inithook,
18678 },
6dda9f4a 18679 [ALC663_ASUS_M51VA] = {
f9e336f6 18680 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18681 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18682 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18683 .dac_nids = alc662_dac_nids,
18684 .dig_out_nid = ALC662_DIGOUT_NID,
18685 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18686 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18687 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18688 .setup = alc663_m51va_setup,
6dda9f4a
KY
18689 .init_hook = alc663_m51va_inithook,
18690 },
18691 [ALC663_ASUS_G71V] = {
f9e336f6 18692 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
18693 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18694 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18695 .dac_nids = alc662_dac_nids,
18696 .dig_out_nid = ALC662_DIGOUT_NID,
18697 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18698 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18699 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 18700 .setup = alc663_g71v_setup,
6dda9f4a
KY
18701 .init_hook = alc663_g71v_inithook,
18702 },
18703 [ALC663_ASUS_H13] = {
f9e336f6 18704 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18705 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18706 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18707 .dac_nids = alc662_dac_nids,
18708 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18709 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
18710 .unsol_event = alc663_m51va_unsol_event,
18711 .init_hook = alc663_m51va_inithook,
18712 },
18713 [ALC663_ASUS_G50V] = {
f9e336f6 18714 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
18715 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18716 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18717 .dac_nids = alc662_dac_nids,
18718 .dig_out_nid = ALC662_DIGOUT_NID,
18719 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18720 .channel_mode = alc662_3ST_6ch_modes,
18721 .input_mux = &alc663_capture_source,
18722 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 18723 .setup = alc663_g50v_setup,
6dda9f4a
KY
18724 .init_hook = alc663_g50v_inithook,
18725 },
f1d4e28b 18726 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18727 .mixers = { alc663_m51va_mixer },
18728 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18729 .init_verbs = { alc662_init_verbs,
18730 alc663_21jd_amic_init_verbs },
18731 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18732 .hp_nid = 0x03,
18733 .dac_nids = alc662_dac_nids,
18734 .dig_out_nid = ALC662_DIGOUT_NID,
18735 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18736 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18737 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18738 .setup = alc663_mode1_setup,
f1d4e28b
KY
18739 .init_hook = alc663_mode1_inithook,
18740 },
18741 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18742 .mixers = { alc662_1bjd_mixer },
18743 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18744 .init_verbs = { alc662_init_verbs,
18745 alc662_1bjd_amic_init_verbs },
18746 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18747 .dac_nids = alc662_dac_nids,
18748 .dig_out_nid = ALC662_DIGOUT_NID,
18749 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18750 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18751 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18752 .setup = alc662_mode2_setup,
f1d4e28b
KY
18753 .init_hook = alc662_mode2_inithook,
18754 },
18755 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18756 .mixers = { alc663_two_hp_m1_mixer },
18757 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18758 .init_verbs = { alc662_init_verbs,
18759 alc663_two_hp_amic_m1_init_verbs },
18760 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18761 .hp_nid = 0x03,
18762 .dac_nids = alc662_dac_nids,
18763 .dig_out_nid = ALC662_DIGOUT_NID,
18764 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18765 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18766 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 18767 .setup = alc663_mode3_setup,
f1d4e28b
KY
18768 .init_hook = alc663_mode3_inithook,
18769 },
18770 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18771 .mixers = { alc663_asus_21jd_clfe_mixer },
18772 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18773 .init_verbs = { alc662_init_verbs,
18774 alc663_21jd_amic_init_verbs},
18775 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18776 .hp_nid = 0x03,
18777 .dac_nids = alc662_dac_nids,
18778 .dig_out_nid = ALC662_DIGOUT_NID,
18779 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18780 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18781 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18782 .setup = alc663_mode4_setup,
f1d4e28b
KY
18783 .init_hook = alc663_mode4_inithook,
18784 },
18785 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18786 .mixers = { alc663_asus_15jd_clfe_mixer },
18787 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18788 .init_verbs = { alc662_init_verbs,
18789 alc663_15jd_amic_init_verbs },
18790 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18791 .hp_nid = 0x03,
18792 .dac_nids = alc662_dac_nids,
18793 .dig_out_nid = ALC662_DIGOUT_NID,
18794 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18795 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18796 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 18797 .setup = alc663_mode5_setup,
f1d4e28b
KY
18798 .init_hook = alc663_mode5_inithook,
18799 },
18800 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18801 .mixers = { alc663_two_hp_m2_mixer },
18802 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18803 .init_verbs = { alc662_init_verbs,
18804 alc663_two_hp_amic_m2_init_verbs },
18805 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18806 .hp_nid = 0x03,
18807 .dac_nids = alc662_dac_nids,
18808 .dig_out_nid = ALC662_DIGOUT_NID,
18809 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18810 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18811 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 18812 .setup = alc663_mode6_setup,
f1d4e28b
KY
18813 .init_hook = alc663_mode6_inithook,
18814 },
ebb83eeb
KY
18815 [ALC663_ASUS_MODE7] = {
18816 .mixers = { alc663_mode7_mixer },
18817 .cap_mixer = alc662_auto_capture_mixer,
18818 .init_verbs = { alc662_init_verbs,
18819 alc663_mode7_init_verbs },
18820 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18821 .hp_nid = 0x03,
18822 .dac_nids = alc662_dac_nids,
18823 .dig_out_nid = ALC662_DIGOUT_NID,
18824 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18825 .channel_mode = alc662_3ST_2ch_modes,
18826 .unsol_event = alc663_mode7_unsol_event,
18827 .setup = alc663_mode7_setup,
18828 .init_hook = alc663_mode7_inithook,
18829 },
18830 [ALC663_ASUS_MODE8] = {
18831 .mixers = { alc663_mode8_mixer },
18832 .cap_mixer = alc662_auto_capture_mixer,
18833 .init_verbs = { alc662_init_verbs,
18834 alc663_mode8_init_verbs },
18835 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18836 .hp_nid = 0x03,
18837 .dac_nids = alc662_dac_nids,
18838 .dig_out_nid = ALC662_DIGOUT_NID,
18839 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18840 .channel_mode = alc662_3ST_2ch_modes,
18841 .unsol_event = alc663_mode8_unsol_event,
18842 .setup = alc663_mode8_setup,
18843 .init_hook = alc663_mode8_inithook,
18844 },
622e84cd
KY
18845 [ALC272_DELL] = {
18846 .mixers = { alc663_m51va_mixer },
18847 .cap_mixer = alc272_auto_capture_mixer,
18848 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
18849 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18850 .dac_nids = alc662_dac_nids,
18851 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18852 .adc_nids = alc272_adc_nids,
18853 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18854 .capsrc_nids = alc272_capsrc_nids,
18855 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18856 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18857 .setup = alc663_m51va_setup,
622e84cd
KY
18858 .init_hook = alc663_m51va_inithook,
18859 },
18860 [ALC272_DELL_ZM1] = {
18861 .mixers = { alc663_m51va_mixer },
18862 .cap_mixer = alc662_auto_capture_mixer,
18863 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
18864 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18865 .dac_nids = alc662_dac_nids,
18866 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18867 .adc_nids = alc662_adc_nids,
b59bdf3b 18868 .num_adc_nids = 1,
622e84cd
KY
18869 .capsrc_nids = alc662_capsrc_nids,
18870 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18871 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18872 .setup = alc663_m51va_setup,
622e84cd
KY
18873 .init_hook = alc663_m51va_inithook,
18874 },
9541ba1d
CP
18875 [ALC272_SAMSUNG_NC10] = {
18876 .mixers = { alc272_nc10_mixer },
18877 .init_verbs = { alc662_init_verbs,
18878 alc663_21jd_amic_init_verbs },
18879 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18880 .dac_nids = alc272_dac_nids,
18881 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18882 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18883 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 18884 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18885 .setup = alc663_mode4_setup,
9541ba1d
CP
18886 .init_hook = alc663_mode4_inithook,
18887 },
bc9f98a9
KY
18888};
18889
18890
18891/*
18892 * BIOS auto configuration
18893 */
18894
7085ec12
TI
18895/* convert from MIX nid to DAC */
18896static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
18897{
18898 if (nid == 0x0f)
18899 return 0x02;
18900 else if (nid >= 0x0c && nid <= 0x0e)
18901 return nid - 0x0c + 0x02;
18902 else
18903 return 0;
18904}
18905
18906/* get MIX nid connected to the given pin targeted to DAC */
18907static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18908 hda_nid_t dac)
18909{
18910 hda_nid_t mix[4];
18911 int i, num;
18912
18913 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18914 for (i = 0; i < num; i++) {
18915 if (alc662_mix_to_dac(mix[i]) == dac)
18916 return mix[i];
18917 }
18918 return 0;
18919}
18920
18921/* look for an empty DAC slot */
18922static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18923{
18924 struct alc_spec *spec = codec->spec;
18925 hda_nid_t srcs[5];
18926 int i, j, num;
18927
18928 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18929 if (num < 0)
18930 return 0;
18931 for (i = 0; i < num; i++) {
18932 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
18933 if (!nid)
18934 continue;
18935 for (j = 0; j < spec->multiout.num_dacs; j++)
18936 if (spec->multiout.dac_nids[j] == nid)
18937 break;
18938 if (j >= spec->multiout.num_dacs)
18939 return nid;
18940 }
18941 return 0;
18942}
18943
18944/* fill in the dac_nids table from the parsed pin configuration */
18945static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18946 const struct auto_pin_cfg *cfg)
18947{
18948 struct alc_spec *spec = codec->spec;
18949 int i;
18950 hda_nid_t dac;
18951
18952 spec->multiout.dac_nids = spec->private_dac_nids;
18953 for (i = 0; i < cfg->line_outs; i++) {
18954 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
18955 if (!dac)
18956 continue;
18957 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
18958 }
18959 return 0;
18960}
18961
0afe5f89 18962static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18963 hda_nid_t nid, unsigned int chs)
18964{
0afe5f89 18965 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
7085ec12
TI
18966 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18967}
18968
0afe5f89 18969static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18970 hda_nid_t nid, unsigned int chs)
18971{
0afe5f89 18972 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12
TI
18973 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18974}
18975
18976#define alc662_add_stereo_vol(spec, pfx, nid) \
18977 alc662_add_vol_ctl(spec, pfx, nid, 3)
18978#define alc662_add_stereo_sw(spec, pfx, nid) \
18979 alc662_add_sw_ctl(spec, pfx, nid, 3)
18980
bc9f98a9 18981/* add playback controls from the parsed DAC table */
7085ec12 18982static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
18983 const struct auto_pin_cfg *cfg)
18984{
7085ec12 18985 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18986 static const char *chname[4] = {
18987 "Front", "Surround", NULL /*CLFE*/, "Side"
18988 };
7085ec12 18989 hda_nid_t nid, mix;
bc9f98a9
KY
18990 int i, err;
18991
18992 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
18993 nid = spec->multiout.dac_nids[i];
18994 if (!nid)
18995 continue;
18996 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
18997 if (!mix)
bc9f98a9 18998 continue;
bc9f98a9
KY
18999 if (i == 2) {
19000 /* Center/LFE */
7085ec12 19001 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
19002 if (err < 0)
19003 return err;
7085ec12 19004 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
19005 if (err < 0)
19006 return err;
7085ec12 19007 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
19008 if (err < 0)
19009 return err;
7085ec12 19010 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
19011 if (err < 0)
19012 return err;
19013 } else {
0d884cb9
TI
19014 const char *pfx;
19015 if (cfg->line_outs == 1 &&
19016 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
7085ec12 19017 if (cfg->hp_outs)
0d884cb9
TI
19018 pfx = "Speaker";
19019 else
19020 pfx = "PCM";
19021 } else
19022 pfx = chname[i];
7085ec12 19023 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
bc9f98a9
KY
19024 if (err < 0)
19025 return err;
0d884cb9
TI
19026 if (cfg->line_outs == 1 &&
19027 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19028 pfx = "Speaker";
7085ec12 19029 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
bc9f98a9
KY
19030 if (err < 0)
19031 return err;
19032 }
19033 }
19034 return 0;
19035}
19036
19037/* add playback controls for speaker and HP outputs */
7085ec12
TI
19038/* return DAC nid if any new DAC is assigned */
19039static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
19040 const char *pfx)
19041{
7085ec12
TI
19042 struct alc_spec *spec = codec->spec;
19043 hda_nid_t nid, mix;
bc9f98a9 19044 int err;
bc9f98a9
KY
19045
19046 if (!pin)
19047 return 0;
7085ec12
TI
19048 nid = alc662_look_for_dac(codec, pin);
19049 if (!nid) {
7085ec12
TI
19050 /* the corresponding DAC is already occupied */
19051 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19052 return 0; /* no way */
19053 /* create a switch only */
0afe5f89 19054 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 19055 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
19056 }
19057
7085ec12
TI
19058 mix = alc662_dac_to_mix(codec, pin, nid);
19059 if (!mix)
19060 return 0;
19061 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19062 if (err < 0)
19063 return err;
19064 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19065 if (err < 0)
19066 return err;
19067 return nid;
bc9f98a9
KY
19068}
19069
19070/* create playback/capture controls for input pins */
05f5f477 19071#define alc662_auto_create_input_ctls \
4b7348a1 19072 alc882_auto_create_input_ctls
bc9f98a9
KY
19073
19074static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19075 hda_nid_t nid, int pin_type,
7085ec12 19076 hda_nid_t dac)
bc9f98a9 19077{
7085ec12 19078 int i, num;
ce503f38 19079 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 19080
f6c7e546 19081 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 19082 /* need the manual connection? */
7085ec12
TI
19083 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19084 if (num <= 1)
19085 return;
19086 for (i = 0; i < num; i++) {
19087 if (alc662_mix_to_dac(srcs[i]) != dac)
19088 continue;
19089 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
19090 return;
bc9f98a9
KY
19091 }
19092}
19093
19094static void alc662_auto_init_multi_out(struct hda_codec *codec)
19095{
19096 struct alc_spec *spec = codec->spec;
7085ec12 19097 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
19098 int i;
19099
19100 for (i = 0; i <= HDA_SIDE; i++) {
19101 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19102 if (nid)
baba8ee9 19103 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 19104 spec->multiout.dac_nids[i]);
bc9f98a9
KY
19105 }
19106}
19107
19108static void alc662_auto_init_hp_out(struct hda_codec *codec)
19109{
19110 struct alc_spec *spec = codec->spec;
19111 hda_nid_t pin;
19112
19113 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
19114 if (pin)
19115 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19116 spec->multiout.hp_nid);
f6c7e546
TI
19117 pin = spec->autocfg.speaker_pins[0];
19118 if (pin)
7085ec12
TI
19119 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19120 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
19121}
19122
bc9f98a9
KY
19123#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19124
19125static void alc662_auto_init_analog_input(struct hda_codec *codec)
19126{
19127 struct alc_spec *spec = codec->spec;
66ceeb6b 19128 struct auto_pin_cfg *cfg = &spec->autocfg;
bc9f98a9
KY
19129 int i;
19130
66ceeb6b
TI
19131 for (i = 0; i < cfg->num_inputs; i++) {
19132 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 19133 if (alc_is_input_pin(codec, nid)) {
30ea098f 19134 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
52ca15b7 19135 if (nid != ALC662_PIN_CD_NID &&
e82c025b 19136 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
19137 snd_hda_codec_write(codec, nid, 0,
19138 AC_VERB_SET_AMP_GAIN_MUTE,
19139 AMP_OUT_MUTE);
19140 }
19141 }
19142}
19143
f511b01c
TI
19144#define alc662_auto_init_input_src alc882_auto_init_input_src
19145
bc9f98a9
KY
19146static int alc662_parse_auto_config(struct hda_codec *codec)
19147{
19148 struct alc_spec *spec = codec->spec;
19149 int err;
19150 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19151
19152 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19153 alc662_ignore);
19154 if (err < 0)
19155 return err;
19156 if (!spec->autocfg.line_outs)
19157 return 0; /* can't find valid BIOS pin config */
19158
7085ec12 19159 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
19160 if (err < 0)
19161 return err;
7085ec12 19162 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19163 if (err < 0)
19164 return err;
7085ec12 19165 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
19166 spec->autocfg.speaker_pins[0],
19167 "Speaker");
19168 if (err < 0)
19169 return err;
7085ec12
TI
19170 if (err)
19171 spec->multiout.extra_out_nid[0] = err;
19172 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
19173 "Headphone");
19174 if (err < 0)
19175 return err;
7085ec12
TI
19176 if (err)
19177 spec->multiout.hp_nid = err;
05f5f477 19178 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19179 if (err < 0)
bc9f98a9
KY
19180 return err;
19181
19182 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19183
757899ac 19184 alc_auto_parse_digital(codec);
bc9f98a9 19185
603c4019 19186 if (spec->kctls.list)
d88897ea 19187 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19188
19189 spec->num_mux_defs = 1;
61b9b9b1 19190 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19191
cec27c89
KY
19192 add_verb(spec, alc662_init_verbs);
19193 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
d1eb57f4 19194 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
cec27c89
KY
19195 add_verb(spec, alc663_init_verbs);
19196
19197 if (codec->vendor_id == 0x10ec0272)
19198 add_verb(spec, alc272_init_verbs);
ee979a14
TI
19199
19200 err = alc_auto_add_mic_boost(codec);
19201 if (err < 0)
19202 return err;
19203
6227cdce
KY
19204 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19205 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19206 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19207 else
19208 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19209
8c87286f 19210 return 1;
bc9f98a9
KY
19211}
19212
19213/* additional initialization for auto-configuration model */
19214static void alc662_auto_init(struct hda_codec *codec)
19215{
f6c7e546 19216 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19217 alc662_auto_init_multi_out(codec);
19218 alc662_auto_init_hp_out(codec);
19219 alc662_auto_init_analog_input(codec);
f511b01c 19220 alc662_auto_init_input_src(codec);
757899ac 19221 alc_auto_init_digital(codec);
f6c7e546 19222 if (spec->unsol_event)
7fb0d78f 19223 alc_inithook(codec);
bc9f98a9
KY
19224}
19225
6cb3b707
DH
19226enum {
19227 ALC662_FIXUP_IDEAPAD,
19228};
19229
19230static const struct alc_fixup alc662_fixups[] = {
19231 [ALC662_FIXUP_IDEAPAD] = {
19232 .pins = (const struct alc_pincfg[]) {
19233 { 0x17, 0x99130112 }, /* subwoofer */
19234 { }
19235 }
19236 },
19237};
19238
19239static struct snd_pci_quirk alc662_fixup_tbl[] = {
19240 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
19241 {}
19242};
19243
19244
19245
bc9f98a9
KY
19246static int patch_alc662(struct hda_codec *codec)
19247{
19248 struct alc_spec *spec;
19249 int err, board_config;
19250
19251 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19252 if (!spec)
19253 return -ENOMEM;
19254
19255 codec->spec = spec;
19256
da00c244
KY
19257 alc_auto_parse_customize_define(codec);
19258
2c3bf9ab
TI
19259 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19260
c027ddcd
KY
19261 if (alc_read_coef_idx(codec, 0) == 0x8020)
19262 alc_codec_rename(codec, "ALC661");
19263 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) &&
19264 codec->bus->pci->subsystem_vendor == 0x1025 &&
19265 spec->cdefine.platform_type == 1)
19266 alc_codec_rename(codec, "ALC272X");
274693f3 19267
bc9f98a9
KY
19268 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19269 alc662_models,
19270 alc662_cfg_tbl);
19271 if (board_config < 0) {
9a11f1aa
TI
19272 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19273 codec->chip_name);
bc9f98a9
KY
19274 board_config = ALC662_AUTO;
19275 }
19276
19277 if (board_config == ALC662_AUTO) {
6cb3b707 19278 alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 1);
bc9f98a9
KY
19279 /* automatic parse from the BIOS config */
19280 err = alc662_parse_auto_config(codec);
19281 if (err < 0) {
19282 alc_free(codec);
19283 return err;
8c87286f 19284 } else if (!err) {
bc9f98a9
KY
19285 printk(KERN_INFO
19286 "hda_codec: Cannot set up configuration "
19287 "from BIOS. Using base mode...\n");
19288 board_config = ALC662_3ST_2ch_DIG;
19289 }
19290 }
19291
dc1eae25 19292 if (has_cdefine_beep(codec)) {
8af2591d
TI
19293 err = snd_hda_attach_beep_device(codec, 0x1);
19294 if (err < 0) {
19295 alc_free(codec);
19296 return err;
19297 }
680cd536
KK
19298 }
19299
bc9f98a9 19300 if (board_config != ALC662_AUTO)
e9c364c0 19301 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19302
bc9f98a9
KY
19303 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19304 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19305
bc9f98a9
KY
19306 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19307 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19308
dd704698
TI
19309 if (!spec->adc_nids) {
19310 spec->adc_nids = alc662_adc_nids;
19311 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19312 }
19313 if (!spec->capsrc_nids)
19314 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19315
f9e336f6 19316 if (!spec->cap_mixer)
b59bdf3b 19317 set_capture_mixer(codec);
cec27c89 19318
dc1eae25 19319 if (has_cdefine_beep(codec)) {
da00c244
KY
19320 switch (codec->vendor_id) {
19321 case 0x10ec0662:
19322 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19323 break;
19324 case 0x10ec0272:
19325 case 0x10ec0663:
19326 case 0x10ec0665:
19327 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19328 break;
19329 case 0x10ec0273:
19330 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19331 break;
19332 }
cec27c89 19333 }
2134ea4f
TI
19334 spec->vmaster_nid = 0x02;
19335
bc9f98a9 19336 codec->patch_ops = alc_patch_ops;
6cb3b707 19337 if (board_config == ALC662_AUTO) {
bc9f98a9 19338 spec->init_hook = alc662_auto_init;
6cb3b707
DH
19339 alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 0);
19340 }
19341
cb53c626
TI
19342#ifdef CONFIG_SND_HDA_POWER_SAVE
19343 if (!spec->loopback.amplist)
19344 spec->loopback.amplist = alc662_loopbacks;
19345#endif
bc9f98a9
KY
19346
19347 return 0;
19348}
19349
274693f3
KY
19350static int patch_alc888(struct hda_codec *codec)
19351{
19352 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19353 kfree(codec->chip_name);
19354 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19355 if (!codec->chip_name) {
19356 alc_free(codec);
274693f3 19357 return -ENOMEM;
ac2c92e0
TI
19358 }
19359 return patch_alc662(codec);
274693f3 19360 }
ac2c92e0 19361 return patch_alc882(codec);
274693f3
KY
19362}
19363
d1eb57f4
KY
19364/*
19365 * ALC680 support
19366 */
c69aefab 19367#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19368#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19369#define alc680_modes alc260_modes
19370
19371static hda_nid_t alc680_dac_nids[3] = {
19372 /* Lout1, Lout2, hp */
19373 0x02, 0x03, 0x04
19374};
19375
19376static hda_nid_t alc680_adc_nids[3] = {
19377 /* ADC0-2 */
19378 /* DMIC, MIC, Line-in*/
19379 0x07, 0x08, 0x09
19380};
19381
c69aefab
KY
19382/*
19383 * Analog capture ADC cgange
19384 */
66ceeb6b
TI
19385static void alc680_rec_autoswitch(struct hda_codec *codec)
19386{
19387 struct alc_spec *spec = codec->spec;
19388 struct auto_pin_cfg *cfg = &spec->autocfg;
19389 int pin_found = 0;
19390 int type_found = AUTO_PIN_LAST;
19391 hda_nid_t nid;
19392 int i;
19393
19394 for (i = 0; i < cfg->num_inputs; i++) {
19395 nid = cfg->inputs[i].pin;
19396 if (!(snd_hda_query_pin_caps(codec, nid) &
19397 AC_PINCAP_PRES_DETECT))
19398 continue;
19399 if (snd_hda_jack_detect(codec, nid)) {
19400 if (cfg->inputs[i].type < type_found) {
19401 type_found = cfg->inputs[i].type;
19402 pin_found = nid;
19403 }
19404 }
19405 }
19406
19407 nid = 0x07;
19408 if (pin_found)
19409 snd_hda_get_connections(codec, pin_found, &nid, 1);
19410
19411 if (nid != spec->cur_adc)
19412 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19413 spec->cur_adc = nid;
19414 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19415 spec->cur_adc_format);
19416}
19417
c69aefab
KY
19418static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19419 struct hda_codec *codec,
19420 unsigned int stream_tag,
19421 unsigned int format,
19422 struct snd_pcm_substream *substream)
19423{
19424 struct alc_spec *spec = codec->spec;
c69aefab 19425
66ceeb6b 19426 spec->cur_adc = 0x07;
c69aefab
KY
19427 spec->cur_adc_stream_tag = stream_tag;
19428 spec->cur_adc_format = format;
19429
66ceeb6b 19430 alc680_rec_autoswitch(codec);
c69aefab
KY
19431 return 0;
19432}
19433
19434static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19435 struct hda_codec *codec,
19436 struct snd_pcm_substream *substream)
19437{
19438 snd_hda_codec_cleanup_stream(codec, 0x07);
19439 snd_hda_codec_cleanup_stream(codec, 0x08);
19440 snd_hda_codec_cleanup_stream(codec, 0x09);
19441 return 0;
19442}
19443
19444static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19445 .substreams = 1, /* can be overridden */
19446 .channels_min = 2,
19447 .channels_max = 2,
19448 /* NID is set in alc_build_pcms */
19449 .ops = {
19450 .prepare = alc680_capture_pcm_prepare,
19451 .cleanup = alc680_capture_pcm_cleanup
19452 },
19453};
19454
d1eb57f4
KY
19455static struct snd_kcontrol_new alc680_base_mixer[] = {
19456 /* output mixer control */
19457 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19458 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19459 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19460 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
c69aefab 19461 HDA_CODEC_VOLUME("Int Mic Boost", 0x12, 0, HDA_INPUT),
d1eb57f4 19462 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c69aefab 19463 HDA_CODEC_VOLUME("Line In Boost", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19464 { }
19465};
19466
c69aefab
KY
19467static struct hda_bind_ctls alc680_bind_cap_vol = {
19468 .ops = &snd_hda_bind_vol,
19469 .values = {
19470 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19471 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19472 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19473 0
19474 },
19475};
19476
19477static struct hda_bind_ctls alc680_bind_cap_switch = {
19478 .ops = &snd_hda_bind_sw,
19479 .values = {
19480 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19481 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19482 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19483 0
19484 },
19485};
19486
19487static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19488 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19489 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19490 { } /* end */
19491};
19492
19493/*
19494 * generic initialization of ADC, input mixers and output mixers
19495 */
19496static struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19497 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19498 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19499 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19500
c69aefab
KY
19501 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19502 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19503 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19504 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19505 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19506 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19507
19508 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19509 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19510 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19511 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19512 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19513
19514 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19515 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19516 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19517
d1eb57f4
KY
19518 { }
19519};
19520
c69aefab
KY
19521/* toggle speaker-output according to the hp-jack state */
19522static void alc680_base_setup(struct hda_codec *codec)
19523{
19524 struct alc_spec *spec = codec->spec;
19525
19526 spec->autocfg.hp_pins[0] = 0x16;
19527 spec->autocfg.speaker_pins[0] = 0x14;
19528 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19529 spec->autocfg.num_inputs = 2;
19530 spec->autocfg.inputs[0].pin = 0x18;
19531 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19532 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19533 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
c69aefab
KY
19534}
19535
19536static void alc680_unsol_event(struct hda_codec *codec,
19537 unsigned int res)
19538{
19539 if ((res >> 26) == ALC880_HP_EVENT)
19540 alc_automute_amp(codec);
19541 if ((res >> 26) == ALC880_MIC_EVENT)
19542 alc680_rec_autoswitch(codec);
19543}
19544
19545static void alc680_inithook(struct hda_codec *codec)
19546{
19547 alc_automute_amp(codec);
19548 alc680_rec_autoswitch(codec);
19549}
19550
d1eb57f4
KY
19551/* create input playback/capture controls for the given pin */
19552static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19553 const char *ctlname, int idx)
19554{
19555 hda_nid_t dac;
19556 int err;
19557
19558 switch (nid) {
19559 case 0x14:
19560 dac = 0x02;
19561 break;
19562 case 0x15:
19563 dac = 0x03;
19564 break;
19565 case 0x16:
19566 dac = 0x04;
19567 break;
19568 default:
19569 return 0;
19570 }
19571 if (spec->multiout.dac_nids[0] != dac &&
19572 spec->multiout.dac_nids[1] != dac) {
19573 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19574 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19575 HDA_OUTPUT));
19576 if (err < 0)
19577 return err;
19578
19579 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19580 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19581
19582 if (err < 0)
19583 return err;
19584 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19585 }
19586
19587 return 0;
19588}
19589
19590/* add playback controls from the parsed DAC table */
19591static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19592 const struct auto_pin_cfg *cfg)
19593{
19594 hda_nid_t nid;
19595 int err;
19596
19597 spec->multiout.dac_nids = spec->private_dac_nids;
19598
19599 nid = cfg->line_out_pins[0];
19600 if (nid) {
19601 const char *name;
19602 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19603 name = "Speaker";
19604 else
19605 name = "Front";
19606 err = alc680_new_analog_output(spec, nid, name, 0);
19607 if (err < 0)
19608 return err;
19609 }
19610
19611 nid = cfg->speaker_pins[0];
19612 if (nid) {
19613 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19614 if (err < 0)
19615 return err;
19616 }
19617 nid = cfg->hp_pins[0];
19618 if (nid) {
19619 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19620 if (err < 0)
19621 return err;
19622 }
19623
19624 return 0;
19625}
19626
19627static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19628 hda_nid_t nid, int pin_type)
19629{
19630 alc_set_pin_output(codec, nid, pin_type);
19631}
19632
19633static void alc680_auto_init_multi_out(struct hda_codec *codec)
19634{
19635 struct alc_spec *spec = codec->spec;
19636 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19637 if (nid) {
19638 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19639 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19640 }
19641}
19642
19643static void alc680_auto_init_hp_out(struct hda_codec *codec)
19644{
19645 struct alc_spec *spec = codec->spec;
19646 hda_nid_t pin;
19647
19648 pin = spec->autocfg.hp_pins[0];
19649 if (pin)
19650 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19651 pin = spec->autocfg.speaker_pins[0];
19652 if (pin)
19653 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19654}
19655
19656/* pcm configuration: identical with ALC880 */
19657#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19658#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19659#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19660#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19661#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19662
19663/*
19664 * BIOS auto configuration
19665 */
19666static int alc680_parse_auto_config(struct hda_codec *codec)
19667{
19668 struct alc_spec *spec = codec->spec;
19669 int err;
19670 static hda_nid_t alc680_ignore[] = { 0 };
19671
19672 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19673 alc680_ignore);
19674 if (err < 0)
19675 return err;
c69aefab 19676
d1eb57f4
KY
19677 if (!spec->autocfg.line_outs) {
19678 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19679 spec->multiout.max_channels = 2;
19680 spec->no_analog = 1;
19681 goto dig_only;
19682 }
19683 return 0; /* can't find valid BIOS pin config */
19684 }
19685 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19686 if (err < 0)
19687 return err;
19688
19689 spec->multiout.max_channels = 2;
19690
19691 dig_only:
19692 /* digital only support output */
757899ac 19693 alc_auto_parse_digital(codec);
d1eb57f4
KY
19694 if (spec->kctls.list)
19695 add_mixer(spec, spec->kctls.list);
19696
19697 add_verb(spec, alc680_init_verbs);
d1eb57f4
KY
19698
19699 err = alc_auto_add_mic_boost(codec);
19700 if (err < 0)
19701 return err;
19702
19703 return 1;
19704}
19705
19706#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19707
19708/* init callback for auto-configuration model -- overriding the default init */
19709static void alc680_auto_init(struct hda_codec *codec)
19710{
19711 struct alc_spec *spec = codec->spec;
19712 alc680_auto_init_multi_out(codec);
19713 alc680_auto_init_hp_out(codec);
19714 alc680_auto_init_analog_input(codec);
757899ac 19715 alc_auto_init_digital(codec);
d1eb57f4
KY
19716 if (spec->unsol_event)
19717 alc_inithook(codec);
19718}
19719
19720/*
19721 * configuration and preset
19722 */
19723static const char *alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19724 [ALC680_BASE] = "base",
19725 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19726};
19727
19728static struct snd_pci_quirk alc680_cfg_tbl[] = {
19729 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19730 {}
19731};
19732
19733static struct alc_config_preset alc680_presets[] = {
19734 [ALC680_BASE] = {
19735 .mixers = { alc680_base_mixer },
c69aefab 19736 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
19737 .init_verbs = { alc680_init_verbs },
19738 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19739 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
19740 .dig_out_nid = ALC680_DIGOUT_NID,
19741 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19742 .channel_mode = alc680_modes,
c69aefab
KY
19743 .unsol_event = alc680_unsol_event,
19744 .setup = alc680_base_setup,
19745 .init_hook = alc680_inithook,
19746
d1eb57f4
KY
19747 },
19748};
19749
19750static int patch_alc680(struct hda_codec *codec)
19751{
19752 struct alc_spec *spec;
19753 int board_config;
19754 int err;
19755
19756 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19757 if (spec == NULL)
19758 return -ENOMEM;
19759
19760 codec->spec = spec;
19761
19762 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19763 alc680_models,
19764 alc680_cfg_tbl);
19765
19766 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19767 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19768 codec->chip_name);
19769 board_config = ALC680_AUTO;
19770 }
19771
19772 if (board_config == ALC680_AUTO) {
19773 /* automatic parse from the BIOS config */
19774 err = alc680_parse_auto_config(codec);
19775 if (err < 0) {
19776 alc_free(codec);
19777 return err;
19778 } else if (!err) {
19779 printk(KERN_INFO
19780 "hda_codec: Cannot set up configuration "
19781 "from BIOS. Using base mode...\n");
19782 board_config = ALC680_BASE;
19783 }
19784 }
19785
19786 if (board_config != ALC680_AUTO)
19787 setup_preset(codec, &alc680_presets[board_config]);
19788
19789 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 19790 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 19791 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 19792 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
19793
19794 if (!spec->adc_nids) {
19795 spec->adc_nids = alc680_adc_nids;
19796 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19797 }
19798
19799 if (!spec->cap_mixer)
19800 set_capture_mixer(codec);
19801
19802 spec->vmaster_nid = 0x02;
19803
19804 codec->patch_ops = alc_patch_ops;
19805 if (board_config == ALC680_AUTO)
19806 spec->init_hook = alc680_auto_init;
19807
19808 return 0;
19809}
19810
1da177e4
LT
19811/*
19812 * patch entries
19813 */
1289e9e8 19814static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 19815 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 19816 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 19817 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 19818 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 19819 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 19820 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 19821 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 19822 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 19823 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 19824 .patch = patch_alc861 },
f32610ed
JS
19825 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19826 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19827 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 19828 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 19829 .patch = patch_alc882 },
bc9f98a9
KY
19830 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19831 .patch = patch_alc662 },
6dda9f4a 19832 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 19833 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 19834 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 19835 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 19836 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 19837 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 19838 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 19839 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 19840 .patch = patch_alc882 },
cb308f97 19841 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 19842 .patch = patch_alc882 },
df694daa 19843 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
4953550a 19844 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
4442608d 19845 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 19846 .patch = patch_alc882 },
274693f3 19847 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 19848 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 19849 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
19850 {} /* terminator */
19851};
1289e9e8
TI
19852
19853MODULE_ALIAS("snd-hda-codec-id:10ec*");
19854
19855MODULE_LICENSE("GPL");
19856MODULE_DESCRIPTION("Realtek HD-audio codec");
19857
19858static struct hda_codec_preset_list realtek_list = {
19859 .preset = snd_hda_preset_realtek,
19860 .owner = THIS_MODULE,
19861};
19862
19863static int __init patch_realtek_init(void)
19864{
19865 return snd_hda_add_codec_preset(&realtek_list);
19866}
19867
19868static void __exit patch_realtek_exit(void)
19869{
19870 snd_hda_delete_codec_preset(&realtek_list);
19871}
19872
19873module_init(patch_realtek_init)
19874module_exit(patch_realtek_exit)