]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Fix initial capsrc selection in patch_alc269()
[mirror_ubuntu-focal-kernel.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>
31#include "hda_codec.h"
32#include "hda_local.h"
680cd536 33#include "hda_beep.h"
1da177e4 34
ccc656ce
KY
35#define ALC880_FRONT_EVENT 0x01
36#define ALC880_DCVOL_EVENT 0x02
37#define ALC880_HP_EVENT 0x04
38#define ALC880_MIC_EVENT 0x08
1da177e4
LT
39
40/* ALC880 board config type */
41enum {
1da177e4
LT
42 ALC880_3ST,
43 ALC880_3ST_DIG,
44 ALC880_5ST,
45 ALC880_5ST_DIG,
46 ALC880_W810,
dfc0ff62 47 ALC880_Z71V,
b6482d48 48 ALC880_6ST,
16ded525
TI
49 ALC880_6ST_DIG,
50 ALC880_F1734,
51 ALC880_ASUS,
52 ALC880_ASUS_DIG,
53 ALC880_ASUS_W1V,
df694daa 54 ALC880_ASUS_DIG2,
2cf9f0fc 55 ALC880_FUJITSU,
16ded525 56 ALC880_UNIWILL_DIG,
ccc656ce
KY
57 ALC880_UNIWILL,
58 ALC880_UNIWILL_P53,
df694daa
KY
59 ALC880_CLEVO,
60 ALC880_TCL_S700,
ae6b813a 61 ALC880_LG,
d681518a 62 ALC880_LG_LW,
df99cd33 63 ALC880_MEDION_RIM,
e9edcee0
TI
64#ifdef CONFIG_SND_DEBUG
65 ALC880_TEST,
66#endif
df694daa 67 ALC880_AUTO,
16ded525
TI
68 ALC880_MODEL_LAST /* last tag */
69};
70
71/* ALC260 models */
72enum {
73 ALC260_BASIC,
74 ALC260_HP,
3f878308 75 ALC260_HP_DC7600,
df694daa
KY
76 ALC260_HP_3013,
77 ALC260_FUJITSU_S702X,
0bfc90e9 78 ALC260_ACER,
bc9f98a9
KY
79 ALC260_WILL,
80 ALC260_REPLACER_672V,
cc959489 81 ALC260_FAVORIT100,
7cf51e48
JW
82#ifdef CONFIG_SND_DEBUG
83 ALC260_TEST,
84#endif
df694daa 85 ALC260_AUTO,
16ded525 86 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
87};
88
df694daa
KY
89/* ALC262 models */
90enum {
91 ALC262_BASIC,
ccc656ce
KY
92 ALC262_HIPPO,
93 ALC262_HIPPO_1,
834be88d 94 ALC262_FUJITSU,
9c7f852e 95 ALC262_HP_BPC,
cd7509a4
KY
96 ALC262_HP_BPC_D7000_WL,
97 ALC262_HP_BPC_D7000_WF,
66d2a9d6 98 ALC262_HP_TC_T5735,
8c427226 99 ALC262_HP_RP5700,
304dcaac 100 ALC262_BENQ_ED8,
272a527c 101 ALC262_SONY_ASSAMD,
83c34218 102 ALC262_BENQ_T31,
f651b50b 103 ALC262_ULTRA,
0e31daf7 104 ALC262_LENOVO_3000,
e8f9ae2a 105 ALC262_NEC,
4e555fe5 106 ALC262_TOSHIBA_S06,
9f99a638 107 ALC262_TOSHIBA_RX1,
ba340e82 108 ALC262_TYAN,
df694daa
KY
109 ALC262_AUTO,
110 ALC262_MODEL_LAST /* last tag */
111};
112
a361d84b
KY
113/* ALC268 models */
114enum {
eb5a6621 115 ALC267_QUANTA_IL1,
a361d84b 116 ALC268_3ST,
d1a991a6 117 ALC268_TOSHIBA,
d273809e 118 ALC268_ACER,
c238b4f4 119 ALC268_ACER_DMIC,
8ef355da 120 ALC268_ACER_ASPIRE_ONE,
3866f0b0 121 ALC268_DELL,
f12462c5 122 ALC268_ZEPTO,
86c53bd2
JW
123#ifdef CONFIG_SND_DEBUG
124 ALC268_TEST,
125#endif
a361d84b
KY
126 ALC268_AUTO,
127 ALC268_MODEL_LAST /* last tag */
128};
129
f6a92248
KY
130/* ALC269 models */
131enum {
132 ALC269_BASIC,
60db6b53 133 ALC269_QUANTA_FL1,
84898e87
KY
134 ALC269_AMIC,
135 ALC269_DMIC,
136 ALC269VB_AMIC,
137 ALC269VB_DMIC,
26f5df26 138 ALC269_FUJITSU,
64154835 139 ALC269_LIFEBOOK,
f6a92248
KY
140 ALC269_AUTO,
141 ALC269_MODEL_LAST /* last tag */
142};
143
df694daa
KY
144/* ALC861 models */
145enum {
146 ALC861_3ST,
9c7f852e 147 ALC660_3ST,
df694daa
KY
148 ALC861_3ST_DIG,
149 ALC861_6ST_DIG,
22309c3e 150 ALC861_UNIWILL_M31,
a53d1aec 151 ALC861_TOSHIBA,
7cdbff94 152 ALC861_ASUS,
56bb0cab 153 ALC861_ASUS_LAPTOP,
df694daa
KY
154 ALC861_AUTO,
155 ALC861_MODEL_LAST,
156};
157
f32610ed
JS
158/* ALC861-VD models */
159enum {
160 ALC660VD_3ST,
6963f84c 161 ALC660VD_3ST_DIG,
13c94744 162 ALC660VD_ASUS_V1S,
f32610ed
JS
163 ALC861VD_3ST,
164 ALC861VD_3ST_DIG,
165 ALC861VD_6ST_DIG,
bdd148a3 166 ALC861VD_LENOVO,
272a527c 167 ALC861VD_DALLAS,
d1a991a6 168 ALC861VD_HP,
f32610ed
JS
169 ALC861VD_AUTO,
170 ALC861VD_MODEL_LAST,
171};
172
bc9f98a9
KY
173/* ALC662 models */
174enum {
175 ALC662_3ST_2ch_DIG,
176 ALC662_3ST_6ch_DIG,
177 ALC662_3ST_6ch,
178 ALC662_5ST_DIG,
179 ALC662_LENOVO_101E,
291702f0 180 ALC662_ASUS_EEEPC_P701,
8c427226 181 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
182 ALC663_ASUS_M51VA,
183 ALC663_ASUS_G71V,
184 ALC663_ASUS_H13,
185 ALC663_ASUS_G50V,
f1d4e28b
KY
186 ALC662_ECS,
187 ALC663_ASUS_MODE1,
188 ALC662_ASUS_MODE2,
189 ALC663_ASUS_MODE3,
190 ALC663_ASUS_MODE4,
191 ALC663_ASUS_MODE5,
192 ALC663_ASUS_MODE6,
ebb83eeb
KY
193 ALC663_ASUS_MODE7,
194 ALC663_ASUS_MODE8,
622e84cd
KY
195 ALC272_DELL,
196 ALC272_DELL_ZM1,
9541ba1d 197 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
198 ALC662_AUTO,
199 ALC662_MODEL_LAST,
200};
201
df694daa
KY
202/* ALC882 models */
203enum {
204 ALC882_3ST_DIG,
205 ALC882_6ST_DIG,
4b146cb0 206 ALC882_ARIMA,
bdd148a3 207 ALC882_W2JC,
272a527c
KY
208 ALC882_TARGA,
209 ALC882_ASUS_A7J,
914759b7 210 ALC882_ASUS_A7M,
9102cd1c 211 ALC885_MACPRO,
76e6f5a9 212 ALC885_MBA21,
87350ad0 213 ALC885_MBP3,
41d5545d 214 ALC885_MB5,
e458b1fa 215 ALC885_MACMINI3,
c54728d8 216 ALC885_IMAC24,
4b7e1803 217 ALC885_IMAC91,
9c7f852e
TI
218 ALC883_3ST_2ch_DIG,
219 ALC883_3ST_6ch_DIG,
220 ALC883_3ST_6ch,
221 ALC883_6ST_DIG,
ccc656ce
KY
222 ALC883_TARGA_DIG,
223 ALC883_TARGA_2ch_DIG,
64a8be74 224 ALC883_TARGA_8ch_DIG,
bab282b9 225 ALC883_ACER,
2880a867 226 ALC883_ACER_ASPIRE,
5b2d1eca 227 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 228 ALC888_ACER_ASPIRE_6530G,
3b315d70 229 ALC888_ACER_ASPIRE_8930G,
fc86f954 230 ALC888_ACER_ASPIRE_7730G,
c07584c8 231 ALC883_MEDION,
ea1fb29a 232 ALC883_MEDION_MD2,
7ad7b218 233 ALC883_MEDION_WIM2160,
b373bdeb 234 ALC883_LAPTOP_EAPD,
bc9f98a9 235 ALC883_LENOVO_101E_2ch,
272a527c 236 ALC883_LENOVO_NB0763,
189609ae 237 ALC888_LENOVO_MS7195_DIG,
e2757d5e 238 ALC888_LENOVO_SKY,
ea1fb29a 239 ALC883_HAIER_W66,
4723c022 240 ALC888_3ST_HP,
5795b9e6 241 ALC888_6ST_DELL,
a8848bd6 242 ALC883_MITAC,
a65cc60f 243 ALC883_CLEVO_M540R,
0c4cc443 244 ALC883_CLEVO_M720,
fb97dc67 245 ALC883_FUJITSU_PI2515,
ef8ef5fb 246 ALC888_FUJITSU_XA3530,
17bba1b7 247 ALC883_3ST_6ch_INTEL,
87a8c370
JK
248 ALC889A_INTEL,
249 ALC889_INTEL,
e2757d5e
KY
250 ALC888_ASUS_M90V,
251 ALC888_ASUS_EEE1601,
eb4c41d3 252 ALC889A_MB31,
3ab90935 253 ALC1200_ASUS_P5Q,
3e1647c5 254 ALC883_SONY_VAIO_TT,
4953550a
TI
255 ALC882_AUTO,
256 ALC882_MODEL_LAST,
9c7f852e
TI
257};
258
d4a86d81
TI
259/* ALC680 models */
260enum {
261 ALC680_BASE,
262 ALC680_AUTO,
263 ALC680_MODEL_LAST,
264};
265
df694daa
KY
266/* for GPIO Poll */
267#define GPIO_MASK 0x03
268
4a79ba34
TI
269/* extra amp-initialization sequence types */
270enum {
271 ALC_INIT_NONE,
272 ALC_INIT_DEFAULT,
273 ALC_INIT_GPIO1,
274 ALC_INIT_GPIO2,
275 ALC_INIT_GPIO3,
276};
277
6c819492
TI
278struct alc_mic_route {
279 hda_nid_t pin;
280 unsigned char mux_idx;
281 unsigned char amix_idx;
282};
283
284#define MUX_IDX_UNDEF ((unsigned char)-1)
285
da00c244
KY
286struct alc_customize_define {
287 unsigned int sku_cfg;
288 unsigned char port_connectivity;
289 unsigned char check_sum;
290 unsigned char customization;
291 unsigned char external_amp;
292 unsigned int enable_pcbeep:1;
293 unsigned int platform_type:1;
294 unsigned int swap:1;
295 unsigned int override:1;
296};
297
1da177e4
LT
298struct alc_spec {
299 /* codec parameterization */
df694daa 300 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 301 unsigned int num_mixers;
f9e336f6 302 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 303 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 304
2d9c6482 305 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
306 * don't forget NULL
307 * termination!
e9edcee0
TI
308 */
309 unsigned int num_init_verbs;
1da177e4 310
aa563af7 311 char stream_name_analog[32]; /* analog PCM stream */
1da177e4
LT
312 struct hda_pcm_stream *stream_analog_playback;
313 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
314 struct hda_pcm_stream *stream_analog_alt_playback;
315 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 316
aa563af7 317 char stream_name_digital[32]; /* digital PCM stream */
1da177e4
LT
318 struct hda_pcm_stream *stream_digital_playback;
319 struct hda_pcm_stream *stream_digital_capture;
320
321 /* playback */
16ded525
TI
322 struct hda_multi_out multiout; /* playback set-up
323 * max_channels, dacs must be set
324 * dig_out_nid and hp_nid are optional
325 */
6330079f 326 hda_nid_t alt_dac_nid;
6a05ac4a 327 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 328 int dig_out_type;
1da177e4
LT
329
330 /* capture */
331 unsigned int num_adc_nids;
332 hda_nid_t *adc_nids;
e1406348 333 hda_nid_t *capsrc_nids;
16ded525 334 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4 335
840b64c0
TI
336 /* capture setup for dynamic dual-adc switch */
337 unsigned int cur_adc_idx;
338 hda_nid_t cur_adc;
339 unsigned int cur_adc_stream_tag;
340 unsigned int cur_adc_format;
341
1da177e4 342 /* capture source */
a1e8d2da 343 unsigned int num_mux_defs;
1da177e4
LT
344 const struct hda_input_mux *input_mux;
345 unsigned int cur_mux[3];
6c819492
TI
346 struct alc_mic_route ext_mic;
347 struct alc_mic_route int_mic;
1da177e4
LT
348
349 /* channel model */
d2a6d7dc 350 const struct hda_channel_mode *channel_mode;
1da177e4 351 int num_channel_mode;
4e195a7b 352 int need_dac_fix;
3b315d70
HM
353 int const_channel_count;
354 int ext_channel_count;
1da177e4
LT
355
356 /* PCM information */
4c5186ed 357 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 358
e9edcee0
TI
359 /* dynamic controls, init_verbs and input_mux */
360 struct auto_pin_cfg autocfg;
da00c244 361 struct alc_customize_define cdefine;
603c4019 362 struct snd_array kctls;
61b9b9b1 363 struct hda_input_mux private_imux[3];
41923e44 364 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
365 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
366 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 367
ae6b813a
TI
368 /* hooks */
369 void (*init_hook)(struct hda_codec *codec);
370 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 371#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 372 void (*power_hook)(struct hda_codec *codec);
f5de24b0 373#endif
ae6b813a 374
834be88d
TI
375 /* for pin sensing */
376 unsigned int sense_updated: 1;
377 unsigned int jack_present: 1;
bec15c3a 378 unsigned int master_sw: 1;
6c819492 379 unsigned int auto_mic:1;
cb53c626 380
e64f14f4
TI
381 /* other flags */
382 unsigned int no_analog :1; /* digital I/O only */
840b64c0 383 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
4a79ba34 384 int init_amp;
e64f14f4 385
2134ea4f
TI
386 /* for virtual master */
387 hda_nid_t vmaster_nid;
cb53c626
TI
388#ifdef CONFIG_SND_HDA_POWER_SAVE
389 struct hda_loopback_check loopback;
390#endif
2c3bf9ab
TI
391
392 /* for PLL fix */
393 hda_nid_t pll_nid;
394 unsigned int pll_coef_idx, pll_coef_bit;
df694daa
KY
395};
396
397/*
398 * configuration template - to be copied to the spec instance
399 */
400struct alc_config_preset {
9c7f852e
TI
401 struct snd_kcontrol_new *mixers[5]; /* should be identical size
402 * with spec
403 */
f9e336f6 404 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
405 const struct hda_verb *init_verbs[5];
406 unsigned int num_dacs;
407 hda_nid_t *dac_nids;
408 hda_nid_t dig_out_nid; /* optional */
409 hda_nid_t hp_nid; /* optional */
b25c9da1 410 hda_nid_t *slave_dig_outs;
df694daa
KY
411 unsigned int num_adc_nids;
412 hda_nid_t *adc_nids;
e1406348 413 hda_nid_t *capsrc_nids;
df694daa
KY
414 hda_nid_t dig_in_nid;
415 unsigned int num_channel_mode;
416 const struct hda_channel_mode *channel_mode;
4e195a7b 417 int need_dac_fix;
3b315d70 418 int const_channel_count;
a1e8d2da 419 unsigned int num_mux_defs;
df694daa 420 const struct hda_input_mux *input_mux;
ae6b813a 421 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 422 void (*setup)(struct hda_codec *);
ae6b813a 423 void (*init_hook)(struct hda_codec *);
cb53c626
TI
424#ifdef CONFIG_SND_HDA_POWER_SAVE
425 struct hda_amp_list *loopbacks;
c97259df 426 void (*power_hook)(struct hda_codec *codec);
cb53c626 427#endif
1da177e4
LT
428};
429
1da177e4
LT
430
431/*
432 * input MUX handling
433 */
9c7f852e
TI
434static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
435 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
436{
437 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
438 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
439 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
440 if (mux_idx >= spec->num_mux_defs)
441 mux_idx = 0;
5311114d
TI
442 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
443 mux_idx = 0;
a1e8d2da 444 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
445}
446
9c7f852e
TI
447static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
448 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
449{
450 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
451 struct alc_spec *spec = codec->spec;
452 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
453
454 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
455 return 0;
456}
457
9c7f852e
TI
458static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
459 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
460{
461 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
462 struct alc_spec *spec = codec->spec;
cd896c33 463 const struct hda_input_mux *imux;
1da177e4 464 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 465 unsigned int mux_idx;
e1406348
TI
466 hda_nid_t nid = spec->capsrc_nids ?
467 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 468 unsigned int type;
1da177e4 469
cd896c33
TI
470 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
471 imux = &spec->input_mux[mux_idx];
5311114d
TI
472 if (!imux->num_items && mux_idx > 0)
473 imux = &spec->input_mux[0];
cd896c33 474
a22d543a 475 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 476 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
477 /* Matrix-mixer style (e.g. ALC882) */
478 unsigned int *cur_val = &spec->cur_mux[adc_idx];
479 unsigned int i, idx;
480
481 idx = ucontrol->value.enumerated.item[0];
482 if (idx >= imux->num_items)
483 idx = imux->num_items - 1;
484 if (*cur_val == idx)
485 return 0;
486 for (i = 0; i < imux->num_items; i++) {
487 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
488 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
489 imux->items[i].index,
490 HDA_AMP_MUTE, v);
491 }
492 *cur_val = idx;
493 return 1;
494 } else {
495 /* MUX style (e.g. ALC880) */
cd896c33 496 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
497 &spec->cur_mux[adc_idx]);
498 }
499}
e9edcee0 500
1da177e4
LT
501/*
502 * channel mode setting
503 */
9c7f852e
TI
504static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
505 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
506{
507 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
508 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
509 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
510 spec->num_channel_mode);
1da177e4
LT
511}
512
9c7f852e
TI
513static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
514 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
515{
516 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
517 struct alc_spec *spec = codec->spec;
d2a6d7dc 518 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 519 spec->num_channel_mode,
3b315d70 520 spec->ext_channel_count);
1da177e4
LT
521}
522
9c7f852e
TI
523static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
524 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
525{
526 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
527 struct alc_spec *spec = codec->spec;
4e195a7b
TI
528 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
529 spec->num_channel_mode,
3b315d70
HM
530 &spec->ext_channel_count);
531 if (err >= 0 && !spec->const_channel_count) {
532 spec->multiout.max_channels = spec->ext_channel_count;
533 if (spec->need_dac_fix)
534 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
535 }
4e195a7b 536 return err;
1da177e4
LT
537}
538
a9430dd8 539/*
4c5186ed 540 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 541 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
542 * being part of a format specifier. Maximum allowed length of a value is
543 * 63 characters plus NULL terminator.
7cf51e48
JW
544 *
545 * Note: some retasking pin complexes seem to ignore requests for input
546 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
547 * are requested. Therefore order this list so that this behaviour will not
548 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
549 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
550 * March 2006.
4c5186ed
JW
551 */
552static char *alc_pin_mode_names[] = {
7cf51e48
JW
553 "Mic 50pc bias", "Mic 80pc bias",
554 "Line in", "Line out", "Headphone out",
4c5186ed
JW
555};
556static unsigned char alc_pin_mode_values[] = {
7cf51e48 557 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
558};
559/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
560 * in the pin being assumed to be exclusively an input or an output pin. In
561 * addition, "input" pins may or may not process the mic bias option
562 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
563 * accept requests for bias as of chip versions up to March 2006) and/or
564 * wiring in the computer.
a9430dd8 565 */
a1e8d2da
JW
566#define ALC_PIN_DIR_IN 0x00
567#define ALC_PIN_DIR_OUT 0x01
568#define ALC_PIN_DIR_INOUT 0x02
569#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
570#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 571
ea1fb29a 572/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
573 * For each direction the minimum and maximum values are given.
574 */
a1e8d2da 575static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
576 { 0, 2 }, /* ALC_PIN_DIR_IN */
577 { 3, 4 }, /* ALC_PIN_DIR_OUT */
578 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
579 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
580 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
581};
582#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
583#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
584#define alc_pin_mode_n_items(_dir) \
585 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
586
9c7f852e
TI
587static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
588 struct snd_ctl_elem_info *uinfo)
a9430dd8 589{
4c5186ed
JW
590 unsigned int item_num = uinfo->value.enumerated.item;
591 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
592
593 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 594 uinfo->count = 1;
4c5186ed
JW
595 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
596
597 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
598 item_num = alc_pin_mode_min(dir);
599 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
600 return 0;
601}
602
9c7f852e
TI
603static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
604 struct snd_ctl_elem_value *ucontrol)
a9430dd8 605{
4c5186ed 606 unsigned int i;
a9430dd8
JW
607 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
608 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 609 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 610 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
611 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
612 AC_VERB_GET_PIN_WIDGET_CONTROL,
613 0x00);
a9430dd8 614
4c5186ed
JW
615 /* Find enumerated value for current pinctl setting */
616 i = alc_pin_mode_min(dir);
4b35d2ca 617 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 618 i++;
9c7f852e 619 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
620 return 0;
621}
622
9c7f852e
TI
623static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
624 struct snd_ctl_elem_value *ucontrol)
a9430dd8 625{
4c5186ed 626 signed int change;
a9430dd8
JW
627 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
628 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
629 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
630 long val = *ucontrol->value.integer.value;
9c7f852e
TI
631 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
632 AC_VERB_GET_PIN_WIDGET_CONTROL,
633 0x00);
a9430dd8 634
f12ab1e0 635 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
636 val = alc_pin_mode_min(dir);
637
638 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
639 if (change) {
640 /* Set pin mode to that requested */
82beb8fd
TI
641 snd_hda_codec_write_cache(codec, nid, 0,
642 AC_VERB_SET_PIN_WIDGET_CONTROL,
643 alc_pin_mode_values[val]);
cdcd9268 644
ea1fb29a 645 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
646 * for the requested pin mode. Enum values of 2 or less are
647 * input modes.
648 *
649 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
650 * reduces noise slightly (particularly on input) so we'll
651 * do it. However, having both input and output buffers
652 * enabled simultaneously doesn't seem to be problematic if
653 * this turns out to be necessary in the future.
cdcd9268
JW
654 */
655 if (val <= 2) {
47fd830a
TI
656 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
657 HDA_AMP_MUTE, HDA_AMP_MUTE);
658 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
659 HDA_AMP_MUTE, 0);
cdcd9268 660 } else {
47fd830a
TI
661 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
662 HDA_AMP_MUTE, HDA_AMP_MUTE);
663 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
664 HDA_AMP_MUTE, 0);
cdcd9268
JW
665 }
666 }
a9430dd8
JW
667 return change;
668}
669
4c5186ed 670#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 671 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 672 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
673 .info = alc_pin_mode_info, \
674 .get = alc_pin_mode_get, \
675 .put = alc_pin_mode_put, \
676 .private_value = nid | (dir<<16) }
df694daa 677
5c8f858d
JW
678/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
679 * together using a mask with more than one bit set. This control is
680 * currently used only by the ALC260 test model. At this stage they are not
681 * needed for any "production" models.
682 */
683#ifdef CONFIG_SND_DEBUG
a5ce8890 684#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 685
9c7f852e
TI
686static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
687 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
688{
689 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
690 hda_nid_t nid = kcontrol->private_value & 0xffff;
691 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
692 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
693 unsigned int val = snd_hda_codec_read(codec, nid, 0,
694 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
695
696 *valp = (val & mask) != 0;
697 return 0;
698}
9c7f852e
TI
699static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
700 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
701{
702 signed int change;
703 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
704 hda_nid_t nid = kcontrol->private_value & 0xffff;
705 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
706 long val = *ucontrol->value.integer.value;
9c7f852e
TI
707 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
708 AC_VERB_GET_GPIO_DATA,
709 0x00);
5c8f858d
JW
710
711 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
712 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
713 if (val == 0)
5c8f858d
JW
714 gpio_data &= ~mask;
715 else
716 gpio_data |= mask;
82beb8fd
TI
717 snd_hda_codec_write_cache(codec, nid, 0,
718 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
719
720 return change;
721}
722#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
723 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 724 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
725 .info = alc_gpio_data_info, \
726 .get = alc_gpio_data_get, \
727 .put = alc_gpio_data_put, \
728 .private_value = nid | (mask<<16) }
729#endif /* CONFIG_SND_DEBUG */
730
92621f13
JW
731/* A switch control to allow the enabling of the digital IO pins on the
732 * ALC260. This is incredibly simplistic; the intention of this control is
733 * to provide something in the test model allowing digital outputs to be
734 * identified if present. If models are found which can utilise these
735 * outputs a more complete mixer control can be devised for those models if
736 * necessary.
737 */
738#ifdef CONFIG_SND_DEBUG
a5ce8890 739#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 740
9c7f852e
TI
741static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
742 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
743{
744 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
745 hda_nid_t nid = kcontrol->private_value & 0xffff;
746 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
747 long *valp = ucontrol->value.integer.value;
9c7f852e 748 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 749 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
750
751 *valp = (val & mask) != 0;
752 return 0;
753}
9c7f852e
TI
754static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
755 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
756{
757 signed int change;
758 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
759 hda_nid_t nid = kcontrol->private_value & 0xffff;
760 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
761 long val = *ucontrol->value.integer.value;
9c7f852e 762 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 763 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 764 0x00);
92621f13
JW
765
766 /* Set/unset the masked control bit(s) as needed */
9c7f852e 767 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
768 if (val==0)
769 ctrl_data &= ~mask;
770 else
771 ctrl_data |= mask;
82beb8fd
TI
772 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
773 ctrl_data);
92621f13
JW
774
775 return change;
776}
777#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
778 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 779 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
780 .info = alc_spdif_ctrl_info, \
781 .get = alc_spdif_ctrl_get, \
782 .put = alc_spdif_ctrl_put, \
783 .private_value = nid | (mask<<16) }
784#endif /* CONFIG_SND_DEBUG */
785
f8225f6d
JW
786/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
787 * Again, this is only used in the ALC26x test models to help identify when
788 * the EAPD line must be asserted for features to work.
789 */
790#ifdef CONFIG_SND_DEBUG
791#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
792
793static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
794 struct snd_ctl_elem_value *ucontrol)
795{
796 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
797 hda_nid_t nid = kcontrol->private_value & 0xffff;
798 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
799 long *valp = ucontrol->value.integer.value;
800 unsigned int val = snd_hda_codec_read(codec, nid, 0,
801 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
802
803 *valp = (val & mask) != 0;
804 return 0;
805}
806
807static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
808 struct snd_ctl_elem_value *ucontrol)
809{
810 int change;
811 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
812 hda_nid_t nid = kcontrol->private_value & 0xffff;
813 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
814 long val = *ucontrol->value.integer.value;
815 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
816 AC_VERB_GET_EAPD_BTLENABLE,
817 0x00);
818
819 /* Set/unset the masked control bit(s) as needed */
820 change = (!val ? 0 : mask) != (ctrl_data & mask);
821 if (!val)
822 ctrl_data &= ~mask;
823 else
824 ctrl_data |= mask;
825 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
826 ctrl_data);
827
828 return change;
829}
830
831#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
832 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 833 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
834 .info = alc_eapd_ctrl_info, \
835 .get = alc_eapd_ctrl_get, \
836 .put = alc_eapd_ctrl_put, \
837 .private_value = nid | (mask<<16) }
838#endif /* CONFIG_SND_DEBUG */
839
23f0c048
TI
840/*
841 * set up the input pin config (depending on the given auto-pin type)
842 */
843static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
844 int auto_pin_type)
845{
846 unsigned int val = PIN_IN;
847
848 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
849 unsigned int pincap;
954a29c8
TI
850 unsigned int oldval;
851 oldval = snd_hda_codec_read(codec, nid, 0,
852 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1327a32b 853 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048 854 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
954a29c8
TI
855 /* if the default pin setup is vref50, we give it priority */
856 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
23f0c048 857 val = PIN_VREF80;
461c6c3a
TI
858 else if (pincap & AC_PINCAP_VREF_50)
859 val = PIN_VREF50;
860 else if (pincap & AC_PINCAP_VREF_100)
861 val = PIN_VREF100;
862 else if (pincap & AC_PINCAP_VREF_GRD)
863 val = PIN_VREFGRD;
23f0c048
TI
864 }
865 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
866}
867
d88897ea
TI
868/*
869 */
870static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
871{
872 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
873 return;
874 spec->mixers[spec->num_mixers++] = mix;
875}
876
877static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
878{
879 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
880 return;
881 spec->init_verbs[spec->num_init_verbs++] = verb;
882}
883
df694daa
KY
884/*
885 * set up from the preset table
886 */
e9c364c0 887static void setup_preset(struct hda_codec *codec,
9c7f852e 888 const struct alc_config_preset *preset)
df694daa 889{
e9c364c0 890 struct alc_spec *spec = codec->spec;
df694daa
KY
891 int i;
892
893 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 894 add_mixer(spec, preset->mixers[i]);
f9e336f6 895 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
896 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
897 i++)
d88897ea 898 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 899
df694daa
KY
900 spec->channel_mode = preset->channel_mode;
901 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 902 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 903 spec->const_channel_count = preset->const_channel_count;
df694daa 904
3b315d70
HM
905 if (preset->const_channel_count)
906 spec->multiout.max_channels = preset->const_channel_count;
907 else
908 spec->multiout.max_channels = spec->channel_mode[0].channels;
909 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
910
911 spec->multiout.num_dacs = preset->num_dacs;
912 spec->multiout.dac_nids = preset->dac_nids;
913 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 914 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 915 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 916
a1e8d2da 917 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 918 if (!spec->num_mux_defs)
a1e8d2da 919 spec->num_mux_defs = 1;
df694daa
KY
920 spec->input_mux = preset->input_mux;
921
922 spec->num_adc_nids = preset->num_adc_nids;
923 spec->adc_nids = preset->adc_nids;
e1406348 924 spec->capsrc_nids = preset->capsrc_nids;
df694daa 925 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
926
927 spec->unsol_event = preset->unsol_event;
928 spec->init_hook = preset->init_hook;
cb53c626 929#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 930 spec->power_hook = preset->power_hook;
cb53c626
TI
931 spec->loopback.amplist = preset->loopbacks;
932#endif
e9c364c0
TI
933
934 if (preset->setup)
935 preset->setup(codec);
df694daa
KY
936}
937
bc9f98a9
KY
938/* Enable GPIO mask and set output */
939static struct hda_verb alc_gpio1_init_verbs[] = {
940 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
941 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
942 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
943 { }
944};
945
946static struct hda_verb alc_gpio2_init_verbs[] = {
947 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
948 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
949 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
950 { }
951};
952
bdd148a3
KY
953static struct hda_verb alc_gpio3_init_verbs[] = {
954 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
955 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
956 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
957 { }
958};
959
2c3bf9ab
TI
960/*
961 * Fix hardware PLL issue
962 * On some codecs, the analog PLL gating control must be off while
963 * the default value is 1.
964 */
965static void alc_fix_pll(struct hda_codec *codec)
966{
967 struct alc_spec *spec = codec->spec;
968 unsigned int val;
969
970 if (!spec->pll_nid)
971 return;
972 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
973 spec->pll_coef_idx);
974 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
975 AC_VERB_GET_PROC_COEF, 0);
976 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
977 spec->pll_coef_idx);
978 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
979 val & ~(1 << spec->pll_coef_bit));
980}
981
982static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
983 unsigned int coef_idx, unsigned int coef_bit)
984{
985 struct alc_spec *spec = codec->spec;
986 spec->pll_nid = nid;
987 spec->pll_coef_idx = coef_idx;
988 spec->pll_coef_bit = coef_bit;
989 alc_fix_pll(codec);
990}
991
a9fd4f3f 992static void alc_automute_pin(struct hda_codec *codec)
c9b58006
KY
993{
994 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
995 unsigned int nid = spec->autocfg.hp_pins[0];
996 int i;
c9b58006 997
ad87c64f
TI
998 if (!nid)
999 return;
864f92be 1000 spec->jack_present = snd_hda_jack_detect(codec, nid);
a9fd4f3f
TI
1001 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1002 nid = spec->autocfg.speaker_pins[i];
1003 if (!nid)
1004 break;
1005 snd_hda_codec_write(codec, nid, 0,
1006 AC_VERB_SET_PIN_WIDGET_CONTROL,
1007 spec->jack_present ? 0 : PIN_OUT);
1008 }
c9b58006
KY
1009}
1010
6c819492
TI
1011static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1012 hda_nid_t nid)
1013{
1014 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1015 int i, nums;
1016
1017 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1018 for (i = 0; i < nums; i++)
1019 if (conn[i] == nid)
1020 return i;
1021 return -1;
1022}
1023
840b64c0
TI
1024/* switch the current ADC according to the jack state */
1025static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1026{
1027 struct alc_spec *spec = codec->spec;
1028 unsigned int present;
1029 hda_nid_t new_adc;
1030
1031 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1032 if (present)
1033 spec->cur_adc_idx = 1;
1034 else
1035 spec->cur_adc_idx = 0;
1036 new_adc = spec->adc_nids[spec->cur_adc_idx];
1037 if (spec->cur_adc && spec->cur_adc != new_adc) {
1038 /* stream is running, let's swap the current ADC */
1039 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
1040 spec->cur_adc = new_adc;
1041 snd_hda_codec_setup_stream(codec, new_adc,
1042 spec->cur_adc_stream_tag, 0,
1043 spec->cur_adc_format);
1044 }
1045}
1046
7fb0d78f
KY
1047static void alc_mic_automute(struct hda_codec *codec)
1048{
1049 struct alc_spec *spec = codec->spec;
6c819492
TI
1050 struct alc_mic_route *dead, *alive;
1051 unsigned int present, type;
1052 hda_nid_t cap_nid;
1053
b59bdf3b
TI
1054 if (!spec->auto_mic)
1055 return;
6c819492
TI
1056 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1057 return;
1058 if (snd_BUG_ON(!spec->adc_nids))
1059 return;
1060
840b64c0
TI
1061 if (spec->dual_adc_switch) {
1062 alc_dual_mic_adc_auto_switch(codec);
1063 return;
1064 }
1065
6c819492
TI
1066 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1067
864f92be 1068 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1069 if (present) {
1070 alive = &spec->ext_mic;
1071 dead = &spec->int_mic;
1072 } else {
1073 alive = &spec->int_mic;
1074 dead = &spec->ext_mic;
1075 }
1076
6c819492
TI
1077 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1078 if (type == AC_WID_AUD_MIX) {
1079 /* Matrix-mixer style (e.g. ALC882) */
1080 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1081 alive->mux_idx,
1082 HDA_AMP_MUTE, 0);
1083 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1084 dead->mux_idx,
1085 HDA_AMP_MUTE, HDA_AMP_MUTE);
1086 } else {
1087 /* MUX style (e.g. ALC880) */
1088 snd_hda_codec_write_cache(codec, cap_nid, 0,
1089 AC_VERB_SET_CONNECT_SEL,
1090 alive->mux_idx);
1091 }
1092
1093 /* FIXME: analog mixer */
7fb0d78f
KY
1094}
1095
c9b58006
KY
1096/* unsolicited event for HP jack sensing */
1097static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1098{
1099 if (codec->vendor_id == 0x10ec0880)
1100 res >>= 28;
1101 else
1102 res >>= 26;
a9fd4f3f
TI
1103 switch (res) {
1104 case ALC880_HP_EVENT:
1105 alc_automute_pin(codec);
1106 break;
1107 case ALC880_MIC_EVENT:
7fb0d78f 1108 alc_mic_automute(codec);
a9fd4f3f
TI
1109 break;
1110 }
7fb0d78f
KY
1111}
1112
1113static void alc_inithook(struct hda_codec *codec)
1114{
a9fd4f3f 1115 alc_automute_pin(codec);
7fb0d78f 1116 alc_mic_automute(codec);
c9b58006
KY
1117}
1118
f9423e7a
KY
1119/* additional initialization for ALC888 variants */
1120static void alc888_coef_init(struct hda_codec *codec)
1121{
1122 unsigned int tmp;
1123
1124 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1125 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1126 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1127 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1128 /* alc888S-VC */
1129 snd_hda_codec_read(codec, 0x20, 0,
1130 AC_VERB_SET_PROC_COEF, 0x830);
1131 else
1132 /* alc888-VB */
1133 snd_hda_codec_read(codec, 0x20, 0,
1134 AC_VERB_SET_PROC_COEF, 0x3030);
1135}
1136
87a8c370
JK
1137static void alc889_coef_init(struct hda_codec *codec)
1138{
1139 unsigned int tmp;
1140
1141 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1142 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1143 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1144 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1145}
1146
3fb4a508
TI
1147/* turn on/off EAPD control (only if available) */
1148static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1149{
1150 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1151 return;
1152 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1153 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1154 on ? 2 : 0);
1155}
1156
4a79ba34 1157static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1158{
4a79ba34 1159 unsigned int tmp;
bc9f98a9 1160
4a79ba34
TI
1161 switch (type) {
1162 case ALC_INIT_GPIO1:
bc9f98a9
KY
1163 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1164 break;
4a79ba34 1165 case ALC_INIT_GPIO2:
bc9f98a9
KY
1166 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1167 break;
4a79ba34 1168 case ALC_INIT_GPIO3:
bdd148a3
KY
1169 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1170 break;
4a79ba34 1171 case ALC_INIT_DEFAULT:
bdd148a3 1172 switch (codec->vendor_id) {
c9b58006 1173 case 0x10ec0260:
3fb4a508
TI
1174 set_eapd(codec, 0x0f, 1);
1175 set_eapd(codec, 0x10, 1);
c9b58006
KY
1176 break;
1177 case 0x10ec0262:
bdd148a3
KY
1178 case 0x10ec0267:
1179 case 0x10ec0268:
c9b58006 1180 case 0x10ec0269:
3fb4a508 1181 case 0x10ec0270:
c6e8f2da 1182 case 0x10ec0272:
f9423e7a
KY
1183 case 0x10ec0660:
1184 case 0x10ec0662:
1185 case 0x10ec0663:
c9b58006 1186 case 0x10ec0862:
20a3a05d 1187 case 0x10ec0889:
3fb4a508
TI
1188 set_eapd(codec, 0x14, 1);
1189 set_eapd(codec, 0x15, 1);
c9b58006 1190 break;
bdd148a3 1191 }
c9b58006
KY
1192 switch (codec->vendor_id) {
1193 case 0x10ec0260:
1194 snd_hda_codec_write(codec, 0x1a, 0,
1195 AC_VERB_SET_COEF_INDEX, 7);
1196 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1197 AC_VERB_GET_PROC_COEF, 0);
1198 snd_hda_codec_write(codec, 0x1a, 0,
1199 AC_VERB_SET_COEF_INDEX, 7);
1200 snd_hda_codec_write(codec, 0x1a, 0,
1201 AC_VERB_SET_PROC_COEF,
1202 tmp | 0x2010);
1203 break;
1204 case 0x10ec0262:
1205 case 0x10ec0880:
1206 case 0x10ec0882:
1207 case 0x10ec0883:
1208 case 0x10ec0885:
4a5a4c56 1209 case 0x10ec0887:
20a3a05d 1210 case 0x10ec0889:
87a8c370 1211 alc889_coef_init(codec);
c9b58006 1212 break;
f9423e7a 1213 case 0x10ec0888:
4a79ba34 1214 alc888_coef_init(codec);
f9423e7a 1215 break;
0aea778e 1216#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1217 case 0x10ec0267:
1218 case 0x10ec0268:
1219 snd_hda_codec_write(codec, 0x20, 0,
1220 AC_VERB_SET_COEF_INDEX, 7);
1221 tmp = snd_hda_codec_read(codec, 0x20, 0,
1222 AC_VERB_GET_PROC_COEF, 0);
1223 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1224 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1225 snd_hda_codec_write(codec, 0x20, 0,
1226 AC_VERB_SET_PROC_COEF,
1227 tmp | 0x3000);
1228 break;
0aea778e 1229#endif /* XXX */
bc9f98a9 1230 }
4a79ba34
TI
1231 break;
1232 }
1233}
1234
1235static void alc_init_auto_hp(struct hda_codec *codec)
1236{
1237 struct alc_spec *spec = codec->spec;
1238
1239 if (!spec->autocfg.hp_pins[0])
1240 return;
1241
1242 if (!spec->autocfg.speaker_pins[0]) {
2a2ed0df
TI
1243 if (spec->autocfg.line_out_pins[0] &&
1244 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
4a79ba34
TI
1245 spec->autocfg.speaker_pins[0] =
1246 spec->autocfg.line_out_pins[0];
1247 else
1248 return;
1249 }
1250
2a2ed0df
TI
1251 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1252 spec->autocfg.hp_pins[0]);
4a79ba34
TI
1253 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1254 AC_VERB_SET_UNSOLICITED_ENABLE,
1255 AC_USRSP_EN | ALC880_HP_EVENT);
1256 spec->unsol_event = alc_sku_unsol_event;
1257}
1258
6c819492
TI
1259static void alc_init_auto_mic(struct hda_codec *codec)
1260{
1261 struct alc_spec *spec = codec->spec;
1262 struct auto_pin_cfg *cfg = &spec->autocfg;
1263 hda_nid_t fixed, ext;
1264 int i;
1265
1266 /* there must be only two mic inputs exclusively */
1267 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++)
1268 if (cfg->input_pins[i])
1269 return;
1270
1271 fixed = ext = 0;
1272 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) {
1273 hda_nid_t nid = cfg->input_pins[i];
1274 unsigned int defcfg;
1275 if (!nid)
1276 return;
1277 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1278 switch (get_defcfg_connect(defcfg)) {
1279 case AC_JACK_PORT_FIXED:
1280 if (fixed)
1281 return; /* already occupied */
1282 fixed = nid;
1283 break;
1284 case AC_JACK_PORT_COMPLEX:
1285 if (ext)
1286 return; /* already occupied */
1287 ext = nid;
1288 break;
1289 default:
1290 return; /* invalid entry */
1291 }
1292 }
eaa9b3a7
TI
1293 if (!ext || !fixed)
1294 return;
6c819492
TI
1295 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1296 return; /* no unsol support */
1297 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1298 ext, fixed);
1299 spec->ext_mic.pin = ext;
1300 spec->int_mic.pin = fixed;
1301 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1302 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1303 spec->auto_mic = 1;
1304 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1305 AC_VERB_SET_UNSOLICITED_ENABLE,
1306 AC_USRSP_EN | ALC880_MIC_EVENT);
1307 spec->unsol_event = alc_sku_unsol_event;
1308}
1309
da00c244
KY
1310static int alc_auto_parse_customize_define(struct hda_codec *codec)
1311{
1312 unsigned int ass, tmp, i;
7fb56223 1313 unsigned nid = 0;
da00c244
KY
1314 struct alc_spec *spec = codec->spec;
1315
b6cbe517
TI
1316 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1317
da00c244 1318 ass = codec->subsystem_id & 0xffff;
b6cbe517 1319 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1320 goto do_sku;
1321
1322 nid = 0x1d;
1323 if (codec->vendor_id == 0x10ec0260)
1324 nid = 0x17;
1325 ass = snd_hda_codec_get_pincfg(codec, nid);
1326
1327 if (!(ass & 1)) {
1328 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1329 codec->chip_name, ass);
1330 return -1;
1331 }
1332
1333 /* check sum */
1334 tmp = 0;
1335 for (i = 1; i < 16; i++) {
1336 if ((ass >> i) & 1)
1337 tmp++;
1338 }
1339 if (((ass >> 16) & 0xf) != tmp)
1340 return -1;
1341
1342 spec->cdefine.port_connectivity = ass >> 30;
1343 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1344 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1345 spec->cdefine.customization = ass >> 8;
1346do_sku:
1347 spec->cdefine.sku_cfg = ass;
1348 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1349 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1350 spec->cdefine.swap = (ass & 0x2) >> 1;
1351 spec->cdefine.override = ass & 0x1;
1352
1353 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1354 nid, spec->cdefine.sku_cfg);
1355 snd_printd("SKU: port_connectivity=0x%x\n",
1356 spec->cdefine.port_connectivity);
1357 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1358 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1359 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1360 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1361 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1362 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1363 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1364
1365 return 0;
1366}
1367
4a79ba34
TI
1368/* check subsystem ID and set up device-specific initialization;
1369 * return 1 if initialized, 0 if invalid SSID
1370 */
1371/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1372 * 31 ~ 16 : Manufacture ID
1373 * 15 ~ 8 : SKU ID
1374 * 7 ~ 0 : Assembly ID
1375 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1376 */
1377static int alc_subsystem_id(struct hda_codec *codec,
1378 hda_nid_t porta, hda_nid_t porte,
6227cdce 1379 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1380{
1381 unsigned int ass, tmp, i;
1382 unsigned nid;
1383 struct alc_spec *spec = codec->spec;
1384
1385 ass = codec->subsystem_id & 0xffff;
1386 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1387 goto do_sku;
1388
1389 /* invalid SSID, check the special NID pin defcfg instead */
1390 /*
def319f9 1391 * 31~30 : port connectivity
4a79ba34
TI
1392 * 29~21 : reserve
1393 * 20 : PCBEEP input
1394 * 19~16 : Check sum (15:1)
1395 * 15~1 : Custom
1396 * 0 : override
1397 */
1398 nid = 0x1d;
1399 if (codec->vendor_id == 0x10ec0260)
1400 nid = 0x17;
1401 ass = snd_hda_codec_get_pincfg(codec, nid);
1402 snd_printd("realtek: No valid SSID, "
1403 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1404 ass, nid);
6227cdce 1405 if (!(ass & 1))
4a79ba34
TI
1406 return 0;
1407 if ((ass >> 30) != 1) /* no physical connection */
1408 return 0;
1409
1410 /* check sum */
1411 tmp = 0;
1412 for (i = 1; i < 16; i++) {
1413 if ((ass >> i) & 1)
1414 tmp++;
1415 }
1416 if (((ass >> 16) & 0xf) != tmp)
1417 return 0;
1418do_sku:
1419 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1420 ass & 0xffff, codec->vendor_id);
1421 /*
1422 * 0 : override
1423 * 1 : Swap Jack
1424 * 2 : 0 --> Desktop, 1 --> Laptop
1425 * 3~5 : External Amplifier control
1426 * 7~6 : Reserved
1427 */
1428 tmp = (ass & 0x38) >> 3; /* external Amp control */
1429 switch (tmp) {
1430 case 1:
1431 spec->init_amp = ALC_INIT_GPIO1;
1432 break;
1433 case 3:
1434 spec->init_amp = ALC_INIT_GPIO2;
1435 break;
1436 case 7:
1437 spec->init_amp = ALC_INIT_GPIO3;
1438 break;
1439 case 5:
1440 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1441 break;
1442 }
ea1fb29a 1443
8c427226 1444 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1445 * when the external headphone out jack is plugged"
1446 */
8c427226 1447 if (!(ass & 0x8000))
4a79ba34 1448 return 1;
c9b58006
KY
1449 /*
1450 * 10~8 : Jack location
1451 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1452 * 14~13: Resvered
1453 * 15 : 1 --> enable the function "Mute internal speaker
1454 * when the external headphone out jack is plugged"
1455 */
c9b58006 1456 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1457 hda_nid_t nid;
c9b58006
KY
1458 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1459 if (tmp == 0)
01d4825d 1460 nid = porta;
c9b58006 1461 else if (tmp == 1)
01d4825d 1462 nid = porte;
c9b58006 1463 else if (tmp == 2)
01d4825d 1464 nid = portd;
6227cdce
KY
1465 else if (tmp == 3)
1466 nid = porti;
c9b58006 1467 else
4a79ba34 1468 return 1;
01d4825d
TI
1469 for (i = 0; i < spec->autocfg.line_outs; i++)
1470 if (spec->autocfg.line_out_pins[i] == nid)
1471 return 1;
1472 spec->autocfg.hp_pins[0] = nid;
c9b58006
KY
1473 }
1474
4a79ba34 1475 alc_init_auto_hp(codec);
6c819492 1476 alc_init_auto_mic(codec);
4a79ba34
TI
1477 return 1;
1478}
ea1fb29a 1479
4a79ba34 1480static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1481 hda_nid_t porta, hda_nid_t porte,
1482 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1483{
6227cdce 1484 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1485 struct alc_spec *spec = codec->spec;
1486 snd_printd("realtek: "
1487 "Enable default setup for auto mode as fallback\n");
1488 spec->init_amp = ALC_INIT_DEFAULT;
1489 alc_init_auto_hp(codec);
6c819492 1490 alc_init_auto_mic(codec);
4a79ba34 1491 }
bc9f98a9
KY
1492}
1493
f95474ec 1494/*
f8f25ba3 1495 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1496 */
1497
1498struct alc_pincfg {
1499 hda_nid_t nid;
1500 u32 val;
1501};
1502
f8f25ba3
TI
1503struct alc_fixup {
1504 const struct alc_pincfg *pins;
1505 const struct hda_verb *verbs;
1506};
1507
1508static void alc_pick_fixup(struct hda_codec *codec,
f95474ec 1509 const struct snd_pci_quirk *quirk,
7fa90e87
TI
1510 const struct alc_fixup *fix,
1511 int pre_init)
f95474ec
TI
1512{
1513 const struct alc_pincfg *cfg;
1514
1515 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1516 if (!quirk)
1517 return;
f8f25ba3
TI
1518 fix += quirk->value;
1519 cfg = fix->pins;
7fa90e87
TI
1520 if (pre_init && cfg) {
1521#ifdef CONFIG_SND_DEBUG_VERBOSE
1522 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
1523 codec->chip_name, quirk->name);
1524#endif
f8f25ba3
TI
1525 for (; cfg->nid; cfg++)
1526 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1527 }
7fa90e87
TI
1528 if (!pre_init && fix->verbs) {
1529#ifdef CONFIG_SND_DEBUG_VERBOSE
1530 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
1531 codec->chip_name, quirk->name);
1532#endif
f8f25ba3 1533 add_verb(codec->spec, fix->verbs);
7fa90e87 1534 }
f95474ec
TI
1535}
1536
274693f3
KY
1537static int alc_read_coef_idx(struct hda_codec *codec,
1538 unsigned int coef_idx)
1539{
1540 unsigned int val;
1541 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1542 coef_idx);
1543 val = snd_hda_codec_read(codec, 0x20, 0,
1544 AC_VERB_GET_PROC_COEF, 0);
1545 return val;
1546}
1547
757899ac
TI
1548/* set right pin controls for digital I/O */
1549static void alc_auto_init_digital(struct hda_codec *codec)
1550{
1551 struct alc_spec *spec = codec->spec;
1552 int i;
1553 hda_nid_t pin;
1554
1555 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1556 pin = spec->autocfg.dig_out_pins[i];
1557 if (pin) {
1558 snd_hda_codec_write(codec, pin, 0,
1559 AC_VERB_SET_PIN_WIDGET_CONTROL,
1560 PIN_OUT);
1561 }
1562 }
1563 pin = spec->autocfg.dig_in_pin;
1564 if (pin)
1565 snd_hda_codec_write(codec, pin, 0,
1566 AC_VERB_SET_PIN_WIDGET_CONTROL,
1567 PIN_IN);
1568}
1569
1570/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1571static void alc_auto_parse_digital(struct hda_codec *codec)
1572{
1573 struct alc_spec *spec = codec->spec;
1574 int i, err;
1575 hda_nid_t dig_nid;
1576
1577 /* support multiple SPDIFs; the secondary is set up as a slave */
1578 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1579 err = snd_hda_get_connections(codec,
1580 spec->autocfg.dig_out_pins[i],
1581 &dig_nid, 1);
1582 if (err < 0)
1583 continue;
1584 if (!i) {
1585 spec->multiout.dig_out_nid = dig_nid;
1586 spec->dig_out_type = spec->autocfg.dig_out_type[0];
1587 } else {
1588 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1589 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1590 break;
1591 spec->slave_dig_outs[i - 1] = dig_nid;
1592 }
1593 }
1594
1595 if (spec->autocfg.dig_in_pin) {
1596 hda_nid_t dig_nid;
1597 err = snd_hda_get_connections(codec,
1598 spec->autocfg.dig_in_pin,
1599 &dig_nid, 1);
1600 if (err > 0)
1601 spec->dig_in_nid = dig_nid;
1602 }
1603}
1604
ef8ef5fb
VP
1605/*
1606 * ALC888
1607 */
1608
1609/*
1610 * 2ch mode
1611 */
1612static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1613/* Mic-in jack as mic in */
1614 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1615 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1616/* Line-in jack as Line in */
1617 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1618 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1619/* Line-Out as Front */
1620 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1621 { } /* end */
1622};
1623
1624/*
1625 * 4ch mode
1626 */
1627static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1628/* Mic-in jack as mic in */
1629 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1630 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1631/* Line-in jack as Surround */
1632 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1633 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1634/* Line-Out as Front */
1635 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1636 { } /* end */
1637};
1638
1639/*
1640 * 6ch mode
1641 */
1642static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1643/* Mic-in jack as CLFE */
1644 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1645 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1646/* Line-in jack as Surround */
1647 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1648 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1649/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1650 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1651 { } /* end */
1652};
1653
1654/*
1655 * 8ch mode
1656 */
1657static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1658/* Mic-in jack as CLFE */
1659 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1660 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1661/* Line-in jack as Surround */
1662 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1663 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1664/* Line-Out as Side */
1665 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1666 { } /* end */
1667};
1668
1669static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1670 { 2, alc888_4ST_ch2_intel_init },
1671 { 4, alc888_4ST_ch4_intel_init },
1672 { 6, alc888_4ST_ch6_intel_init },
1673 { 8, alc888_4ST_ch8_intel_init },
1674};
1675
1676/*
1677 * ALC888 Fujitsu Siemens Amillo xa3530
1678 */
1679
1680static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1681/* Front Mic: set to PIN_IN (empty by default) */
1682 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1683/* Connect Internal HP to Front */
1684 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1685 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1686 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1687/* Connect Bass HP to Front */
1688 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1689 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1690 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1691/* Connect Line-Out side jack (SPDIF) to Side */
1692 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1693 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1694 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1695/* Connect Mic jack to CLFE */
1696 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1697 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1698 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1699/* Connect Line-in jack to Surround */
1700 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1701 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1702 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1703/* Connect HP out jack to Front */
1704 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1705 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1706 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1707/* Enable unsolicited event for HP jack and Line-out jack */
1708 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1709 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1710 {}
1711};
1712
a9fd4f3f 1713static void alc_automute_amp(struct hda_codec *codec)
ef8ef5fb 1714{
a9fd4f3f 1715 struct alc_spec *spec = codec->spec;
864f92be 1716 unsigned int mute;
a9fd4f3f
TI
1717 hda_nid_t nid;
1718 int i;
1719
1720 spec->jack_present = 0;
1721 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1722 nid = spec->autocfg.hp_pins[i];
1723 if (!nid)
1724 break;
864f92be 1725 if (snd_hda_jack_detect(codec, nid)) {
a9fd4f3f
TI
1726 spec->jack_present = 1;
1727 break;
1728 }
1729 }
1730
1731 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
ef8ef5fb 1732 /* Toggle internal speakers muting */
a9fd4f3f
TI
1733 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1734 nid = spec->autocfg.speaker_pins[i];
1735 if (!nid)
1736 break;
1737 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1738 HDA_AMP_MUTE, mute);
1739 }
ef8ef5fb
VP
1740}
1741
a9fd4f3f
TI
1742static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1743 unsigned int res)
ef8ef5fb 1744{
a9fd4f3f
TI
1745 if (codec->vendor_id == 0x10ec0880)
1746 res >>= 28;
1747 else
1748 res >>= 26;
1749 if (res == ALC880_HP_EVENT)
1750 alc_automute_amp(codec);
ef8ef5fb
VP
1751}
1752
4f5d1706 1753static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
1754{
1755 struct alc_spec *spec = codec->spec;
1756
1757 spec->autocfg.hp_pins[0] = 0x15;
1758 spec->autocfg.speaker_pins[0] = 0x14;
1759 spec->autocfg.speaker_pins[1] = 0x16;
1760 spec->autocfg.speaker_pins[2] = 0x17;
1761 spec->autocfg.speaker_pins[3] = 0x19;
1762 spec->autocfg.speaker_pins[4] = 0x1a;
6732bd0d
WF
1763}
1764
1765static void alc889_intel_init_hook(struct hda_codec *codec)
1766{
1767 alc889_coef_init(codec);
4f5d1706 1768 alc_automute_amp(codec);
6732bd0d
WF
1769}
1770
4f5d1706 1771static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
1772{
1773 struct alc_spec *spec = codec->spec;
1774
1775 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1776 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1777 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1778 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
a9fd4f3f 1779}
ef8ef5fb 1780
5b2d1eca
VP
1781/*
1782 * ALC888 Acer Aspire 4930G model
1783 */
1784
1785static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1786/* Front Mic: set to PIN_IN (empty by default) */
1787 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1788/* Unselect Front Mic by default in input mixer 3 */
1789 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 1790/* Enable unsolicited event for HP jack */
5b2d1eca
VP
1791 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1792/* Connect Internal HP to front */
1793 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1794 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1795 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1796/* Connect HP out to front */
1797 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1798 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1799 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1800 { }
1801};
1802
d2fd4b09
TV
1803/*
1804 * ALC888 Acer Aspire 6530G model
1805 */
1806
1807static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
1808/* Route to built-in subwoofer as well as speakers */
1809 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1810 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1811 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1812 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
1813/* Bias voltage on for external mic port */
1814 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
1815/* Front Mic: set to PIN_IN (empty by default) */
1816 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1817/* Unselect Front Mic by default in input mixer 3 */
1818 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
1819/* Enable unsolicited event for HP jack */
1820 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1821/* Enable speaker output */
1822 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1823 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 1824 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
1825/* Enable headphone output */
1826 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1827 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1828 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 1829 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
1830 { }
1831};
1832
3b315d70 1833/*
018df418 1834 * ALC889 Acer Aspire 8930G model
3b315d70
HM
1835 */
1836
018df418 1837static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
1838/* Front Mic: set to PIN_IN (empty by default) */
1839 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1840/* Unselect Front Mic by default in input mixer 3 */
1841 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1842/* Enable unsolicited event for HP jack */
1843 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1844/* Connect Internal Front to Front */
1845 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1846 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1847 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1848/* Connect Internal Rear to Rear */
1849 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1850 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1851 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1852/* Connect Internal CLFE to CLFE */
1853 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1854 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1855 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1856/* Connect HP out to Front */
018df418 1857 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
1858 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1859 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1860/* Enable all DACs */
1861/* DAC DISABLE/MUTE 1? */
1862/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1863 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1864 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1865/* DAC DISABLE/MUTE 2? */
1866/* some bit here disables the other DACs. Init=0x4900 */
1867 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1868 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
1869/* DMIC fix
1870 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1871 * which makes the stereo useless. However, either the mic or the ALC889
1872 * makes the signal become a difference/sum signal instead of standard
1873 * stereo, which is annoying. So instead we flip this bit which makes the
1874 * codec replicate the sum signal to both channels, turning it into a
1875 * normal mono mic.
1876 */
1877/* DMIC_CONTROL? Init value = 0x0001 */
1878 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1879 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
1880 { }
1881};
1882
ef8ef5fb 1883static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
1884 /* Front mic only available on one ADC */
1885 {
1886 .num_items = 4,
1887 .items = {
1888 { "Mic", 0x0 },
1889 { "Line", 0x2 },
1890 { "CD", 0x4 },
1891 { "Front Mic", 0xb },
1892 },
1893 },
1894 {
1895 .num_items = 3,
1896 .items = {
1897 { "Mic", 0x0 },
1898 { "Line", 0x2 },
1899 { "CD", 0x4 },
1900 },
1901 }
1902};
1903
d2fd4b09
TV
1904static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1905 /* Interal mic only available on one ADC */
1906 {
684a8842 1907 .num_items = 5,
d2fd4b09
TV
1908 .items = {
1909 { "Ext Mic", 0x0 },
684a8842 1910 { "Line In", 0x2 },
d2fd4b09 1911 { "CD", 0x4 },
684a8842 1912 { "Input Mix", 0xa },
d2fd4b09
TV
1913 { "Int Mic", 0xb },
1914 },
1915 },
1916 {
684a8842 1917 .num_items = 4,
d2fd4b09
TV
1918 .items = {
1919 { "Ext Mic", 0x0 },
684a8842 1920 { "Line In", 0x2 },
d2fd4b09 1921 { "CD", 0x4 },
684a8842 1922 { "Input Mix", 0xa },
d2fd4b09
TV
1923 },
1924 }
1925};
1926
018df418
HM
1927static struct hda_input_mux alc889_capture_sources[3] = {
1928 /* Digital mic only available on first "ADC" */
1929 {
1930 .num_items = 5,
1931 .items = {
1932 { "Mic", 0x0 },
1933 { "Line", 0x2 },
1934 { "CD", 0x4 },
1935 { "Front Mic", 0xb },
1936 { "Input Mix", 0xa },
1937 },
1938 },
1939 {
1940 .num_items = 4,
1941 .items = {
1942 { "Mic", 0x0 },
1943 { "Line", 0x2 },
1944 { "CD", 0x4 },
1945 { "Input Mix", 0xa },
1946 },
1947 },
1948 {
1949 .num_items = 4,
1950 .items = {
1951 { "Mic", 0x0 },
1952 { "Line", 0x2 },
1953 { "CD", 0x4 },
1954 { "Input Mix", 0xa },
1955 },
1956 }
1957};
1958
ef8ef5fb 1959static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
1960 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1961 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1962 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1963 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1964 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1965 HDA_OUTPUT),
1966 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1967 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1968 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1969 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1970 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1971 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1972 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1973 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1974 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1975 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1976 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1977 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
1978 { } /* end */
1979};
1980
556eea9a
HM
1981static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
1982 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1983 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1984 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1985 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1986 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1987 HDA_OUTPUT),
1988 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1989 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1990 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1991 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1992 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1993 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1994 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1995 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1996 { } /* end */
1997};
1998
1999
4f5d1706 2000static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2001{
a9fd4f3f 2002 struct alc_spec *spec = codec->spec;
5b2d1eca 2003
a9fd4f3f
TI
2004 spec->autocfg.hp_pins[0] = 0x15;
2005 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2006 spec->autocfg.speaker_pins[1] = 0x16;
2007 spec->autocfg.speaker_pins[2] = 0x17;
5b2d1eca
VP
2008}
2009
4f5d1706 2010static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2011{
2012 struct alc_spec *spec = codec->spec;
2013
2014 spec->autocfg.hp_pins[0] = 0x15;
2015 spec->autocfg.speaker_pins[0] = 0x14;
2016 spec->autocfg.speaker_pins[1] = 0x16;
2017 spec->autocfg.speaker_pins[2] = 0x17;
320d5920
EL
2018}
2019
4f5d1706 2020static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2021{
2022 struct alc_spec *spec = codec->spec;
2023
2024 spec->autocfg.hp_pins[0] = 0x15;
2025 spec->autocfg.speaker_pins[0] = 0x14;
2026 spec->autocfg.speaker_pins[1] = 0x16;
2027 spec->autocfg.speaker_pins[2] = 0x1b;
3b315d70
HM
2028}
2029
1da177e4 2030/*
e9edcee0
TI
2031 * ALC880 3-stack model
2032 *
2033 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2034 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2035 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2036 */
2037
e9edcee0
TI
2038static hda_nid_t alc880_dac_nids[4] = {
2039 /* front, rear, clfe, rear_surr */
2040 0x02, 0x05, 0x04, 0x03
2041};
2042
2043static hda_nid_t alc880_adc_nids[3] = {
2044 /* ADC0-2 */
2045 0x07, 0x08, 0x09,
2046};
2047
2048/* The datasheet says the node 0x07 is connected from inputs,
2049 * but it shows zero connection in the real implementation on some devices.
df694daa 2050 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2051 */
e9edcee0
TI
2052static hda_nid_t alc880_adc_nids_alt[2] = {
2053 /* ADC1-2 */
2054 0x08, 0x09,
2055};
2056
2057#define ALC880_DIGOUT_NID 0x06
2058#define ALC880_DIGIN_NID 0x0a
2059
2060static struct hda_input_mux alc880_capture_source = {
2061 .num_items = 4,
2062 .items = {
2063 { "Mic", 0x0 },
2064 { "Front Mic", 0x3 },
2065 { "Line", 0x2 },
2066 { "CD", 0x4 },
2067 },
2068};
2069
2070/* channel source setting (2/6 channel selection for 3-stack) */
2071/* 2ch mode */
2072static struct hda_verb alc880_threestack_ch2_init[] = {
2073 /* set line-in to input, mute it */
2074 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2075 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2076 /* set mic-in to input vref 80%, mute it */
2077 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2078 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2079 { } /* end */
2080};
2081
2082/* 6ch mode */
2083static struct hda_verb alc880_threestack_ch6_init[] = {
2084 /* set line-in to output, unmute it */
2085 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2086 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2087 /* set mic-in to output, unmute it */
2088 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2089 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2090 { } /* end */
2091};
2092
d2a6d7dc 2093static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2094 { 2, alc880_threestack_ch2_init },
2095 { 6, alc880_threestack_ch6_init },
2096};
2097
c8b6bf9b 2098static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2099 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2100 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2101 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2102 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2103 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2104 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
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),
1da177e4
LT
2107 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2108 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2109 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2110 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2111 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2112 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2113 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2114 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2115 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2116 {
2117 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2118 .name = "Channel Mode",
df694daa
KY
2119 .info = alc_ch_mode_info,
2120 .get = alc_ch_mode_get,
2121 .put = alc_ch_mode_put,
e9edcee0
TI
2122 },
2123 { } /* end */
2124};
2125
2126/* capture mixer elements */
f9e336f6
TI
2127static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2128 struct snd_ctl_elem_info *uinfo)
2129{
2130 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2131 struct alc_spec *spec = codec->spec;
2132 int err;
1da177e4 2133
5a9e02e9 2134 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2135 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2136 HDA_INPUT);
2137 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2138 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2139 return err;
2140}
2141
2142static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2143 unsigned int size, unsigned int __user *tlv)
2144{
2145 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2146 struct alc_spec *spec = codec->spec;
2147 int err;
1da177e4 2148
5a9e02e9 2149 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2150 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2151 HDA_INPUT);
2152 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2153 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2154 return err;
2155}
2156
2157typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2158 struct snd_ctl_elem_value *ucontrol);
2159
2160static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2161 struct snd_ctl_elem_value *ucontrol,
2162 getput_call_t func)
2163{
2164 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2165 struct alc_spec *spec = codec->spec;
2166 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2167 int err;
2168
5a9e02e9 2169 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2170 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2171 3, 0, HDA_INPUT);
2172 err = func(kcontrol, ucontrol);
5a9e02e9 2173 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2174 return err;
2175}
2176
2177static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2178 struct snd_ctl_elem_value *ucontrol)
2179{
2180 return alc_cap_getput_caller(kcontrol, ucontrol,
2181 snd_hda_mixer_amp_volume_get);
2182}
2183
2184static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2185 struct snd_ctl_elem_value *ucontrol)
2186{
2187 return alc_cap_getput_caller(kcontrol, ucontrol,
2188 snd_hda_mixer_amp_volume_put);
2189}
2190
2191/* capture mixer elements */
2192#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2193
2194static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2195 struct snd_ctl_elem_value *ucontrol)
2196{
2197 return alc_cap_getput_caller(kcontrol, ucontrol,
2198 snd_hda_mixer_amp_switch_get);
2199}
2200
2201static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2202 struct snd_ctl_elem_value *ucontrol)
2203{
2204 return alc_cap_getput_caller(kcontrol, ucontrol,
2205 snd_hda_mixer_amp_switch_put);
2206}
2207
a23b688f 2208#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2209 { \
2210 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2211 .name = "Capture Switch", \
2212 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2213 .count = num, \
2214 .info = alc_cap_sw_info, \
2215 .get = alc_cap_sw_get, \
2216 .put = alc_cap_sw_put, \
2217 }, \
2218 { \
2219 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2220 .name = "Capture Volume", \
2221 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2222 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2223 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2224 .count = num, \
2225 .info = alc_cap_vol_info, \
2226 .get = alc_cap_vol_get, \
2227 .put = alc_cap_vol_put, \
2228 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2229 }
2230
2231#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2232 { \
2233 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2234 /* .name = "Capture Source", */ \
2235 .name = "Input Source", \
2236 .count = num, \
2237 .info = alc_mux_enum_info, \
2238 .get = alc_mux_enum_get, \
2239 .put = alc_mux_enum_put, \
a23b688f
TI
2240 }
2241
2242#define DEFINE_CAPMIX(num) \
2243static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2244 _DEFINE_CAPMIX(num), \
2245 _DEFINE_CAPSRC(num), \
2246 { } /* end */ \
2247}
2248
2249#define DEFINE_CAPMIX_NOSRC(num) \
2250static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2251 _DEFINE_CAPMIX(num), \
2252 { } /* end */ \
f9e336f6
TI
2253}
2254
2255/* up to three ADCs */
2256DEFINE_CAPMIX(1);
2257DEFINE_CAPMIX(2);
2258DEFINE_CAPMIX(3);
a23b688f
TI
2259DEFINE_CAPMIX_NOSRC(1);
2260DEFINE_CAPMIX_NOSRC(2);
2261DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2262
2263/*
2264 * ALC880 5-stack model
2265 *
9c7f852e
TI
2266 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2267 * Side = 0x02 (0xd)
e9edcee0
TI
2268 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2269 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2270 */
2271
2272/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 2273static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2274 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2275 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2276 { } /* end */
2277};
2278
e9edcee0
TI
2279/* channel source setting (6/8 channel selection for 5-stack) */
2280/* 6ch mode */
2281static struct hda_verb alc880_fivestack_ch6_init[] = {
2282 /* set line-in to input, mute it */
2283 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2284 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2285 { } /* end */
2286};
2287
e9edcee0
TI
2288/* 8ch mode */
2289static struct hda_verb alc880_fivestack_ch8_init[] = {
2290 /* set line-in to output, unmute it */
2291 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2292 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2293 { } /* end */
2294};
2295
d2a6d7dc 2296static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2297 { 6, alc880_fivestack_ch6_init },
2298 { 8, alc880_fivestack_ch8_init },
2299};
2300
2301
2302/*
2303 * ALC880 6-stack model
2304 *
9c7f852e
TI
2305 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2306 * Side = 0x05 (0x0f)
e9edcee0
TI
2307 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2308 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2309 */
2310
2311static hda_nid_t alc880_6st_dac_nids[4] = {
2312 /* front, rear, clfe, rear_surr */
2313 0x02, 0x03, 0x04, 0x05
f12ab1e0 2314};
e9edcee0
TI
2315
2316static struct hda_input_mux alc880_6stack_capture_source = {
2317 .num_items = 4,
2318 .items = {
2319 { "Mic", 0x0 },
2320 { "Front Mic", 0x1 },
2321 { "Line", 0x2 },
2322 { "CD", 0x4 },
2323 },
2324};
2325
2326/* fixed 8-channels */
d2a6d7dc 2327static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2328 { 8, NULL },
2329};
2330
c8b6bf9b 2331static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2332 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2333 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2334 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2335 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2336 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2337 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2338 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2339 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2340 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2341 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2342 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2343 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2344 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2345 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2346 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2347 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2348 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2349 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2350 {
2351 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2352 .name = "Channel Mode",
df694daa
KY
2353 .info = alc_ch_mode_info,
2354 .get = alc_ch_mode_get,
2355 .put = alc_ch_mode_put,
16ded525
TI
2356 },
2357 { } /* end */
2358};
2359
e9edcee0
TI
2360
2361/*
2362 * ALC880 W810 model
2363 *
2364 * W810 has rear IO for:
2365 * Front (DAC 02)
2366 * Surround (DAC 03)
2367 * Center/LFE (DAC 04)
2368 * Digital out (06)
2369 *
2370 * The system also has a pair of internal speakers, and a headphone jack.
2371 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2372 *
e9edcee0
TI
2373 * There is a variable resistor to control the speaker or headphone
2374 * volume. This is a hardware-only device without a software API.
2375 *
2376 * Plugging headphones in will disable the internal speakers. This is
2377 * implemented in hardware, not via the driver using jack sense. In
2378 * a similar fashion, plugging into the rear socket marked "front" will
2379 * disable both the speakers and headphones.
2380 *
2381 * For input, there's a microphone jack, and an "audio in" jack.
2382 * These may not do anything useful with this driver yet, because I
2383 * haven't setup any initialization verbs for these yet...
2384 */
2385
2386static hda_nid_t alc880_w810_dac_nids[3] = {
2387 /* front, rear/surround, clfe */
2388 0x02, 0x03, 0x04
16ded525
TI
2389};
2390
e9edcee0 2391/* fixed 6 channels */
d2a6d7dc 2392static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2393 { 6, NULL }
2394};
2395
2396/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 2397static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2398 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2399 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2400 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2401 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2402 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2403 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2404 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2405 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2406 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2407 { } /* end */
2408};
2409
2410
2411/*
2412 * Z710V model
2413 *
2414 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2415 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2416 * Line = 0x1a
e9edcee0
TI
2417 */
2418
2419static hda_nid_t alc880_z71v_dac_nids[1] = {
2420 0x02
2421};
2422#define ALC880_Z71V_HP_DAC 0x03
2423
2424/* fixed 2 channels */
d2a6d7dc 2425static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2426 { 2, NULL }
2427};
2428
c8b6bf9b 2429static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2430 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2431 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2432 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2433 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2434 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2435 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2436 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2437 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2438 { } /* end */
2439};
2440
e9edcee0 2441
e9edcee0
TI
2442/*
2443 * ALC880 F1734 model
2444 *
2445 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2446 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2447 */
2448
2449static hda_nid_t alc880_f1734_dac_nids[1] = {
2450 0x03
2451};
2452#define ALC880_F1734_HP_DAC 0x02
2453
c8b6bf9b 2454static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2455 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2456 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2457 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2458 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2459 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2460 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2461 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2462 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2463 { } /* end */
2464};
2465
937b4160
TI
2466static struct hda_input_mux alc880_f1734_capture_source = {
2467 .num_items = 2,
2468 .items = {
2469 { "Mic", 0x1 },
2470 { "CD", 0x4 },
2471 },
2472};
2473
e9edcee0 2474
e9edcee0
TI
2475/*
2476 * ALC880 ASUS model
2477 *
2478 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2479 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2480 * Mic = 0x18, Line = 0x1a
2481 */
2482
2483#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2484#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2485
c8b6bf9b 2486static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2487 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2488 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2489 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2490 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2491 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2492 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2493 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2494 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2495 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2496 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2497 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2498 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2499 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2500 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2501 {
2502 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2503 .name = "Channel Mode",
df694daa
KY
2504 .info = alc_ch_mode_info,
2505 .get = alc_ch_mode_get,
2506 .put = alc_ch_mode_put,
16ded525
TI
2507 },
2508 { } /* end */
2509};
e9edcee0 2510
e9edcee0
TI
2511/*
2512 * ALC880 ASUS W1V model
2513 *
2514 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2515 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2516 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2517 */
2518
2519/* additional mixers to alc880_asus_mixer */
c8b6bf9b 2520static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
2521 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2522 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2523 { } /* end */
2524};
2525
df694daa
KY
2526/* TCL S700 */
2527static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2528 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2529 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2530 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2531 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2532 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2533 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2534 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2535 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2536 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2537 { } /* end */
2538};
2539
ccc656ce
KY
2540/* Uniwill */
2541static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2542 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2543 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2544 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2545 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2546 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2547 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2548 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2549 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2550 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2551 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2552 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2553 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2554 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2555 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2556 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2557 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2558 {
2559 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2560 .name = "Channel Mode",
2561 .info = alc_ch_mode_info,
2562 .get = alc_ch_mode_get,
2563 .put = alc_ch_mode_put,
2564 },
2565 { } /* end */
2566};
2567
2cf9f0fc
TD
2568static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2569 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2570 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2571 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2572 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2573 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2574 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2575 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2576 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2577 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2578 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2579 { } /* end */
2580};
2581
ccc656ce 2582static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2583 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2584 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2585 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2586 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2587 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2588 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2589 { } /* end */
2590};
2591
2134ea4f
TI
2592/*
2593 * virtual master controls
2594 */
2595
2596/*
2597 * slave controls for virtual master
2598 */
2599static const char *alc_slave_vols[] = {
2600 "Front Playback Volume",
2601 "Surround Playback Volume",
2602 "Center Playback Volume",
2603 "LFE Playback Volume",
2604 "Side Playback Volume",
2605 "Headphone Playback Volume",
2606 "Speaker Playback Volume",
2607 "Mono Playback Volume",
2134ea4f 2608 "Line-Out Playback Volume",
26f5df26 2609 "PCM Playback Volume",
2134ea4f
TI
2610 NULL,
2611};
2612
2613static const char *alc_slave_sws[] = {
2614 "Front Playback Switch",
2615 "Surround Playback Switch",
2616 "Center Playback Switch",
2617 "LFE Playback Switch",
2618 "Side Playback Switch",
2619 "Headphone Playback Switch",
2620 "Speaker Playback Switch",
2621 "Mono Playback Switch",
edb54a55 2622 "IEC958 Playback Switch",
23033b2b
TI
2623 "Line-Out Playback Switch",
2624 "PCM Playback Switch",
2134ea4f
TI
2625 NULL,
2626};
2627
1da177e4 2628/*
e9edcee0 2629 * build control elements
1da177e4 2630 */
603c4019 2631
5b0cb1d8
JK
2632#define NID_MAPPING (-1)
2633
2634#define SUBDEV_SPEAKER_ (0 << 6)
2635#define SUBDEV_HP_ (1 << 6)
2636#define SUBDEV_LINE_ (2 << 6)
2637#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2638#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2639#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2640
603c4019
TI
2641static void alc_free_kctls(struct hda_codec *codec);
2642
67d634c0 2643#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2644/* additional beep mixers; the actual parameters are overwritten at build */
2645static struct snd_kcontrol_new alc_beep_mixer[] = {
2646 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 2647 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
2648 { } /* end */
2649};
67d634c0 2650#endif
45bdd1c1 2651
1da177e4
LT
2652static int alc_build_controls(struct hda_codec *codec)
2653{
2654 struct alc_spec *spec = codec->spec;
2f44f847 2655 struct snd_kcontrol *kctl = NULL;
5b0cb1d8
JK
2656 struct snd_kcontrol_new *knew;
2657 int i, j, err;
2658 unsigned int u;
2659 hda_nid_t nid;
1da177e4
LT
2660
2661 for (i = 0; i < spec->num_mixers; i++) {
2662 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2663 if (err < 0)
2664 return err;
2665 }
f9e336f6
TI
2666 if (spec->cap_mixer) {
2667 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2668 if (err < 0)
2669 return err;
2670 }
1da177e4 2671 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2672 err = snd_hda_create_spdif_out_ctls(codec,
2673 spec->multiout.dig_out_nid);
1da177e4
LT
2674 if (err < 0)
2675 return err;
e64f14f4
TI
2676 if (!spec->no_analog) {
2677 err = snd_hda_create_spdif_share_sw(codec,
2678 &spec->multiout);
2679 if (err < 0)
2680 return err;
2681 spec->multiout.share_spdif = 1;
2682 }
1da177e4
LT
2683 }
2684 if (spec->dig_in_nid) {
2685 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2686 if (err < 0)
2687 return err;
2688 }
2134ea4f 2689
67d634c0 2690#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2691 /* create beep controls if needed */
2692 if (spec->beep_amp) {
2693 struct snd_kcontrol_new *knew;
2694 for (knew = alc_beep_mixer; knew->name; knew++) {
2695 struct snd_kcontrol *kctl;
2696 kctl = snd_ctl_new1(knew, codec);
2697 if (!kctl)
2698 return -ENOMEM;
2699 kctl->private_value = spec->beep_amp;
5e26dfd0 2700 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
2701 if (err < 0)
2702 return err;
2703 }
2704 }
67d634c0 2705#endif
45bdd1c1 2706
2134ea4f 2707 /* if we have no master control, let's create it */
e64f14f4
TI
2708 if (!spec->no_analog &&
2709 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2710 unsigned int vmaster_tlv[4];
2134ea4f 2711 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2712 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2713 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2714 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2715 if (err < 0)
2716 return err;
2717 }
e64f14f4
TI
2718 if (!spec->no_analog &&
2719 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2720 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2721 NULL, alc_slave_sws);
2722 if (err < 0)
2723 return err;
2724 }
2725
5b0cb1d8 2726 /* assign Capture Source enums to NID */
fbe618f2
TI
2727 if (spec->capsrc_nids || spec->adc_nids) {
2728 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2729 if (!kctl)
2730 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2731 for (i = 0; kctl && i < kctl->count; i++) {
2732 hda_nid_t *nids = spec->capsrc_nids;
2733 if (!nids)
2734 nids = spec->adc_nids;
2735 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
2736 if (err < 0)
2737 return err;
2738 }
5b0cb1d8
JK
2739 }
2740 if (spec->cap_mixer) {
2741 const char *kname = kctl ? kctl->id.name : NULL;
2742 for (knew = spec->cap_mixer; knew->name; knew++) {
2743 if (kname && strcmp(knew->name, kname) == 0)
2744 continue;
2745 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2746 for (i = 0; kctl && i < kctl->count; i++) {
2747 err = snd_hda_add_nid(codec, kctl, i,
2748 spec->adc_nids[i]);
2749 if (err < 0)
2750 return err;
2751 }
2752 }
2753 }
2754
2755 /* other nid->control mapping */
2756 for (i = 0; i < spec->num_mixers; i++) {
2757 for (knew = spec->mixers[i]; knew->name; knew++) {
2758 if (knew->iface != NID_MAPPING)
2759 continue;
2760 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2761 if (kctl == NULL)
2762 continue;
2763 u = knew->subdevice;
2764 for (j = 0; j < 4; j++, u >>= 8) {
2765 nid = u & 0x3f;
2766 if (nid == 0)
2767 continue;
2768 switch (u & 0xc0) {
2769 case SUBDEV_SPEAKER_:
2770 nid = spec->autocfg.speaker_pins[nid];
2771 break;
2772 case SUBDEV_LINE_:
2773 nid = spec->autocfg.line_out_pins[nid];
2774 break;
2775 case SUBDEV_HP_:
2776 nid = spec->autocfg.hp_pins[nid];
2777 break;
2778 default:
2779 continue;
2780 }
2781 err = snd_hda_add_nid(codec, kctl, 0, nid);
2782 if (err < 0)
2783 return err;
2784 }
2785 u = knew->private_value;
2786 for (j = 0; j < 4; j++, u >>= 8) {
2787 nid = u & 0xff;
2788 if (nid == 0)
2789 continue;
2790 err = snd_hda_add_nid(codec, kctl, 0, nid);
2791 if (err < 0)
2792 return err;
2793 }
2794 }
2795 }
bae84e70
TI
2796
2797 alc_free_kctls(codec); /* no longer needed */
2798
1da177e4
LT
2799 return 0;
2800}
2801
e9edcee0 2802
1da177e4
LT
2803/*
2804 * initialize the codec volumes, etc
2805 */
2806
e9edcee0
TI
2807/*
2808 * generic initialization of ADC, input mixers and output mixers
2809 */
2810static struct hda_verb alc880_volume_init_verbs[] = {
2811 /*
2812 * Unmute ADC0-2 and set the default input to mic-in
2813 */
71fe7b82 2814 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2815 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2816 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2817 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2818 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2819 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 2820
e9edcee0
TI
2821 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2822 * mixer widget
9c7f852e
TI
2823 * Note: PASD motherboards uses the Line In 2 as the input for front
2824 * panel mic (mic 2)
1da177e4 2825 */
e9edcee0 2826 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
2827 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2828 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2829 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2830 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2831 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2832 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2833 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 2834
e9edcee0
TI
2835 /*
2836 * Set up output mixers (0x0c - 0x0f)
1da177e4 2837 */
e9edcee0
TI
2838 /* set vol=0 to output mixers */
2839 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2840 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2841 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2842 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2843 /* set up input amps for analog loopback */
2844 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
2845 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2846 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2847 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2848 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2849 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2850 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2851 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2852 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
2853
2854 { }
2855};
2856
e9edcee0
TI
2857/*
2858 * 3-stack pin configuration:
2859 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2860 */
2861static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2862 /*
2863 * preset connection lists of input pins
2864 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2865 */
2866 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2867 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2868 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2869
2870 /*
2871 * Set pin mode and muting
2872 */
2873 /* set front pin widgets 0x14 for output */
05acb863 2874 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2875 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2876 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2877 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2878 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2879 /* Mic2 (as headphone out) for HP output */
2880 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2881 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2882 /* Line In pin widget for input */
05acb863 2883 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
2884 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2885 /* Line2 (as front mic) pin widget for input and vref at 80% */
2886 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2887 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2888 /* CD pin widget for input */
05acb863 2889 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 2890
e9edcee0
TI
2891 { }
2892};
1da177e4 2893
e9edcee0
TI
2894/*
2895 * 5-stack pin configuration:
2896 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2897 * line-in/side = 0x1a, f-mic = 0x1b
2898 */
2899static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2900 /*
2901 * preset connection lists of input pins
2902 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 2903 */
e9edcee0
TI
2904 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2905 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 2906
e9edcee0
TI
2907 /*
2908 * Set pin mode and muting
1da177e4 2909 */
e9edcee0
TI
2910 /* set pin widgets 0x14-0x17 for output */
2911 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2912 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2913 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2914 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2915 /* unmute pins for output (no gain on this amp) */
2916 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2917 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2918 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2919 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2920
2921 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2922 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2923 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2924 /* Mic2 (as headphone out) for HP output */
2925 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2926 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2927 /* Line In pin widget for input */
2928 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2929 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2930 /* Line2 (as front mic) pin widget for input and vref at 80% */
2931 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2932 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2933 /* CD pin widget for input */
2934 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
2935
2936 { }
2937};
2938
e9edcee0
TI
2939/*
2940 * W810 pin configuration:
2941 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2942 */
2943static struct hda_verb alc880_pin_w810_init_verbs[] = {
2944 /* hphone/speaker input selector: front DAC */
2945 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 2946
05acb863 2947 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2948 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2949 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2950 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2951 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2952 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2953
e9edcee0 2954 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 2955 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2956
1da177e4
LT
2957 { }
2958};
2959
e9edcee0
TI
2960/*
2961 * Z71V pin configuration:
2962 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2963 */
2964static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 2965 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2966 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2967 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2968 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 2969
16ded525 2970 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2971 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 2972 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2973 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
2974
2975 { }
2976};
2977
e9edcee0
TI
2978/*
2979 * 6-stack pin configuration:
9c7f852e
TI
2980 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2981 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
2982 */
2983static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2984 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2985
16ded525 2986 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2987 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2988 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2989 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2990 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2991 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2992 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2993 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2994
16ded525 2995 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2996 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2997 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2998 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2999 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3000 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3001 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3002 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3003 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3004
e9edcee0
TI
3005 { }
3006};
3007
ccc656ce
KY
3008/*
3009 * Uniwill pin configuration:
3010 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3011 * line = 0x1a
3012 */
3013static struct hda_verb alc880_uniwill_init_verbs[] = {
3014 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3015
3016 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3017 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3018 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3019 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3020 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3021 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3022 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3023 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3026 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3027 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3028 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3029 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3030
3031 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3032 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3033 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3034 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3035 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3036 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3037 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3038 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3039 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3040
3041 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3042 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3043
3044 { }
3045};
3046
3047/*
3048* Uniwill P53
ea1fb29a 3049* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
3050 */
3051static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3052 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3053
3054 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3055 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3056 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3057 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3058 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3059 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3060 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3061 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3062 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3063 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3064 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3065 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3066
3067 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3068 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3069 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3070 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3071 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3072 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3073
3074 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3075 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3076
3077 { }
3078};
3079
2cf9f0fc
TD
3080static struct hda_verb alc880_beep_init_verbs[] = {
3081 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3082 { }
3083};
3084
458a4fab
TI
3085/* auto-toggle front mic */
3086static void alc880_uniwill_mic_automute(struct hda_codec *codec)
3087{
3088 unsigned int present;
3089 unsigned char bits;
ccc656ce 3090
864f92be 3091 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3092 bits = present ? HDA_AMP_MUTE : 0;
3093 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3094}
3095
4f5d1706 3096static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3097{
a9fd4f3f
TI
3098 struct alc_spec *spec = codec->spec;
3099
3100 spec->autocfg.hp_pins[0] = 0x14;
3101 spec->autocfg.speaker_pins[0] = 0x15;
3102 spec->autocfg.speaker_pins[0] = 0x16;
4f5d1706
TI
3103}
3104
3105static void alc880_uniwill_init_hook(struct hda_codec *codec)
3106{
a9fd4f3f 3107 alc_automute_amp(codec);
458a4fab 3108 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
3109}
3110
3111static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3112 unsigned int res)
3113{
3114 /* Looks like the unsol event is incompatible with the standard
3115 * definition. 4bit tag is placed at 28 bit!
3116 */
458a4fab 3117 switch (res >> 28) {
458a4fab
TI
3118 case ALC880_MIC_EVENT:
3119 alc880_uniwill_mic_automute(codec);
3120 break;
a9fd4f3f
TI
3121 default:
3122 alc_automute_amp_unsol_event(codec, res);
3123 break;
458a4fab 3124 }
ccc656ce
KY
3125}
3126
4f5d1706 3127static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3128{
a9fd4f3f 3129 struct alc_spec *spec = codec->spec;
ccc656ce 3130
a9fd4f3f
TI
3131 spec->autocfg.hp_pins[0] = 0x14;
3132 spec->autocfg.speaker_pins[0] = 0x15;
ccc656ce
KY
3133}
3134
3135static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3136{
3137 unsigned int present;
ea1fb29a 3138
ccc656ce 3139 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3140 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3141 present &= HDA_AMP_VOLMASK;
3142 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3143 HDA_AMP_VOLMASK, present);
3144 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3145 HDA_AMP_VOLMASK, present);
ccc656ce 3146}
47fd830a 3147
ccc656ce
KY
3148static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3149 unsigned int res)
3150{
3151 /* Looks like the unsol event is incompatible with the standard
3152 * definition. 4bit tag is placed at 28 bit!
3153 */
f12ab1e0 3154 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3155 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
3156 else
3157 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
3158}
3159
e9edcee0
TI
3160/*
3161 * F1734 pin configuration:
3162 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3163 */
3164static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3165 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3166 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3167 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3168 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3169 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3170
e9edcee0 3171 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3172 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3173 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3174 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3175
e9edcee0
TI
3176 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3177 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3178 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3179 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3180 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3181 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3182 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3183 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3184 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3185
937b4160
TI
3186 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3187 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3188
dfc0ff62
TI
3189 { }
3190};
3191
e9edcee0
TI
3192/*
3193 * ASUS pin configuration:
3194 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3195 */
3196static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3197 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3198 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3199 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3200 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3201
3202 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3203 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3204 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3205 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3206 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3207 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3208 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3209 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3210
3211 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3212 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3213 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3214 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3215 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3216 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3217 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3218 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3219 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3220
e9edcee0
TI
3221 { }
3222};
16ded525 3223
e9edcee0 3224/* Enable GPIO mask and set output */
bc9f98a9
KY
3225#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3226#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3227#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3228
3229/* Clevo m520g init */
3230static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3231 /* headphone output */
3232 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3233 /* line-out */
3234 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3235 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3236 /* Line-in */
3237 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3238 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3239 /* CD */
3240 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3241 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3242 /* Mic1 (rear panel) */
3243 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3244 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3245 /* Mic2 (front panel) */
3246 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3247 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3248 /* headphone */
3249 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3250 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3251 /* change to EAPD mode */
3252 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3253 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3254
3255 { }
16ded525
TI
3256};
3257
df694daa 3258static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3259 /* change to EAPD mode */
3260 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3261 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3262
df694daa
KY
3263 /* Headphone output */
3264 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3265 /* Front output*/
3266 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3267 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3268
3269 /* Line In pin widget for input */
3270 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3271 /* CD pin widget for input */
3272 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3273 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3274 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3275
3276 /* change to EAPD mode */
3277 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3278 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3279
3280 { }
3281};
16ded525 3282
e9edcee0 3283/*
ae6b813a
TI
3284 * LG m1 express dual
3285 *
3286 * Pin assignment:
3287 * Rear Line-In/Out (blue): 0x14
3288 * Build-in Mic-In: 0x15
3289 * Speaker-out: 0x17
3290 * HP-Out (green): 0x1b
3291 * Mic-In/Out (red): 0x19
3292 * SPDIF-Out: 0x1e
3293 */
3294
3295/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3296static hda_nid_t alc880_lg_dac_nids[3] = {
3297 0x05, 0x02, 0x03
3298};
3299
3300/* seems analog CD is not working */
3301static struct hda_input_mux alc880_lg_capture_source = {
3302 .num_items = 3,
3303 .items = {
3304 { "Mic", 0x1 },
3305 { "Line", 0x5 },
3306 { "Internal Mic", 0x6 },
3307 },
3308};
3309
3310/* 2,4,6 channel modes */
3311static struct hda_verb alc880_lg_ch2_init[] = {
3312 /* set line-in and mic-in to input */
3313 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3314 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3315 { }
3316};
3317
3318static struct hda_verb alc880_lg_ch4_init[] = {
3319 /* set line-in to out and mic-in to input */
3320 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3321 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3322 { }
3323};
3324
3325static struct hda_verb alc880_lg_ch6_init[] = {
3326 /* set line-in and mic-in to output */
3327 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3328 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3329 { }
3330};
3331
3332static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3333 { 2, alc880_lg_ch2_init },
3334 { 4, alc880_lg_ch4_init },
3335 { 6, alc880_lg_ch6_init },
3336};
3337
3338static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3339 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3340 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3341 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3342 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3343 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3344 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3345 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3346 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3347 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3348 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3349 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3350 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3351 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3352 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3353 {
3354 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3355 .name = "Channel Mode",
3356 .info = alc_ch_mode_info,
3357 .get = alc_ch_mode_get,
3358 .put = alc_ch_mode_put,
3359 },
3360 { } /* end */
3361};
3362
3363static struct hda_verb alc880_lg_init_verbs[] = {
3364 /* set capture source to mic-in */
3365 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3366 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3367 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3368 /* mute all amp mixer inputs */
3369 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3370 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3371 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3372 /* line-in to input */
3373 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3374 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3375 /* built-in mic */
3376 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3377 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3378 /* speaker-out */
3379 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3380 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3381 /* mic-in to input */
3382 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3383 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3384 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3385 /* HP-out */
3386 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3387 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3388 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3389 /* jack sense */
a9fd4f3f 3390 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3391 { }
3392};
3393
3394/* toggle speaker-output according to the hp-jack state */
4f5d1706 3395static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3396{
a9fd4f3f 3397 struct alc_spec *spec = codec->spec;
ae6b813a 3398
a9fd4f3f
TI
3399 spec->autocfg.hp_pins[0] = 0x1b;
3400 spec->autocfg.speaker_pins[0] = 0x17;
ae6b813a
TI
3401}
3402
d681518a
TI
3403/*
3404 * LG LW20
3405 *
3406 * Pin assignment:
3407 * Speaker-out: 0x14
3408 * Mic-In: 0x18
e4f41da9
CM
3409 * Built-in Mic-In: 0x19
3410 * Line-In: 0x1b
3411 * HP-Out: 0x1a
d681518a
TI
3412 * SPDIF-Out: 0x1e
3413 */
3414
d681518a 3415static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3416 .num_items = 3,
d681518a
TI
3417 .items = {
3418 { "Mic", 0x0 },
3419 { "Internal Mic", 0x1 },
e4f41da9 3420 { "Line In", 0x2 },
d681518a
TI
3421 },
3422};
3423
0a8c5da3
CM
3424#define alc880_lg_lw_modes alc880_threestack_modes
3425
d681518a 3426static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3427 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3428 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3429 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3430 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3431 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3432 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3433 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3434 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3435 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3436 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3437 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3438 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3439 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3440 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3441 {
3442 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3443 .name = "Channel Mode",
3444 .info = alc_ch_mode_info,
3445 .get = alc_ch_mode_get,
3446 .put = alc_ch_mode_put,
3447 },
d681518a
TI
3448 { } /* end */
3449};
3450
3451static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3452 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3453 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3454 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3455
d681518a
TI
3456 /* set capture source to mic-in */
3457 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3458 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3459 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3460 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3461 /* speaker-out */
3462 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3463 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3464 /* HP-out */
d681518a
TI
3465 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3466 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3467 /* mic-in to input */
3468 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3469 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3470 /* built-in mic */
3471 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3472 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3473 /* jack sense */
a9fd4f3f 3474 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3475 { }
3476};
3477
3478/* toggle speaker-output according to the hp-jack state */
4f5d1706 3479static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3480{
a9fd4f3f 3481 struct alc_spec *spec = codec->spec;
d681518a 3482
a9fd4f3f
TI
3483 spec->autocfg.hp_pins[0] = 0x1b;
3484 spec->autocfg.speaker_pins[0] = 0x14;
d681518a
TI
3485}
3486
df99cd33
TI
3487static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3488 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3489 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3490 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3491 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3492 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3493 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3494 { } /* end */
3495};
3496
3497static struct hda_input_mux alc880_medion_rim_capture_source = {
3498 .num_items = 2,
3499 .items = {
3500 { "Mic", 0x0 },
3501 { "Internal Mic", 0x1 },
3502 },
3503};
3504
3505static struct hda_verb alc880_medion_rim_init_verbs[] = {
3506 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3507
3508 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3509 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3510
3511 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3512 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3513 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3514 /* Mic2 (as headphone out) for HP output */
3515 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3516 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3517 /* Internal Speaker */
3518 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3519 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3520
3521 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3522 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3523
3524 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3525 { }
3526};
3527
3528/* toggle speaker-output according to the hp-jack state */
3529static void alc880_medion_rim_automute(struct hda_codec *codec)
3530{
a9fd4f3f
TI
3531 struct alc_spec *spec = codec->spec;
3532 alc_automute_amp(codec);
3533 /* toggle EAPD */
3534 if (spec->jack_present)
df99cd33
TI
3535 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3536 else
3537 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3538}
3539
3540static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3541 unsigned int res)
3542{
3543 /* Looks like the unsol event is incompatible with the standard
3544 * definition. 4bit tag is placed at 28 bit!
3545 */
3546 if ((res >> 28) == ALC880_HP_EVENT)
3547 alc880_medion_rim_automute(codec);
3548}
3549
4f5d1706 3550static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
3551{
3552 struct alc_spec *spec = codec->spec;
3553
3554 spec->autocfg.hp_pins[0] = 0x14;
3555 spec->autocfg.speaker_pins[0] = 0x1b;
a9fd4f3f
TI
3556}
3557
cb53c626
TI
3558#ifdef CONFIG_SND_HDA_POWER_SAVE
3559static struct hda_amp_list alc880_loopbacks[] = {
3560 { 0x0b, HDA_INPUT, 0 },
3561 { 0x0b, HDA_INPUT, 1 },
3562 { 0x0b, HDA_INPUT, 2 },
3563 { 0x0b, HDA_INPUT, 3 },
3564 { 0x0b, HDA_INPUT, 4 },
3565 { } /* end */
3566};
3567
3568static struct hda_amp_list alc880_lg_loopbacks[] = {
3569 { 0x0b, HDA_INPUT, 1 },
3570 { 0x0b, HDA_INPUT, 6 },
3571 { 0x0b, HDA_INPUT, 7 },
3572 { } /* end */
3573};
3574#endif
3575
ae6b813a
TI
3576/*
3577 * Common callbacks
e9edcee0
TI
3578 */
3579
1da177e4
LT
3580static int alc_init(struct hda_codec *codec)
3581{
3582 struct alc_spec *spec = codec->spec;
e9edcee0
TI
3583 unsigned int i;
3584
2c3bf9ab 3585 alc_fix_pll(codec);
4a79ba34 3586 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 3587
e9edcee0
TI
3588 for (i = 0; i < spec->num_init_verbs; i++)
3589 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
3590
3591 if (spec->init_hook)
3592 spec->init_hook(codec);
3593
ad35879a
TI
3594#ifdef CONFIG_SND_HDA_POWER_SAVE
3595 if (codec->patch_ops.check_power_status)
3596 codec->patch_ops.check_power_status(codec, 0x01);
3597#endif
1da177e4
LT
3598 return 0;
3599}
3600
ae6b813a
TI
3601static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3602{
3603 struct alc_spec *spec = codec->spec;
3604
3605 if (spec->unsol_event)
3606 spec->unsol_event(codec, res);
3607}
3608
cb53c626
TI
3609#ifdef CONFIG_SND_HDA_POWER_SAVE
3610static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3611{
3612 struct alc_spec *spec = codec->spec;
3613 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3614}
3615#endif
3616
1da177e4
LT
3617/*
3618 * Analog playback callbacks
3619 */
3620static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3621 struct hda_codec *codec,
c8b6bf9b 3622 struct snd_pcm_substream *substream)
1da177e4
LT
3623{
3624 struct alc_spec *spec = codec->spec;
9a08160b
TI
3625 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3626 hinfo);
1da177e4
LT
3627}
3628
3629static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3630 struct hda_codec *codec,
3631 unsigned int stream_tag,
3632 unsigned int format,
c8b6bf9b 3633 struct snd_pcm_substream *substream)
1da177e4
LT
3634{
3635 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3636 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3637 stream_tag, format, substream);
1da177e4
LT
3638}
3639
3640static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3641 struct hda_codec *codec,
c8b6bf9b 3642 struct snd_pcm_substream *substream)
1da177e4
LT
3643{
3644 struct alc_spec *spec = codec->spec;
3645 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3646}
3647
3648/*
3649 * Digital out
3650 */
3651static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3652 struct hda_codec *codec,
c8b6bf9b 3653 struct snd_pcm_substream *substream)
1da177e4
LT
3654{
3655 struct alc_spec *spec = codec->spec;
3656 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3657}
3658
6b97eb45
TI
3659static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3660 struct hda_codec *codec,
3661 unsigned int stream_tag,
3662 unsigned int format,
3663 struct snd_pcm_substream *substream)
3664{
3665 struct alc_spec *spec = codec->spec;
3666 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3667 stream_tag, format, substream);
3668}
3669
9b5f12e5
TI
3670static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3671 struct hda_codec *codec,
3672 struct snd_pcm_substream *substream)
3673{
3674 struct alc_spec *spec = codec->spec;
3675 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3676}
3677
1da177e4
LT
3678static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3679 struct hda_codec *codec,
c8b6bf9b 3680 struct snd_pcm_substream *substream)
1da177e4
LT
3681{
3682 struct alc_spec *spec = codec->spec;
3683 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3684}
3685
3686/*
3687 * Analog capture
3688 */
6330079f 3689static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3690 struct hda_codec *codec,
3691 unsigned int stream_tag,
3692 unsigned int format,
c8b6bf9b 3693 struct snd_pcm_substream *substream)
1da177e4
LT
3694{
3695 struct alc_spec *spec = codec->spec;
3696
6330079f 3697 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3698 stream_tag, 0, format);
3699 return 0;
3700}
3701
6330079f 3702static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3703 struct hda_codec *codec,
c8b6bf9b 3704 struct snd_pcm_substream *substream)
1da177e4
LT
3705{
3706 struct alc_spec *spec = codec->spec;
3707
888afa15
TI
3708 snd_hda_codec_cleanup_stream(codec,
3709 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3710 return 0;
3711}
3712
840b64c0
TI
3713/* analog capture with dynamic dual-adc changes */
3714static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3715 struct hda_codec *codec,
3716 unsigned int stream_tag,
3717 unsigned int format,
3718 struct snd_pcm_substream *substream)
3719{
3720 struct alc_spec *spec = codec->spec;
3721 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
3722 spec->cur_adc_stream_tag = stream_tag;
3723 spec->cur_adc_format = format;
3724 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
3725 return 0;
3726}
3727
3728static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3729 struct hda_codec *codec,
3730 struct snd_pcm_substream *substream)
3731{
3732 struct alc_spec *spec = codec->spec;
3733 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
3734 spec->cur_adc = 0;
3735 return 0;
3736}
3737
3738static struct hda_pcm_stream dualmic_pcm_analog_capture = {
3739 .substreams = 1,
3740 .channels_min = 2,
3741 .channels_max = 2,
3742 .nid = 0, /* fill later */
3743 .ops = {
3744 .prepare = dualmic_capture_pcm_prepare,
3745 .cleanup = dualmic_capture_pcm_cleanup
3746 },
3747};
1da177e4
LT
3748
3749/*
3750 */
3751static struct hda_pcm_stream alc880_pcm_analog_playback = {
3752 .substreams = 1,
3753 .channels_min = 2,
3754 .channels_max = 8,
e9edcee0 3755 /* NID is set in alc_build_pcms */
1da177e4
LT
3756 .ops = {
3757 .open = alc880_playback_pcm_open,
3758 .prepare = alc880_playback_pcm_prepare,
3759 .cleanup = alc880_playback_pcm_cleanup
3760 },
3761};
3762
3763static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
3764 .substreams = 1,
3765 .channels_min = 2,
3766 .channels_max = 2,
3767 /* NID is set in alc_build_pcms */
3768};
3769
3770static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3771 .substreams = 1,
3772 .channels_min = 2,
3773 .channels_max = 2,
3774 /* NID is set in alc_build_pcms */
3775};
3776
3777static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3778 .substreams = 2, /* can be overridden */
1da177e4
LT
3779 .channels_min = 2,
3780 .channels_max = 2,
e9edcee0 3781 /* NID is set in alc_build_pcms */
1da177e4 3782 .ops = {
6330079f
TI
3783 .prepare = alc880_alt_capture_pcm_prepare,
3784 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
3785 },
3786};
3787
3788static struct hda_pcm_stream alc880_pcm_digital_playback = {
3789 .substreams = 1,
3790 .channels_min = 2,
3791 .channels_max = 2,
3792 /* NID is set in alc_build_pcms */
3793 .ops = {
3794 .open = alc880_dig_playback_pcm_open,
6b97eb45 3795 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
3796 .prepare = alc880_dig_playback_pcm_prepare,
3797 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
3798 },
3799};
3800
3801static struct hda_pcm_stream alc880_pcm_digital_capture = {
3802 .substreams = 1,
3803 .channels_min = 2,
3804 .channels_max = 2,
3805 /* NID is set in alc_build_pcms */
3806};
3807
4c5186ed 3808/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 3809static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
3810 .substreams = 0,
3811 .channels_min = 0,
3812 .channels_max = 0,
3813};
3814
1da177e4
LT
3815static int alc_build_pcms(struct hda_codec *codec)
3816{
3817 struct alc_spec *spec = codec->spec;
3818 struct hda_pcm *info = spec->pcm_rec;
3819 int i;
3820
3821 codec->num_pcms = 1;
3822 codec->pcm_info = info;
3823
e64f14f4
TI
3824 if (spec->no_analog)
3825 goto skip_analog;
3826
812a2cca
TI
3827 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3828 "%s Analog", codec->chip_name);
1da177e4 3829 info->name = spec->stream_name_analog;
274693f3 3830
4a471b7d 3831 if (spec->stream_analog_playback) {
da3cec35
TI
3832 if (snd_BUG_ON(!spec->multiout.dac_nids))
3833 return -EINVAL;
4a471b7d
TI
3834 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3835 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3836 }
3837 if (spec->stream_analog_capture) {
da3cec35
TI
3838 if (snd_BUG_ON(!spec->adc_nids))
3839 return -EINVAL;
4a471b7d
TI
3840 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3841 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3842 }
3843
3844 if (spec->channel_mode) {
3845 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3846 for (i = 0; i < spec->num_channel_mode; i++) {
3847 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3848 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3849 }
1da177e4
LT
3850 }
3851 }
3852
e64f14f4 3853 skip_analog:
e08a007d 3854 /* SPDIF for stream index #1 */
1da177e4 3855 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
3856 snprintf(spec->stream_name_digital,
3857 sizeof(spec->stream_name_digital),
3858 "%s Digital", codec->chip_name);
e08a007d 3859 codec->num_pcms = 2;
b25c9da1 3860 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 3861 info = spec->pcm_rec + 1;
1da177e4 3862 info->name = spec->stream_name_digital;
8c441982
TI
3863 if (spec->dig_out_type)
3864 info->pcm_type = spec->dig_out_type;
3865 else
3866 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
3867 if (spec->multiout.dig_out_nid &&
3868 spec->stream_digital_playback) {
1da177e4
LT
3869 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3870 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3871 }
4a471b7d
TI
3872 if (spec->dig_in_nid &&
3873 spec->stream_digital_capture) {
1da177e4
LT
3874 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3875 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3876 }
963f803f
TI
3877 /* FIXME: do we need this for all Realtek codec models? */
3878 codec->spdif_status_reset = 1;
1da177e4
LT
3879 }
3880
e64f14f4
TI
3881 if (spec->no_analog)
3882 return 0;
3883
e08a007d
TI
3884 /* If the use of more than one ADC is requested for the current
3885 * model, configure a second analog capture-only PCM.
3886 */
3887 /* Additional Analaog capture for index #2 */
6330079f
TI
3888 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3889 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 3890 codec->num_pcms = 3;
c06134d7 3891 info = spec->pcm_rec + 2;
e08a007d 3892 info->name = spec->stream_name_analog;
6330079f
TI
3893 if (spec->alt_dac_nid) {
3894 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3895 *spec->stream_analog_alt_playback;
3896 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3897 spec->alt_dac_nid;
3898 } else {
3899 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3900 alc_pcm_null_stream;
3901 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3902 }
3903 if (spec->num_adc_nids > 1) {
3904 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3905 *spec->stream_analog_alt_capture;
3906 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3907 spec->adc_nids[1];
3908 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3909 spec->num_adc_nids - 1;
3910 } else {
3911 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3912 alc_pcm_null_stream;
3913 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
3914 }
3915 }
3916
1da177e4
LT
3917 return 0;
3918}
3919
a4e09aa3
TI
3920static inline void alc_shutup(struct hda_codec *codec)
3921{
3922 snd_hda_shutup_pins(codec);
3923}
3924
603c4019
TI
3925static void alc_free_kctls(struct hda_codec *codec)
3926{
3927 struct alc_spec *spec = codec->spec;
3928
3929 if (spec->kctls.list) {
3930 struct snd_kcontrol_new *kctl = spec->kctls.list;
3931 int i;
3932 for (i = 0; i < spec->kctls.used; i++)
3933 kfree(kctl[i].name);
3934 }
3935 snd_array_free(&spec->kctls);
3936}
3937
1da177e4
LT
3938static void alc_free(struct hda_codec *codec)
3939{
e9edcee0 3940 struct alc_spec *spec = codec->spec;
e9edcee0 3941
f12ab1e0 3942 if (!spec)
e9edcee0
TI
3943 return;
3944
a4e09aa3 3945 alc_shutup(codec);
603c4019 3946 alc_free_kctls(codec);
e9edcee0 3947 kfree(spec);
680cd536 3948 snd_hda_detach_beep_device(codec);
1da177e4
LT
3949}
3950
f5de24b0 3951#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
3952static void alc_power_eapd(struct hda_codec *codec)
3953{
3954 /* We currently only handle front, HP */
3955 switch (codec->vendor_id) {
3956 case 0x10ec0260:
9e4c8496
TI
3957 set_eapd(codec, 0x0f, 0);
3958 set_eapd(codec, 0x10, 0);
c97259df
DC
3959 break;
3960 case 0x10ec0262:
3961 case 0x10ec0267:
3962 case 0x10ec0268:
3963 case 0x10ec0269:
9e4c8496 3964 case 0x10ec0270:
c97259df
DC
3965 case 0x10ec0272:
3966 case 0x10ec0660:
3967 case 0x10ec0662:
3968 case 0x10ec0663:
3969 case 0x10ec0862:
3970 case 0x10ec0889:
9e4c8496
TI
3971 set_eapd(codec, 0x14, 0);
3972 set_eapd(codec, 0x15, 0);
c97259df
DC
3973 break;
3974 }
3975}
3976
f5de24b0
HM
3977static int alc_suspend(struct hda_codec *codec, pm_message_t state)
3978{
3979 struct alc_spec *spec = codec->spec;
a4e09aa3 3980 alc_shutup(codec);
f5de24b0 3981 if (spec && spec->power_hook)
c97259df 3982 spec->power_hook(codec);
f5de24b0
HM
3983 return 0;
3984}
3985#endif
3986
e044c39a 3987#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
3988static int alc_resume(struct hda_codec *codec)
3989{
e044c39a
TI
3990 codec->patch_ops.init(codec);
3991 snd_hda_codec_resume_amp(codec);
3992 snd_hda_codec_resume_cache(codec);
ad35879a
TI
3993#ifdef CONFIG_SND_HDA_POWER_SAVE
3994 if (codec->patch_ops.check_power_status)
3995 codec->patch_ops.check_power_status(codec, 0x01);
3996#endif
e044c39a
TI
3997 return 0;
3998}
e044c39a
TI
3999#endif
4000
1da177e4
LT
4001/*
4002 */
4003static struct hda_codec_ops alc_patch_ops = {
4004 .build_controls = alc_build_controls,
4005 .build_pcms = alc_build_pcms,
4006 .init = alc_init,
4007 .free = alc_free,
ae6b813a 4008 .unsol_event = alc_unsol_event,
e044c39a
TI
4009#ifdef SND_HDA_NEEDS_RESUME
4010 .resume = alc_resume,
4011#endif
cb53c626 4012#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4013 .suspend = alc_suspend,
cb53c626
TI
4014 .check_power_status = alc_check_power_status,
4015#endif
c97259df 4016 .reboot_notify = alc_shutup,
1da177e4
LT
4017};
4018
c027ddcd
KY
4019/* replace the codec chip_name with the given string */
4020static int alc_codec_rename(struct hda_codec *codec, const char *name)
4021{
4022 kfree(codec->chip_name);
4023 codec->chip_name = kstrdup(name, GFP_KERNEL);
4024 if (!codec->chip_name) {
4025 alc_free(codec);
4026 return -ENOMEM;
4027 }
4028 return 0;
4029}
4030
2fa522be
TI
4031/*
4032 * Test configuration for debugging
4033 *
4034 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4035 * enum controls.
4036 */
4037#ifdef CONFIG_SND_DEBUG
4038static hda_nid_t alc880_test_dac_nids[4] = {
4039 0x02, 0x03, 0x04, 0x05
4040};
4041
4042static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4043 .num_items = 7,
2fa522be
TI
4044 .items = {
4045 { "In-1", 0x0 },
4046 { "In-2", 0x1 },
4047 { "In-3", 0x2 },
4048 { "In-4", 0x3 },
4049 { "CD", 0x4 },
ae6b813a
TI
4050 { "Front", 0x5 },
4051 { "Surround", 0x6 },
2fa522be
TI
4052 },
4053};
4054
d2a6d7dc 4055static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4056 { 2, NULL },
fd2c326d 4057 { 4, NULL },
2fa522be 4058 { 6, NULL },
fd2c326d 4059 { 8, NULL },
2fa522be
TI
4060};
4061
9c7f852e
TI
4062static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4063 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4064{
4065 static char *texts[] = {
4066 "N/A", "Line Out", "HP Out",
4067 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4068 };
4069 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4070 uinfo->count = 1;
4071 uinfo->value.enumerated.items = 8;
4072 if (uinfo->value.enumerated.item >= 8)
4073 uinfo->value.enumerated.item = 7;
4074 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4075 return 0;
4076}
4077
9c7f852e
TI
4078static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4079 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4080{
4081 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4082 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4083 unsigned int pin_ctl, item = 0;
4084
4085 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4086 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4087 if (pin_ctl & AC_PINCTL_OUT_EN) {
4088 if (pin_ctl & AC_PINCTL_HP_EN)
4089 item = 2;
4090 else
4091 item = 1;
4092 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4093 switch (pin_ctl & AC_PINCTL_VREFEN) {
4094 case AC_PINCTL_VREF_HIZ: item = 3; break;
4095 case AC_PINCTL_VREF_50: item = 4; break;
4096 case AC_PINCTL_VREF_GRD: item = 5; break;
4097 case AC_PINCTL_VREF_80: item = 6; break;
4098 case AC_PINCTL_VREF_100: item = 7; break;
4099 }
4100 }
4101 ucontrol->value.enumerated.item[0] = item;
4102 return 0;
4103}
4104
9c7f852e
TI
4105static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4106 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4107{
4108 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4109 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4110 static unsigned int ctls[] = {
4111 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4112 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4113 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4114 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4115 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4116 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4117 };
4118 unsigned int old_ctl, new_ctl;
4119
4120 old_ctl = snd_hda_codec_read(codec, nid, 0,
4121 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4122 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4123 if (old_ctl != new_ctl) {
82beb8fd
TI
4124 int val;
4125 snd_hda_codec_write_cache(codec, nid, 0,
4126 AC_VERB_SET_PIN_WIDGET_CONTROL,
4127 new_ctl);
47fd830a
TI
4128 val = ucontrol->value.enumerated.item[0] >= 3 ?
4129 HDA_AMP_MUTE : 0;
4130 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4131 HDA_AMP_MUTE, val);
2fa522be
TI
4132 return 1;
4133 }
4134 return 0;
4135}
4136
9c7f852e
TI
4137static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4138 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4139{
4140 static char *texts[] = {
4141 "Front", "Surround", "CLFE", "Side"
4142 };
4143 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4144 uinfo->count = 1;
4145 uinfo->value.enumerated.items = 4;
4146 if (uinfo->value.enumerated.item >= 4)
4147 uinfo->value.enumerated.item = 3;
4148 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4149 return 0;
4150}
4151
9c7f852e
TI
4152static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4153 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4154{
4155 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4156 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4157 unsigned int sel;
4158
4159 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4160 ucontrol->value.enumerated.item[0] = sel & 3;
4161 return 0;
4162}
4163
9c7f852e
TI
4164static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4165 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4166{
4167 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4168 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4169 unsigned int sel;
4170
4171 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4172 if (ucontrol->value.enumerated.item[0] != sel) {
4173 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4174 snd_hda_codec_write_cache(codec, nid, 0,
4175 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4176 return 1;
4177 }
4178 return 0;
4179}
4180
4181#define PIN_CTL_TEST(xname,nid) { \
4182 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4183 .name = xname, \
5b0cb1d8 4184 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4185 .info = alc_test_pin_ctl_info, \
4186 .get = alc_test_pin_ctl_get, \
4187 .put = alc_test_pin_ctl_put, \
4188 .private_value = nid \
4189 }
4190
4191#define PIN_SRC_TEST(xname,nid) { \
4192 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4193 .name = xname, \
5b0cb1d8 4194 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4195 .info = alc_test_pin_src_info, \
4196 .get = alc_test_pin_src_get, \
4197 .put = alc_test_pin_src_put, \
4198 .private_value = nid \
4199 }
4200
c8b6bf9b 4201static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4202 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4203 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4204 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4205 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4206 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4207 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4208 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4209 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4210 PIN_CTL_TEST("Front Pin Mode", 0x14),
4211 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4212 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4213 PIN_CTL_TEST("Side Pin Mode", 0x17),
4214 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4215 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4216 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4217 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4218 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4219 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4220 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4221 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4222 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4223 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4224 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4225 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4226 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4227 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4228 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4229 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4230 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4231 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4232 {
4233 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4234 .name = "Channel Mode",
df694daa
KY
4235 .info = alc_ch_mode_info,
4236 .get = alc_ch_mode_get,
4237 .put = alc_ch_mode_put,
2fa522be
TI
4238 },
4239 { } /* end */
4240};
4241
4242static struct hda_verb alc880_test_init_verbs[] = {
4243 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4244 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4245 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4246 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4247 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4248 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4249 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4250 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4251 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4252 /* Vol output for 0x0c-0x0f */
05acb863
TI
4253 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4254 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4255 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4256 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4257 /* Set output pins 0x14-0x17 */
05acb863
TI
4258 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4259 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4260 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4261 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4262 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4263 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4264 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4265 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4266 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4267 /* Set input pins 0x18-0x1c */
16ded525
TI
4268 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4269 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4270 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4271 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4272 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4273 /* Mute input pins 0x18-0x1b */
05acb863
TI
4274 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4275 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4276 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4277 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4278 /* ADC set up */
05acb863 4279 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4280 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4281 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4282 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4283 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4284 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4285 /* Analog input/passthru */
4286 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4287 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4288 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4289 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4290 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4291 { }
4292};
4293#endif
4294
1da177e4
LT
4295/*
4296 */
4297
f5fcc13c
TI
4298static const char *alc880_models[ALC880_MODEL_LAST] = {
4299 [ALC880_3ST] = "3stack",
4300 [ALC880_TCL_S700] = "tcl",
4301 [ALC880_3ST_DIG] = "3stack-digout",
4302 [ALC880_CLEVO] = "clevo",
4303 [ALC880_5ST] = "5stack",
4304 [ALC880_5ST_DIG] = "5stack-digout",
4305 [ALC880_W810] = "w810",
4306 [ALC880_Z71V] = "z71v",
4307 [ALC880_6ST] = "6stack",
4308 [ALC880_6ST_DIG] = "6stack-digout",
4309 [ALC880_ASUS] = "asus",
4310 [ALC880_ASUS_W1V] = "asus-w1v",
4311 [ALC880_ASUS_DIG] = "asus-dig",
4312 [ALC880_ASUS_DIG2] = "asus-dig2",
4313 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4314 [ALC880_UNIWILL_P53] = "uniwill-p53",
4315 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4316 [ALC880_F1734] = "F1734",
4317 [ALC880_LG] = "lg",
4318 [ALC880_LG_LW] = "lg-lw",
df99cd33 4319 [ALC880_MEDION_RIM] = "medion",
2fa522be 4320#ifdef CONFIG_SND_DEBUG
f5fcc13c 4321 [ALC880_TEST] = "test",
2fa522be 4322#endif
f5fcc13c
TI
4323 [ALC880_AUTO] = "auto",
4324};
4325
4326static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4327 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4328 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4329 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4330 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4331 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4332 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4333 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4334 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4335 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4336 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4337 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4338 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4339 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4340 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4341 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4342 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4343 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4344 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4345 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4346 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4347 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4348 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4349 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4350 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4351 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4352 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4353 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4354 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4355 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4356 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4357 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4358 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4359 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4360 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4361 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4362 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4363 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4364 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4365 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4366 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 4367 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
4368 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4369 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4370 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4371 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4372 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4373 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4374 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4375 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4376 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4377 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4378 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
4379 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4380 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4381 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4382 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4383 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4384 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4385 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4386 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4387 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4388 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4389 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4390 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4391 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4392 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4393 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4394 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4395 /* default Intel */
4396 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4397 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4398 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4399 {}
4400};
4401
16ded525 4402/*
df694daa 4403 * ALC880 codec presets
16ded525 4404 */
16ded525
TI
4405static struct alc_config_preset alc880_presets[] = {
4406 [ALC880_3ST] = {
e9edcee0 4407 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4408 .init_verbs = { alc880_volume_init_verbs,
4409 alc880_pin_3stack_init_verbs },
16ded525 4410 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4411 .dac_nids = alc880_dac_nids,
16ded525
TI
4412 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4413 .channel_mode = alc880_threestack_modes,
4e195a7b 4414 .need_dac_fix = 1,
16ded525
TI
4415 .input_mux = &alc880_capture_source,
4416 },
4417 [ALC880_3ST_DIG] = {
e9edcee0 4418 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4419 .init_verbs = { alc880_volume_init_verbs,
4420 alc880_pin_3stack_init_verbs },
16ded525 4421 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4422 .dac_nids = alc880_dac_nids,
4423 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4424 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4425 .channel_mode = alc880_threestack_modes,
4e195a7b 4426 .need_dac_fix = 1,
16ded525
TI
4427 .input_mux = &alc880_capture_source,
4428 },
df694daa
KY
4429 [ALC880_TCL_S700] = {
4430 .mixers = { alc880_tcl_s700_mixer },
4431 .init_verbs = { alc880_volume_init_verbs,
4432 alc880_pin_tcl_S700_init_verbs,
4433 alc880_gpio2_init_verbs },
4434 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4435 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4436 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4437 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4438 .hp_nid = 0x03,
4439 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4440 .channel_mode = alc880_2_jack_modes,
4441 .input_mux = &alc880_capture_source,
4442 },
16ded525 4443 [ALC880_5ST] = {
f12ab1e0
TI
4444 .mixers = { alc880_three_stack_mixer,
4445 alc880_five_stack_mixer},
4446 .init_verbs = { alc880_volume_init_verbs,
4447 alc880_pin_5stack_init_verbs },
16ded525
TI
4448 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4449 .dac_nids = alc880_dac_nids,
16ded525
TI
4450 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4451 .channel_mode = alc880_fivestack_modes,
4452 .input_mux = &alc880_capture_source,
4453 },
4454 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4455 .mixers = { alc880_three_stack_mixer,
4456 alc880_five_stack_mixer },
4457 .init_verbs = { alc880_volume_init_verbs,
4458 alc880_pin_5stack_init_verbs },
16ded525
TI
4459 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4460 .dac_nids = alc880_dac_nids,
4461 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4462 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4463 .channel_mode = alc880_fivestack_modes,
4464 .input_mux = &alc880_capture_source,
4465 },
b6482d48
TI
4466 [ALC880_6ST] = {
4467 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4468 .init_verbs = { alc880_volume_init_verbs,
4469 alc880_pin_6stack_init_verbs },
b6482d48
TI
4470 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4471 .dac_nids = alc880_6st_dac_nids,
4472 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4473 .channel_mode = alc880_sixstack_modes,
4474 .input_mux = &alc880_6stack_capture_source,
4475 },
16ded525 4476 [ALC880_6ST_DIG] = {
e9edcee0 4477 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4478 .init_verbs = { alc880_volume_init_verbs,
4479 alc880_pin_6stack_init_verbs },
16ded525
TI
4480 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4481 .dac_nids = alc880_6st_dac_nids,
4482 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4483 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4484 .channel_mode = alc880_sixstack_modes,
4485 .input_mux = &alc880_6stack_capture_source,
4486 },
4487 [ALC880_W810] = {
e9edcee0 4488 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4489 .init_verbs = { alc880_volume_init_verbs,
4490 alc880_pin_w810_init_verbs,
b0af0de5 4491 alc880_gpio2_init_verbs },
16ded525
TI
4492 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4493 .dac_nids = alc880_w810_dac_nids,
4494 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4495 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4496 .channel_mode = alc880_w810_modes,
4497 .input_mux = &alc880_capture_source,
4498 },
4499 [ALC880_Z71V] = {
e9edcee0 4500 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
4501 .init_verbs = { alc880_volume_init_verbs,
4502 alc880_pin_z71v_init_verbs },
16ded525
TI
4503 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4504 .dac_nids = alc880_z71v_dac_nids,
4505 .dig_out_nid = ALC880_DIGOUT_NID,
4506 .hp_nid = 0x03,
e9edcee0
TI
4507 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4508 .channel_mode = alc880_2_jack_modes,
16ded525
TI
4509 .input_mux = &alc880_capture_source,
4510 },
4511 [ALC880_F1734] = {
e9edcee0 4512 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
4513 .init_verbs = { alc880_volume_init_verbs,
4514 alc880_pin_f1734_init_verbs },
e9edcee0
TI
4515 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4516 .dac_nids = alc880_f1734_dac_nids,
4517 .hp_nid = 0x02,
4518 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4519 .channel_mode = alc880_2_jack_modes,
937b4160
TI
4520 .input_mux = &alc880_f1734_capture_source,
4521 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4522 .setup = alc880_uniwill_p53_setup,
4523 .init_hook = alc_automute_amp,
16ded525
TI
4524 },
4525 [ALC880_ASUS] = {
e9edcee0 4526 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4527 .init_verbs = { alc880_volume_init_verbs,
4528 alc880_pin_asus_init_verbs,
e9edcee0
TI
4529 alc880_gpio1_init_verbs },
4530 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4531 .dac_nids = alc880_asus_dac_nids,
4532 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4533 .channel_mode = alc880_asus_modes,
4e195a7b 4534 .need_dac_fix = 1,
16ded525
TI
4535 .input_mux = &alc880_capture_source,
4536 },
4537 [ALC880_ASUS_DIG] = {
e9edcee0 4538 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4539 .init_verbs = { alc880_volume_init_verbs,
4540 alc880_pin_asus_init_verbs,
e9edcee0
TI
4541 alc880_gpio1_init_verbs },
4542 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4543 .dac_nids = alc880_asus_dac_nids,
16ded525 4544 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4545 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4546 .channel_mode = alc880_asus_modes,
4e195a7b 4547 .need_dac_fix = 1,
16ded525
TI
4548 .input_mux = &alc880_capture_source,
4549 },
df694daa
KY
4550 [ALC880_ASUS_DIG2] = {
4551 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4552 .init_verbs = { alc880_volume_init_verbs,
4553 alc880_pin_asus_init_verbs,
df694daa
KY
4554 alc880_gpio2_init_verbs }, /* use GPIO2 */
4555 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4556 .dac_nids = alc880_asus_dac_nids,
4557 .dig_out_nid = ALC880_DIGOUT_NID,
4558 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4559 .channel_mode = alc880_asus_modes,
4e195a7b 4560 .need_dac_fix = 1,
df694daa
KY
4561 .input_mux = &alc880_capture_source,
4562 },
16ded525 4563 [ALC880_ASUS_W1V] = {
e9edcee0 4564 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
4565 .init_verbs = { alc880_volume_init_verbs,
4566 alc880_pin_asus_init_verbs,
e9edcee0
TI
4567 alc880_gpio1_init_verbs },
4568 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4569 .dac_nids = alc880_asus_dac_nids,
16ded525 4570 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4571 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4572 .channel_mode = alc880_asus_modes,
4e195a7b 4573 .need_dac_fix = 1,
16ded525
TI
4574 .input_mux = &alc880_capture_source,
4575 },
4576 [ALC880_UNIWILL_DIG] = {
45bdd1c1 4577 .mixers = { alc880_asus_mixer },
ccc656ce
KY
4578 .init_verbs = { alc880_volume_init_verbs,
4579 alc880_pin_asus_init_verbs },
e9edcee0
TI
4580 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4581 .dac_nids = alc880_asus_dac_nids,
16ded525 4582 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4583 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4584 .channel_mode = alc880_asus_modes,
4e195a7b 4585 .need_dac_fix = 1,
16ded525
TI
4586 .input_mux = &alc880_capture_source,
4587 },
ccc656ce
KY
4588 [ALC880_UNIWILL] = {
4589 .mixers = { alc880_uniwill_mixer },
4590 .init_verbs = { alc880_volume_init_verbs,
4591 alc880_uniwill_init_verbs },
4592 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4593 .dac_nids = alc880_asus_dac_nids,
4594 .dig_out_nid = ALC880_DIGOUT_NID,
4595 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4596 .channel_mode = alc880_threestack_modes,
4597 .need_dac_fix = 1,
4598 .input_mux = &alc880_capture_source,
4599 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 4600 .setup = alc880_uniwill_setup,
a9fd4f3f 4601 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
4602 },
4603 [ALC880_UNIWILL_P53] = {
4604 .mixers = { alc880_uniwill_p53_mixer },
4605 .init_verbs = { alc880_volume_init_verbs,
4606 alc880_uniwill_p53_init_verbs },
4607 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4608 .dac_nids = alc880_asus_dac_nids,
4609 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4610 .channel_mode = alc880_threestack_modes,
4611 .input_mux = &alc880_capture_source,
4612 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4613 .setup = alc880_uniwill_p53_setup,
4614 .init_hook = alc_automute_amp,
2cf9f0fc
TD
4615 },
4616 [ALC880_FUJITSU] = {
45bdd1c1 4617 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4618 .init_verbs = { alc880_volume_init_verbs,
4619 alc880_uniwill_p53_init_verbs,
4620 alc880_beep_init_verbs },
4621 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4622 .dac_nids = alc880_dac_nids,
d53d7d9e 4623 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4624 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4625 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4626 .input_mux = &alc880_capture_source,
4627 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4628 .setup = alc880_uniwill_p53_setup,
4629 .init_hook = alc_automute_amp,
ccc656ce 4630 },
df694daa
KY
4631 [ALC880_CLEVO] = {
4632 .mixers = { alc880_three_stack_mixer },
4633 .init_verbs = { alc880_volume_init_verbs,
4634 alc880_pin_clevo_init_verbs },
4635 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4636 .dac_nids = alc880_dac_nids,
4637 .hp_nid = 0x03,
4638 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4639 .channel_mode = alc880_threestack_modes,
4e195a7b 4640 .need_dac_fix = 1,
df694daa
KY
4641 .input_mux = &alc880_capture_source,
4642 },
ae6b813a
TI
4643 [ALC880_LG] = {
4644 .mixers = { alc880_lg_mixer },
4645 .init_verbs = { alc880_volume_init_verbs,
4646 alc880_lg_init_verbs },
4647 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4648 .dac_nids = alc880_lg_dac_nids,
4649 .dig_out_nid = ALC880_DIGOUT_NID,
4650 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4651 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4652 .need_dac_fix = 1,
ae6b813a 4653 .input_mux = &alc880_lg_capture_source,
a9fd4f3f 4654 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4655 .setup = alc880_lg_setup,
4656 .init_hook = alc_automute_amp,
cb53c626
TI
4657#ifdef CONFIG_SND_HDA_POWER_SAVE
4658 .loopbacks = alc880_lg_loopbacks,
4659#endif
ae6b813a 4660 },
d681518a
TI
4661 [ALC880_LG_LW] = {
4662 .mixers = { alc880_lg_lw_mixer },
4663 .init_verbs = { alc880_volume_init_verbs,
4664 alc880_lg_lw_init_verbs },
0a8c5da3 4665 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
4666 .dac_nids = alc880_dac_nids,
4667 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
4668 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4669 .channel_mode = alc880_lg_lw_modes,
d681518a 4670 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f 4671 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4672 .setup = alc880_lg_lw_setup,
4673 .init_hook = alc_automute_amp,
d681518a 4674 },
df99cd33
TI
4675 [ALC880_MEDION_RIM] = {
4676 .mixers = { alc880_medion_rim_mixer },
4677 .init_verbs = { alc880_volume_init_verbs,
4678 alc880_medion_rim_init_verbs,
4679 alc_gpio2_init_verbs },
4680 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4681 .dac_nids = alc880_dac_nids,
4682 .dig_out_nid = ALC880_DIGOUT_NID,
4683 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4684 .channel_mode = alc880_2_jack_modes,
4685 .input_mux = &alc880_medion_rim_capture_source,
4686 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
4687 .setup = alc880_medion_rim_setup,
4688 .init_hook = alc880_medion_rim_automute,
df99cd33 4689 },
16ded525
TI
4690#ifdef CONFIG_SND_DEBUG
4691 [ALC880_TEST] = {
e9edcee0
TI
4692 .mixers = { alc880_test_mixer },
4693 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
4694 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4695 .dac_nids = alc880_test_dac_nids,
4696 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4697 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4698 .channel_mode = alc880_test_modes,
4699 .input_mux = &alc880_test_capture_source,
4700 },
4701#endif
4702};
4703
e9edcee0
TI
4704/*
4705 * Automatic parse of I/O pins from the BIOS configuration
4706 */
4707
e9edcee0
TI
4708enum {
4709 ALC_CTL_WIDGET_VOL,
4710 ALC_CTL_WIDGET_MUTE,
4711 ALC_CTL_BIND_MUTE,
4712};
c8b6bf9b 4713static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
4714 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4715 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 4716 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
4717};
4718
4719/* add dynamic controls */
f12ab1e0
TI
4720static int add_control(struct alc_spec *spec, int type, const char *name,
4721 unsigned long val)
e9edcee0 4722{
c8b6bf9b 4723 struct snd_kcontrol_new *knew;
e9edcee0 4724
603c4019
TI
4725 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4726 knew = snd_array_new(&spec->kctls);
4727 if (!knew)
4728 return -ENOMEM;
e9edcee0 4729 *knew = alc880_control_templates[type];
543537bd 4730 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 4731 if (!knew->name)
e9edcee0 4732 return -ENOMEM;
4d02d1b6 4733 if (get_amp_nid_(val))
5e26dfd0 4734 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 4735 knew->private_value = val;
e9edcee0
TI
4736 return 0;
4737}
4738
0afe5f89
TI
4739static int add_control_with_pfx(struct alc_spec *spec, int type,
4740 const char *pfx, const char *dir,
4741 const char *sfx, unsigned long val)
4742{
4743 char name[32];
4744 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
4745 return add_control(spec, type, name, val);
4746}
4747
4748#define add_pb_vol_ctrl(spec, type, pfx, val) \
4749 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val)
4750#define add_pb_sw_ctrl(spec, type, pfx, val) \
4751 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val)
4752
e9edcee0
TI
4753#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4754#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4755#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4756#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
4757#define alc880_idx_to_dac(nid) ((nid) + 0x02)
4758#define alc880_dac_to_idx(nid) ((nid) - 0x02)
4759#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4760#define alc880_idx_to_selector(nid) ((nid) + 0x10)
4761#define ALC880_PIN_CD_NID 0x1c
4762
4763/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
4764static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4765 const struct auto_pin_cfg *cfg)
e9edcee0
TI
4766{
4767 hda_nid_t nid;
4768 int assigned[4];
4769 int i, j;
4770
4771 memset(assigned, 0, sizeof(assigned));
b0af0de5 4772 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
4773
4774 /* check the pins hardwired to audio widget */
4775 for (i = 0; i < cfg->line_outs; i++) {
4776 nid = cfg->line_out_pins[i];
4777 if (alc880_is_fixed_pin(nid)) {
4778 int idx = alc880_fixed_pin_idx(nid);
5014f193 4779 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
4780 assigned[idx] = 1;
4781 }
4782 }
4783 /* left pins can be connect to any audio widget */
4784 for (i = 0; i < cfg->line_outs; i++) {
4785 nid = cfg->line_out_pins[i];
4786 if (alc880_is_fixed_pin(nid))
4787 continue;
4788 /* search for an empty channel */
4789 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
4790 if (!assigned[j]) {
4791 spec->multiout.dac_nids[i] =
4792 alc880_idx_to_dac(j);
e9edcee0
TI
4793 assigned[j] = 1;
4794 break;
4795 }
4796 }
4797 }
4798 spec->multiout.num_dacs = cfg->line_outs;
4799 return 0;
4800}
4801
4802/* add playback controls from the parsed DAC table */
df694daa
KY
4803static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4804 const struct auto_pin_cfg *cfg)
e9edcee0 4805{
f12ab1e0
TI
4806 static const char *chname[4] = {
4807 "Front", "Surround", NULL /*CLFE*/, "Side"
4808 };
e9edcee0
TI
4809 hda_nid_t nid;
4810 int i, err;
4811
4812 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 4813 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
4814 continue;
4815 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4816 if (i == 2) {
4817 /* Center/LFE */
0afe5f89
TI
4818 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4819 "Center",
f12ab1e0
TI
4820 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4821 HDA_OUTPUT));
4822 if (err < 0)
e9edcee0 4823 return err;
0afe5f89
TI
4824 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4825 "LFE",
f12ab1e0
TI
4826 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4827 HDA_OUTPUT));
4828 if (err < 0)
e9edcee0 4829 return err;
0afe5f89
TI
4830 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4831 "Center",
f12ab1e0
TI
4832 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4833 HDA_INPUT));
4834 if (err < 0)
e9edcee0 4835 return err;
0afe5f89
TI
4836 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4837 "LFE",
f12ab1e0
TI
4838 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4839 HDA_INPUT));
4840 if (err < 0)
e9edcee0
TI
4841 return err;
4842 } else {
cb162b6b
TI
4843 const char *pfx;
4844 if (cfg->line_outs == 1 &&
4845 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4846 pfx = "Speaker";
4847 else
4848 pfx = chname[i];
0afe5f89 4849 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
4850 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4851 HDA_OUTPUT));
4852 if (err < 0)
e9edcee0 4853 return err;
0afe5f89 4854 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
4855 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4856 HDA_INPUT));
4857 if (err < 0)
e9edcee0
TI
4858 return err;
4859 }
4860 }
e9edcee0
TI
4861 return 0;
4862}
4863
8d88bc3d
TI
4864/* add playback controls for speaker and HP outputs */
4865static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4866 const char *pfx)
e9edcee0
TI
4867{
4868 hda_nid_t nid;
4869 int err;
4870
f12ab1e0 4871 if (!pin)
e9edcee0
TI
4872 return 0;
4873
4874 if (alc880_is_fixed_pin(pin)) {
4875 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 4876 /* specify the DAC as the extra output */
f12ab1e0 4877 if (!spec->multiout.hp_nid)
e9edcee0 4878 spec->multiout.hp_nid = nid;
82bc955f
TI
4879 else
4880 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
4881 /* control HP volume/switch on the output mixer amp */
4882 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 4883 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
4884 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4885 if (err < 0)
e9edcee0 4886 return err;
0afe5f89 4887 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
4888 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4889 if (err < 0)
e9edcee0
TI
4890 return err;
4891 } else if (alc880_is_multi_pin(pin)) {
4892 /* set manual connection */
e9edcee0 4893 /* we have only a switch on HP-out PIN */
0afe5f89 4894 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
4895 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4896 if (err < 0)
e9edcee0
TI
4897 return err;
4898 }
4899 return 0;
4900}
4901
4902/* create input playback/capture controls for the given pin */
f12ab1e0
TI
4903static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4904 const char *ctlname,
df694daa 4905 int idx, hda_nid_t mix_nid)
e9edcee0 4906{
df694daa 4907 int err;
e9edcee0 4908
0afe5f89 4909 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
f12ab1e0
TI
4910 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4911 if (err < 0)
e9edcee0 4912 return err;
0afe5f89 4913 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
f12ab1e0
TI
4914 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4915 if (err < 0)
e9edcee0
TI
4916 return err;
4917 return 0;
4918}
4919
05f5f477
TI
4920static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
4921{
4922 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
4923 return (pincap & AC_PINCAP_IN) != 0;
4924}
4925
e9edcee0 4926/* create playback/capture controls for input pins */
05f5f477
TI
4927static int alc_auto_create_input_ctls(struct hda_codec *codec,
4928 const struct auto_pin_cfg *cfg,
4929 hda_nid_t mixer,
4930 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 4931{
05f5f477 4932 struct alc_spec *spec = codec->spec;
61b9b9b1 4933 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa 4934 int i, err, idx;
e9edcee0
TI
4935
4936 for (i = 0; i < AUTO_PIN_LAST; i++) {
05f5f477
TI
4937 hda_nid_t pin;
4938
4939 pin = cfg->input_pins[i];
4940 if (!alc_is_input_pin(codec, pin))
4941 continue;
4942
4943 if (mixer) {
4944 idx = get_connection_index(codec, mixer, pin);
4945 if (idx >= 0) {
4946 err = new_analog_input(spec, pin,
4947 auto_pin_cfg_labels[i],
4948 idx, mixer);
4949 if (err < 0)
4950 return err;
4951 }
4952 }
4953
4954 if (!cap1)
4955 continue;
4956 idx = get_connection_index(codec, cap1, pin);
4957 if (idx < 0 && cap2)
4958 idx = get_connection_index(codec, cap2, pin);
4959 if (idx >= 0) {
f12ab1e0
TI
4960 imux->items[imux->num_items].label =
4961 auto_pin_cfg_labels[i];
05f5f477 4962 imux->items[imux->num_items].index = idx;
e9edcee0
TI
4963 imux->num_items++;
4964 }
4965 }
4966 return 0;
4967}
4968
05f5f477
TI
4969static int alc880_auto_create_input_ctls(struct hda_codec *codec,
4970 const struct auto_pin_cfg *cfg)
4971{
4972 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
4973}
4974
f6c7e546
TI
4975static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4976 unsigned int pin_type)
4977{
4978 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4979 pin_type);
4980 /* unmute pin */
d260cdf6
TI
4981 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4982 AMP_OUT_UNMUTE);
f6c7e546
TI
4983}
4984
df694daa
KY
4985static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4986 hda_nid_t nid, int pin_type,
e9edcee0
TI
4987 int dac_idx)
4988{
f6c7e546 4989 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
4990 /* need the manual connection? */
4991 if (alc880_is_multi_pin(nid)) {
4992 struct alc_spec *spec = codec->spec;
4993 int idx = alc880_multi_pin_idx(nid);
4994 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4995 AC_VERB_SET_CONNECT_SEL,
4996 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4997 }
4998}
4999
baba8ee9
TI
5000static int get_pin_type(int line_out_type)
5001{
5002 if (line_out_type == AUTO_PIN_HP_OUT)
5003 return PIN_HP;
5004 else
5005 return PIN_OUT;
5006}
5007
e9edcee0
TI
5008static void alc880_auto_init_multi_out(struct hda_codec *codec)
5009{
5010 struct alc_spec *spec = codec->spec;
5011 int i;
ea1fb29a 5012
e9edcee0
TI
5013 for (i = 0; i < spec->autocfg.line_outs; i++) {
5014 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5015 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5016 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5017 }
5018}
5019
8d88bc3d 5020static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5021{
5022 struct alc_spec *spec = codec->spec;
5023 hda_nid_t pin;
5024
82bc955f 5025 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5026 if (pin) /* connect to front */
5027 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5028 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5029 if (pin) /* connect to front */
5030 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5031}
5032
5033static void alc880_auto_init_analog_input(struct hda_codec *codec)
5034{
5035 struct alc_spec *spec = codec->spec;
5036 int i;
5037
5038 for (i = 0; i < AUTO_PIN_LAST; i++) {
5039 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 5040 if (alc_is_input_pin(codec, nid)) {
23f0c048 5041 alc_set_input_pin(codec, nid, i);
e82c025b
TI
5042 if (nid != ALC880_PIN_CD_NID &&
5043 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5044 snd_hda_codec_write(codec, nid, 0,
5045 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5046 AMP_OUT_MUTE);
5047 }
5048 }
5049}
5050
7f311a46
TI
5051static void alc880_auto_init_input_src(struct hda_codec *codec)
5052{
5053 struct alc_spec *spec = codec->spec;
5054 int c;
5055
5056 for (c = 0; c < spec->num_adc_nids; c++) {
5057 unsigned int mux_idx;
5058 const struct hda_input_mux *imux;
5059 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5060 imux = &spec->input_mux[mux_idx];
5061 if (!imux->num_items && mux_idx > 0)
5062 imux = &spec->input_mux[0];
5063 if (imux)
5064 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5065 AC_VERB_SET_CONNECT_SEL,
5066 imux->items[0].index);
5067 }
5068}
5069
e9edcee0 5070/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5071/* return 1 if successful, 0 if the proper config is not found,
5072 * or a negative error code
5073 */
e9edcee0
TI
5074static int alc880_parse_auto_config(struct hda_codec *codec)
5075{
5076 struct alc_spec *spec = codec->spec;
757899ac 5077 int err;
df694daa 5078 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5079
f12ab1e0
TI
5080 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5081 alc880_ignore);
5082 if (err < 0)
e9edcee0 5083 return err;
f12ab1e0 5084 if (!spec->autocfg.line_outs)
e9edcee0 5085 return 0; /* can't find valid BIOS pin config */
df694daa 5086
f12ab1e0
TI
5087 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5088 if (err < 0)
5089 return err;
5090 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5091 if (err < 0)
5092 return err;
5093 err = alc880_auto_create_extra_out(spec,
5094 spec->autocfg.speaker_pins[0],
5095 "Speaker");
5096 if (err < 0)
5097 return err;
5098 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5099 "Headphone");
5100 if (err < 0)
5101 return err;
05f5f477 5102 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5103 if (err < 0)
e9edcee0
TI
5104 return err;
5105
5106 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5107
757899ac 5108 alc_auto_parse_digital(codec);
e9edcee0 5109
603c4019 5110 if (spec->kctls.list)
d88897ea 5111 add_mixer(spec, spec->kctls.list);
e9edcee0 5112
d88897ea 5113 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5114
a1e8d2da 5115 spec->num_mux_defs = 1;
61b9b9b1 5116 spec->input_mux = &spec->private_imux[0];
e9edcee0 5117
6227cdce 5118 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5119
e9edcee0
TI
5120 return 1;
5121}
5122
ae6b813a
TI
5123/* additional initialization for auto-configuration model */
5124static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5125{
f6c7e546 5126 struct alc_spec *spec = codec->spec;
e9edcee0 5127 alc880_auto_init_multi_out(codec);
8d88bc3d 5128 alc880_auto_init_extra_out(codec);
e9edcee0 5129 alc880_auto_init_analog_input(codec);
7f311a46 5130 alc880_auto_init_input_src(codec);
757899ac 5131 alc_auto_init_digital(codec);
f6c7e546 5132 if (spec->unsol_event)
7fb0d78f 5133 alc_inithook(codec);
e9edcee0
TI
5134}
5135
b59bdf3b
TI
5136/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5137 * one of two digital mic pins, e.g. on ALC272
5138 */
5139static void fixup_automic_adc(struct hda_codec *codec)
5140{
5141 struct alc_spec *spec = codec->spec;
5142 int i;
5143
5144 for (i = 0; i < spec->num_adc_nids; i++) {
5145 hda_nid_t cap = spec->capsrc_nids ?
5146 spec->capsrc_nids[i] : spec->adc_nids[i];
5147 int iidx, eidx;
5148
5149 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5150 if (iidx < 0)
5151 continue;
5152 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5153 if (eidx < 0)
5154 continue;
5155 spec->int_mic.mux_idx = iidx;
5156 spec->ext_mic.mux_idx = eidx;
5157 if (spec->capsrc_nids)
5158 spec->capsrc_nids += i;
5159 spec->adc_nids += i;
5160 spec->num_adc_nids = 1;
5161 return;
5162 }
5163 snd_printd(KERN_INFO "hda_codec: %s: "
5164 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5165 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5166 spec->auto_mic = 0; /* disable auto-mic to be sure */
5167}
5168
748cce43
TI
5169/* select or unmute the given capsrc route */
5170static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5171 int idx)
5172{
5173 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5174 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5175 HDA_AMP_MUTE, 0);
5176 } else {
5177 snd_hda_codec_write_cache(codec, cap, 0,
5178 AC_VERB_SET_CONNECT_SEL, idx);
5179 }
5180}
5181
840b64c0
TI
5182/* set the default connection to that pin */
5183static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5184{
5185 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5186 int i;
5187
eaa9b3a7
TI
5188 for (i = 0; i < spec->num_adc_nids; i++) {
5189 hda_nid_t cap = spec->capsrc_nids ?
5190 spec->capsrc_nids[i] : spec->adc_nids[i];
5191 int idx;
5192
5193 idx = get_connection_index(codec, cap, pin);
5194 if (idx < 0)
5195 continue;
748cce43 5196 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5197 return i; /* return the found index */
5198 }
5199 return -1; /* not found */
5200}
5201
5202/* choose the ADC/MUX containing the input pin and initialize the setup */
5203static void fixup_single_adc(struct hda_codec *codec)
5204{
5205 struct alc_spec *spec = codec->spec;
5206 hda_nid_t pin = 0;
5207 int i;
5208
5209 /* search for the input pin; there must be only one */
5210 for (i = 0; i < AUTO_PIN_LAST; i++) {
5211 if (spec->autocfg.input_pins[i]) {
5212 pin = spec->autocfg.input_pins[i];
5213 break;
5214 }
5215 }
5216 if (!pin)
eaa9b3a7 5217 return;
840b64c0
TI
5218 i = init_capsrc_for_pin(codec, pin);
5219 if (i >= 0) {
5220 /* use only this ADC */
5221 if (spec->capsrc_nids)
5222 spec->capsrc_nids += i;
5223 spec->adc_nids += i;
5224 spec->num_adc_nids = 1;
eaa9b3a7
TI
5225 }
5226}
5227
840b64c0
TI
5228/* initialize dual adcs */
5229static void fixup_dual_adc_switch(struct hda_codec *codec)
5230{
5231 struct alc_spec *spec = codec->spec;
5232 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5233 init_capsrc_for_pin(codec, spec->int_mic.pin);
5234}
5235
b59bdf3b 5236static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5237{
b59bdf3b 5238 struct alc_spec *spec = codec->spec;
a23b688f
TI
5239 static struct snd_kcontrol_new *caps[2][3] = {
5240 { alc_capture_mixer_nosrc1,
5241 alc_capture_mixer_nosrc2,
5242 alc_capture_mixer_nosrc3 },
5243 { alc_capture_mixer1,
5244 alc_capture_mixer2,
5245 alc_capture_mixer3 },
f9e336f6 5246 };
a23b688f 5247 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5248 int mux = 0;
840b64c0
TI
5249 int num_adcs = spec->num_adc_nids;
5250 if (spec->dual_adc_switch)
5251 fixup_dual_adc_switch(codec);
5252 else if (spec->auto_mic)
b59bdf3b 5253 fixup_automic_adc(codec);
eaa9b3a7
TI
5254 else if (spec->input_mux) {
5255 if (spec->input_mux->num_items > 1)
5256 mux = 1;
5257 else if (spec->input_mux->num_items == 1)
5258 fixup_single_adc(codec);
5259 }
840b64c0
TI
5260 if (spec->dual_adc_switch)
5261 num_adcs = 1;
5262 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5263 }
f9e336f6
TI
5264}
5265
6694635d
TI
5266/* fill adc_nids (and capsrc_nids) containing all active input pins */
5267static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5268 int num_nids)
5269{
5270 struct alc_spec *spec = codec->spec;
5271 int n;
5272 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5273
5274 for (n = 0; n < num_nids; n++) {
5275 hda_nid_t adc, cap;
5276 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5277 int nconns, i, j;
5278
5279 adc = nids[n];
5280 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5281 continue;
5282 cap = adc;
5283 nconns = snd_hda_get_connections(codec, cap, conn,
5284 ARRAY_SIZE(conn));
5285 if (nconns == 1) {
5286 cap = conn[0];
5287 nconns = snd_hda_get_connections(codec, cap, conn,
5288 ARRAY_SIZE(conn));
5289 }
5290 if (nconns <= 0)
5291 continue;
5292 if (!fallback_adc) {
5293 fallback_adc = adc;
5294 fallback_cap = cap;
5295 }
5296 for (i = 0; i < AUTO_PIN_LAST; i++) {
5297 hda_nid_t nid = spec->autocfg.input_pins[i];
5298 if (!nid)
5299 continue;
5300 for (j = 0; j < nconns; j++) {
5301 if (conn[j] == nid)
5302 break;
5303 }
5304 if (j >= nconns)
5305 break;
5306 }
5307 if (i >= AUTO_PIN_LAST) {
5308 int num_adcs = spec->num_adc_nids;
5309 spec->private_adc_nids[num_adcs] = adc;
5310 spec->private_capsrc_nids[num_adcs] = cap;
5311 spec->num_adc_nids++;
5312 spec->adc_nids = spec->private_adc_nids;
5313 if (adc != cap)
5314 spec->capsrc_nids = spec->private_capsrc_nids;
5315 }
5316 }
5317 if (!spec->num_adc_nids) {
5318 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5319 " using fallback 0x%x\n",
5320 codec->chip_name, fallback_adc);
6694635d
TI
5321 spec->private_adc_nids[0] = fallback_adc;
5322 spec->adc_nids = spec->private_adc_nids;
5323 if (fallback_adc != fallback_cap) {
5324 spec->private_capsrc_nids[0] = fallback_cap;
5325 spec->capsrc_nids = spec->private_adc_nids;
5326 }
5327 }
5328}
5329
67d634c0 5330#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5331#define set_beep_amp(spec, nid, idx, dir) \
5332 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25
TI
5333
5334static struct snd_pci_quirk beep_white_list[] = {
5335 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
e096c8e6 5336 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5337 {}
5338};
5339
5340static inline int has_cdefine_beep(struct hda_codec *codec)
5341{
5342 struct alc_spec *spec = codec->spec;
5343 const struct snd_pci_quirk *q;
5344 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5345 if (q)
5346 return q->value;
5347 return spec->cdefine.enable_pcbeep;
5348}
67d634c0
TI
5349#else
5350#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5351#define has_cdefine_beep(codec) 0
67d634c0 5352#endif
45bdd1c1
TI
5353
5354/*
5355 * OK, here we have finally the patch for ALC880
5356 */
5357
1da177e4
LT
5358static int patch_alc880(struct hda_codec *codec)
5359{
5360 struct alc_spec *spec;
5361 int board_config;
df694daa 5362 int err;
1da177e4 5363
e560d8d8 5364 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5365 if (spec == NULL)
5366 return -ENOMEM;
5367
5368 codec->spec = spec;
5369
f5fcc13c
TI
5370 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5371 alc880_models,
5372 alc880_cfg_tbl);
5373 if (board_config < 0) {
9a11f1aa
TI
5374 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5375 codec->chip_name);
e9edcee0 5376 board_config = ALC880_AUTO;
1da177e4 5377 }
1da177e4 5378
e9edcee0
TI
5379 if (board_config == ALC880_AUTO) {
5380 /* automatic parse from the BIOS config */
5381 err = alc880_parse_auto_config(codec);
5382 if (err < 0) {
5383 alc_free(codec);
5384 return err;
f12ab1e0 5385 } else if (!err) {
9c7f852e
TI
5386 printk(KERN_INFO
5387 "hda_codec: Cannot set up configuration "
5388 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5389 board_config = ALC880_3ST;
5390 }
1da177e4
LT
5391 }
5392
680cd536
KK
5393 err = snd_hda_attach_beep_device(codec, 0x1);
5394 if (err < 0) {
5395 alc_free(codec);
5396 return err;
5397 }
5398
df694daa 5399 if (board_config != ALC880_AUTO)
e9c364c0 5400 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5401
1da177e4
LT
5402 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5403 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5404 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5405
1da177e4
LT
5406 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5407 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5408
f12ab1e0 5409 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5410 /* check whether NID 0x07 is valid */
54d17403 5411 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5412 /* get type */
a22d543a 5413 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5414 if (wcap != AC_WID_AUD_IN) {
5415 spec->adc_nids = alc880_adc_nids_alt;
5416 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5417 } else {
5418 spec->adc_nids = alc880_adc_nids;
5419 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5420 }
5421 }
b59bdf3b 5422 set_capture_mixer(codec);
45bdd1c1 5423 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5424
2134ea4f
TI
5425 spec->vmaster_nid = 0x0c;
5426
1da177e4 5427 codec->patch_ops = alc_patch_ops;
e9edcee0 5428 if (board_config == ALC880_AUTO)
ae6b813a 5429 spec->init_hook = alc880_auto_init;
cb53c626
TI
5430#ifdef CONFIG_SND_HDA_POWER_SAVE
5431 if (!spec->loopback.amplist)
5432 spec->loopback.amplist = alc880_loopbacks;
5433#endif
1da177e4
LT
5434
5435 return 0;
5436}
5437
e9edcee0 5438
1da177e4
LT
5439/*
5440 * ALC260 support
5441 */
5442
e9edcee0
TI
5443static hda_nid_t alc260_dac_nids[1] = {
5444 /* front */
5445 0x02,
5446};
5447
5448static hda_nid_t alc260_adc_nids[1] = {
5449 /* ADC0 */
5450 0x04,
5451};
5452
df694daa 5453static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5454 /* ADC1 */
5455 0x05,
5456};
5457
d57fdac0
JW
5458/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5459 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5460 */
5461static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5462 /* ADC0, ADC1 */
5463 0x04, 0x05
5464};
5465
e9edcee0
TI
5466#define ALC260_DIGOUT_NID 0x03
5467#define ALC260_DIGIN_NID 0x06
5468
5469static struct hda_input_mux alc260_capture_source = {
5470 .num_items = 4,
5471 .items = {
5472 { "Mic", 0x0 },
5473 { "Front Mic", 0x1 },
5474 { "Line", 0x2 },
5475 { "CD", 0x4 },
5476 },
5477};
5478
17e7aec6 5479/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5480 * headphone jack and the internal CD lines since these are the only pins at
5481 * which audio can appear. For flexibility, also allow the option of
5482 * recording the mixer output on the second ADC (ADC0 doesn't have a
5483 * connection to the mixer output).
a9430dd8 5484 */
a1e8d2da
JW
5485static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5486 {
5487 .num_items = 3,
5488 .items = {
5489 { "Mic/Line", 0x0 },
5490 { "CD", 0x4 },
5491 { "Headphone", 0x2 },
5492 },
a9430dd8 5493 },
a1e8d2da
JW
5494 {
5495 .num_items = 4,
5496 .items = {
5497 { "Mic/Line", 0x0 },
5498 { "CD", 0x4 },
5499 { "Headphone", 0x2 },
5500 { "Mixer", 0x5 },
5501 },
5502 },
5503
a9430dd8
JW
5504};
5505
a1e8d2da
JW
5506/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5507 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5508 */
a1e8d2da
JW
5509static struct hda_input_mux alc260_acer_capture_sources[2] = {
5510 {
5511 .num_items = 4,
5512 .items = {
5513 { "Mic", 0x0 },
5514 { "Line", 0x2 },
5515 { "CD", 0x4 },
5516 { "Headphone", 0x5 },
5517 },
5518 },
5519 {
5520 .num_items = 5,
5521 .items = {
5522 { "Mic", 0x0 },
5523 { "Line", 0x2 },
5524 { "CD", 0x4 },
5525 { "Headphone", 0x6 },
5526 { "Mixer", 0x5 },
5527 },
0bfc90e9
JW
5528 },
5529};
cc959489
MS
5530
5531/* Maxdata Favorit 100XS */
5532static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5533 {
5534 .num_items = 2,
5535 .items = {
5536 { "Line/Mic", 0x0 },
5537 { "CD", 0x4 },
5538 },
5539 },
5540 {
5541 .num_items = 3,
5542 .items = {
5543 { "Line/Mic", 0x0 },
5544 { "CD", 0x4 },
5545 { "Mixer", 0x5 },
5546 },
5547 },
5548};
5549
1da177e4
LT
5550/*
5551 * This is just place-holder, so there's something for alc_build_pcms to look
5552 * at when it calculates the maximum number of channels. ALC260 has no mixer
5553 * element which allows changing the channel mode, so the verb list is
5554 * never used.
5555 */
d2a6d7dc 5556static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5557 { 2, NULL },
5558};
5559
df694daa
KY
5560
5561/* Mixer combinations
5562 *
5563 * basic: base_output + input + pc_beep + capture
5564 * HP: base_output + input + capture_alt
5565 * HP_3013: hp_3013 + input + capture
5566 * fujitsu: fujitsu + capture
0bfc90e9 5567 * acer: acer + capture
df694daa
KY
5568 */
5569
5570static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5571 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5572 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5573 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5574 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5575 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5576 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5577 { } /* end */
f12ab1e0 5578};
1da177e4 5579
df694daa 5580static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5581 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5582 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5583 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5584 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5585 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5586 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5587 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5588 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5589 { } /* end */
5590};
5591
bec15c3a
TI
5592/* update HP, line and mono out pins according to the master switch */
5593static void alc260_hp_master_update(struct hda_codec *codec,
5594 hda_nid_t hp, hda_nid_t line,
5595 hda_nid_t mono)
5596{
5597 struct alc_spec *spec = codec->spec;
5598 unsigned int val = spec->master_sw ? PIN_HP : 0;
5599 /* change HP and line-out pins */
30cde0aa 5600 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5601 val);
30cde0aa 5602 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5603 val);
5604 /* mono (speaker) depending on the HP jack sense */
5605 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5606 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5607 val);
5608}
5609
5610static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5611 struct snd_ctl_elem_value *ucontrol)
5612{
5613 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5614 struct alc_spec *spec = codec->spec;
5615 *ucontrol->value.integer.value = spec->master_sw;
5616 return 0;
5617}
5618
5619static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5620 struct snd_ctl_elem_value *ucontrol)
5621{
5622 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5623 struct alc_spec *spec = codec->spec;
5624 int val = !!*ucontrol->value.integer.value;
5625 hda_nid_t hp, line, mono;
5626
5627 if (val == spec->master_sw)
5628 return 0;
5629 spec->master_sw = val;
5630 hp = (kcontrol->private_value >> 16) & 0xff;
5631 line = (kcontrol->private_value >> 8) & 0xff;
5632 mono = kcontrol->private_value & 0xff;
5633 alc260_hp_master_update(codec, hp, line, mono);
5634 return 1;
5635}
5636
5637static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5638 {
5639 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5640 .name = "Master Playback Switch",
5b0cb1d8 5641 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5642 .info = snd_ctl_boolean_mono_info,
5643 .get = alc260_hp_master_sw_get,
5644 .put = alc260_hp_master_sw_put,
5645 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5646 },
5647 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5648 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5649 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5650 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5651 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5652 HDA_OUTPUT),
5653 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5654 { } /* end */
5655};
5656
5657static struct hda_verb alc260_hp_unsol_verbs[] = {
5658 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5659 {},
5660};
5661
5662static void alc260_hp_automute(struct hda_codec *codec)
5663{
5664 struct alc_spec *spec = codec->spec;
bec15c3a 5665
864f92be 5666 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5667 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5668}
5669
5670static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5671{
5672 if ((res >> 26) == ALC880_HP_EVENT)
5673 alc260_hp_automute(codec);
5674}
5675
df694daa 5676static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5677 {
5678 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5679 .name = "Master Playback Switch",
5b0cb1d8 5680 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5681 .info = snd_ctl_boolean_mono_info,
5682 .get = alc260_hp_master_sw_get,
5683 .put = alc260_hp_master_sw_put,
30cde0aa 5684 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5685 },
df694daa
KY
5686 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5687 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5688 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5689 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5690 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5691 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
5692 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5693 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
5694 { } /* end */
5695};
5696
3f878308
KY
5697static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5698 .ops = &snd_hda_bind_vol,
5699 .values = {
5700 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5701 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5702 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5703 0
5704 },
5705};
5706
5707static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5708 .ops = &snd_hda_bind_sw,
5709 .values = {
5710 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5711 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5712 0
5713 },
5714};
5715
5716static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5717 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5718 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5719 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5720 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5721 { } /* end */
5722};
5723
bec15c3a
TI
5724static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5725 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5726 {},
5727};
5728
5729static void alc260_hp_3013_automute(struct hda_codec *codec)
5730{
5731 struct alc_spec *spec = codec->spec;
bec15c3a 5732
864f92be 5733 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 5734 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
5735}
5736
5737static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5738 unsigned int res)
5739{
5740 if ((res >> 26) == ALC880_HP_EVENT)
5741 alc260_hp_3013_automute(codec);
5742}
5743
3f878308
KY
5744static void alc260_hp_3012_automute(struct hda_codec *codec)
5745{
864f92be 5746 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 5747
3f878308
KY
5748 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5749 bits);
5750 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5751 bits);
5752 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5753 bits);
5754}
5755
5756static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5757 unsigned int res)
5758{
5759 if ((res >> 26) == ALC880_HP_EVENT)
5760 alc260_hp_3012_automute(codec);
5761}
5762
5763/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
5764 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5765 */
c8b6bf9b 5766static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 5767 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5768 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 5769 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
5770 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5771 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5772 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5773 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 5774 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
5775 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5776 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
5777 { } /* end */
5778};
5779
a1e8d2da
JW
5780/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5781 * versions of the ALC260 don't act on requests to enable mic bias from NID
5782 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5783 * datasheet doesn't mention this restriction. At this stage it's not clear
5784 * whether this behaviour is intentional or is a hardware bug in chip
5785 * revisions available in early 2006. Therefore for now allow the
5786 * "Headphone Jack Mode" control to span all choices, but if it turns out
5787 * that the lack of mic bias for this NID is intentional we could change the
5788 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5789 *
5790 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5791 * don't appear to make the mic bias available from the "line" jack, even
5792 * though the NID used for this jack (0x14) can supply it. The theory is
5793 * that perhaps Acer have included blocking capacitors between the ALC260
5794 * and the output jack. If this turns out to be the case for all such
5795 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5796 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
5797 *
5798 * The C20x Tablet series have a mono internal speaker which is controlled
5799 * via the chip's Mono sum widget and pin complex, so include the necessary
5800 * controls for such models. On models without a "mono speaker" the control
5801 * won't do anything.
a1e8d2da 5802 */
0bfc90e9
JW
5803static struct snd_kcontrol_new alc260_acer_mixer[] = {
5804 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5805 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 5806 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 5807 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 5808 HDA_OUTPUT),
31bffaa9 5809 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 5810 HDA_INPUT),
0bfc90e9
JW
5811 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5812 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5813 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5814 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5815 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5816 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5817 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5818 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
5819 { } /* end */
5820};
5821
cc959489
MS
5822/* Maxdata Favorit 100XS: one output and one input (0x12) jack
5823 */
5824static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5825 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5826 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5827 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5828 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5829 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5830 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5831 { } /* end */
5832};
5833
bc9f98a9
KY
5834/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5835 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5836 */
5837static struct snd_kcontrol_new alc260_will_mixer[] = {
5838 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5839 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5840 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5841 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5842 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5843 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5844 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5845 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5846 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5847 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
5848 { } /* end */
5849};
5850
5851/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5852 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5853 */
5854static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5855 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5856 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5857 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5858 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5859 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5860 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5861 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5862 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5863 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5864 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5865 { } /* end */
5866};
5867
df694daa
KY
5868/*
5869 * initialization verbs
5870 */
1da177e4
LT
5871static struct hda_verb alc260_init_verbs[] = {
5872 /* Line In pin widget for input */
05acb863 5873 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5874 /* CD pin widget for input */
05acb863 5875 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5876 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 5877 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5878 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 5879 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5880 /* LINE-2 is used for line-out in rear */
05acb863 5881 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5882 /* select line-out */
fd56f2db 5883 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5884 /* LINE-OUT pin */
05acb863 5885 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5886 /* enable HP */
05acb863 5887 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 5888 /* enable Mono */
05acb863
TI
5889 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5890 /* mute capture amp left and right */
16ded525 5891 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
5892 /* set connection select to line in (default select for this ADC) */
5893 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
5894 /* mute capture amp left and right */
5895 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5896 /* set connection select to line in (default select for this ADC) */
5897 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
5898 /* set vol=0 Line-Out mixer amp left and right */
5899 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5900 /* unmute pin widget amp left and right (no gain on this amp) */
5901 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5902 /* set vol=0 HP mixer amp left and right */
5903 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5904 /* unmute pin widget amp left and right (no gain on this amp) */
5905 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5906 /* set vol=0 Mono mixer amp left and right */
5907 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5908 /* unmute pin widget amp left and right (no gain on this amp) */
5909 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5910 /* unmute LINE-2 out pin */
5911 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
5912 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5913 * Line In 2 = 0x03
5914 */
cb53c626
TI
5915 /* mute analog inputs */
5916 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5917 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5918 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5919 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5920 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5921 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
5922 /* mute Front out path */
5923 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5924 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5925 /* mute Headphone out path */
5926 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5927 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5928 /* mute Mono out path */
5929 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5930 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
5931 { }
5932};
5933
474167d6 5934#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
5935static struct hda_verb alc260_hp_init_verbs[] = {
5936 /* Headphone and output */
5937 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5938 /* mono output */
5939 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5940 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5941 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5942 /* Mic2 (front panel) pin widget for input and vref at 80% */
5943 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5944 /* Line In pin widget for input */
5945 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5946 /* Line-2 pin widget for output */
5947 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5948 /* CD pin widget for input */
5949 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5950 /* unmute amp left and right */
5951 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5952 /* set connection select to line in (default select for this ADC) */
5953 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5954 /* unmute Line-Out mixer amp left and right (volume = 0) */
5955 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5956 /* mute pin widget amp left and right (no gain on this amp) */
5957 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5958 /* unmute HP mixer amp left and right (volume = 0) */
5959 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5960 /* mute pin widget amp left and right (no gain on this amp) */
5961 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5962 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5963 * Line In 2 = 0x03
5964 */
cb53c626
TI
5965 /* mute analog inputs */
5966 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5967 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5968 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5969 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5970 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5971 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5972 /* Unmute Front out path */
5973 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5974 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5975 /* Unmute Headphone out path */
5976 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5977 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5978 /* Unmute Mono out path */
5979 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5980 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5981 { }
5982};
474167d6 5983#endif
df694daa
KY
5984
5985static struct hda_verb alc260_hp_3013_init_verbs[] = {
5986 /* Line out and output */
5987 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5988 /* mono output */
5989 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5990 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5991 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5992 /* Mic2 (front panel) pin widget for input and vref at 80% */
5993 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5994 /* Line In pin widget for input */
5995 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5996 /* Headphone pin widget for output */
5997 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5998 /* CD pin widget for input */
5999 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6000 /* unmute amp left and right */
6001 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6002 /* set connection select to line in (default select for this ADC) */
6003 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6004 /* unmute Line-Out mixer amp left and right (volume = 0) */
6005 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6006 /* mute pin widget amp left and right (no gain on this amp) */
6007 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6008 /* unmute HP mixer amp left and right (volume = 0) */
6009 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6010 /* mute pin widget amp left and right (no gain on this amp) */
6011 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6012 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6013 * Line In 2 = 0x03
6014 */
cb53c626
TI
6015 /* mute analog inputs */
6016 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6017 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6018 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6019 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6020 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6021 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6022 /* Unmute Front out path */
6023 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6024 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6025 /* Unmute Headphone out path */
6026 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6027 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6028 /* Unmute Mono out path */
6029 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6030 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6031 { }
6032};
6033
a9430dd8 6034/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6035 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6036 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
6037 */
6038static struct hda_verb alc260_fujitsu_init_verbs[] = {
6039 /* Disable all GPIOs */
6040 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6041 /* Internal speaker is connected to headphone pin */
6042 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6043 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6044 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6045 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6046 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6047 /* Ensure all other unused pins are disabled and muted. */
6048 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6049 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6050 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6051 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6052 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6053 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6054 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6055 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6056
6057 /* Disable digital (SPDIF) pins */
6058 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6059 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6060
ea1fb29a 6061 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6062 * when acting as an output.
6063 */
6064 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6065
f7ace40d 6066 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6067 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6068 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6069 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6070 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6071 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6072 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6073 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6074 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6075 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6076
f7ace40d
JW
6077 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6078 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6079 /* Unmute Line1 pin widget output buffer since it starts as an output.
6080 * If the pin mode is changed by the user the pin mode control will
6081 * take care of enabling the pin's input/output buffers as needed.
6082 * Therefore there's no need to enable the input buffer at this
6083 * stage.
cdcd9268 6084 */
f7ace40d 6085 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6086 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6087 * mixer ctrl)
6088 */
f7ace40d
JW
6089 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6090
6091 /* Mute capture amp left and right */
6092 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6093 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6094 * in (on mic1 pin)
6095 */
6096 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6097
6098 /* Do the same for the second ADC: mute capture input amp and
6099 * set ADC connection to line in (on mic1 pin)
6100 */
6101 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6102 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6103
6104 /* Mute all inputs to mixer widget (even unconnected ones) */
6105 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6106 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6107 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6108 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6109 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6110 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6111 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6112 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6113
6114 { }
a9430dd8
JW
6115};
6116
0bfc90e9
JW
6117/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6118 * similar laptops (adapted from Fujitsu init verbs).
6119 */
6120static struct hda_verb alc260_acer_init_verbs[] = {
6121 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6122 * the headphone jack. Turn this on and rely on the standard mute
6123 * methods whenever the user wants to turn these outputs off.
6124 */
6125 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6126 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6127 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6128 /* Internal speaker/Headphone jack is connected to Line-out pin */
6129 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6130 /* Internal microphone/Mic jack is connected to Mic1 pin */
6131 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6132 /* Line In jack is connected to Line1 pin */
6133 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6134 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6135 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6136 /* Ensure all other unused pins are disabled and muted. */
6137 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6138 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6139 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6140 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6141 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6142 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6143 /* Disable digital (SPDIF) pins */
6144 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6145 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6146
ea1fb29a 6147 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6148 * bus when acting as outputs.
6149 */
6150 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6151 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6152
6153 /* Start with output sum widgets muted and their output gains at min */
6154 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6155 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6156 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6157 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6158 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6159 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6160 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6161 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6162 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6163
f12ab1e0
TI
6164 /* Unmute Line-out pin widget amp left and right
6165 * (no equiv mixer ctrl)
6166 */
0bfc90e9 6167 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6168 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6169 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6170 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6171 * inputs. If the pin mode is changed by the user the pin mode control
6172 * will take care of enabling the pin's input/output buffers as needed.
6173 * Therefore there's no need to enable the input buffer at this
6174 * stage.
6175 */
6176 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6177 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6178
6179 /* Mute capture amp left and right */
6180 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6181 /* Set ADC connection select to match default mixer setting - mic
6182 * (on mic1 pin)
6183 */
6184 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6185
6186 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6187 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6188 */
6189 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6190 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6191
6192 /* Mute all inputs to mixer widget (even unconnected ones) */
6193 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6194 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6195 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6196 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6197 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6198 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6199 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6200 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6201
6202 { }
6203};
6204
cc959489
MS
6205/* Initialisation sequence for Maxdata Favorit 100XS
6206 * (adapted from Acer init verbs).
6207 */
6208static struct hda_verb alc260_favorit100_init_verbs[] = {
6209 /* GPIO 0 enables the output jack.
6210 * Turn this on and rely on the standard mute
6211 * methods whenever the user wants to turn these outputs off.
6212 */
6213 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6214 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6215 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6216 /* Line/Mic input jack is connected to Mic1 pin */
6217 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6218 /* Ensure all other unused pins are disabled and muted. */
6219 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6220 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6221 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6222 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6223 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6224 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6225 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6226 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6227 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6228 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6229 /* Disable digital (SPDIF) pins */
6230 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6231 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6232
6233 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6234 * bus when acting as outputs.
6235 */
6236 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6237 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6238
6239 /* Start with output sum widgets muted and their output gains at min */
6240 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6241 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6242 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6243 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6244 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6245 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6246 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6247 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6248 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6249
6250 /* Unmute Line-out pin widget amp left and right
6251 * (no equiv mixer ctrl)
6252 */
6253 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6254 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6255 * inputs. If the pin mode is changed by the user the pin mode control
6256 * will take care of enabling the pin's input/output buffers as needed.
6257 * Therefore there's no need to enable the input buffer at this
6258 * stage.
6259 */
6260 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6261
6262 /* Mute capture amp left and right */
6263 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6264 /* Set ADC connection select to match default mixer setting - mic
6265 * (on mic1 pin)
6266 */
6267 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6268
6269 /* Do similar with the second ADC: mute capture input amp and
6270 * set ADC connection to mic to match ALSA's default state.
6271 */
6272 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6273 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6274
6275 /* Mute all inputs to mixer widget (even unconnected ones) */
6276 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6277 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6278 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6279 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6280 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6281 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6282 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6283 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6284
6285 { }
6286};
6287
bc9f98a9
KY
6288static struct hda_verb alc260_will_verbs[] = {
6289 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6290 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6291 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6292 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6293 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6294 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6295 {}
6296};
6297
6298static struct hda_verb alc260_replacer_672v_verbs[] = {
6299 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6300 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6301 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6302
6303 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6304 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6305 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6306
6307 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6308 {}
6309};
6310
6311/* toggle speaker-output according to the hp-jack state */
6312static void alc260_replacer_672v_automute(struct hda_codec *codec)
6313{
6314 unsigned int present;
6315
6316 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6317 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6318 if (present) {
82beb8fd
TI
6319 snd_hda_codec_write_cache(codec, 0x01, 0,
6320 AC_VERB_SET_GPIO_DATA, 1);
6321 snd_hda_codec_write_cache(codec, 0x0f, 0,
6322 AC_VERB_SET_PIN_WIDGET_CONTROL,
6323 PIN_HP);
bc9f98a9 6324 } else {
82beb8fd
TI
6325 snd_hda_codec_write_cache(codec, 0x01, 0,
6326 AC_VERB_SET_GPIO_DATA, 0);
6327 snd_hda_codec_write_cache(codec, 0x0f, 0,
6328 AC_VERB_SET_PIN_WIDGET_CONTROL,
6329 PIN_OUT);
bc9f98a9
KY
6330 }
6331}
6332
6333static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6334 unsigned int res)
6335{
6336 if ((res >> 26) == ALC880_HP_EVENT)
6337 alc260_replacer_672v_automute(codec);
6338}
6339
3f878308
KY
6340static struct hda_verb alc260_hp_dc7600_verbs[] = {
6341 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6342 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6343 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6344 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6345 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6346 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6347 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6348 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6349 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6350 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6351 {}
6352};
6353
7cf51e48
JW
6354/* Test configuration for debugging, modelled after the ALC880 test
6355 * configuration.
6356 */
6357#ifdef CONFIG_SND_DEBUG
6358static hda_nid_t alc260_test_dac_nids[1] = {
6359 0x02,
6360};
6361static hda_nid_t alc260_test_adc_nids[2] = {
6362 0x04, 0x05,
6363};
a1e8d2da 6364/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6365 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6366 * is NID 0x04.
17e7aec6 6367 */
a1e8d2da
JW
6368static struct hda_input_mux alc260_test_capture_sources[2] = {
6369 {
6370 .num_items = 7,
6371 .items = {
6372 { "MIC1 pin", 0x0 },
6373 { "MIC2 pin", 0x1 },
6374 { "LINE1 pin", 0x2 },
6375 { "LINE2 pin", 0x3 },
6376 { "CD pin", 0x4 },
6377 { "LINE-OUT pin", 0x5 },
6378 { "HP-OUT pin", 0x6 },
6379 },
6380 },
6381 {
6382 .num_items = 8,
6383 .items = {
6384 { "MIC1 pin", 0x0 },
6385 { "MIC2 pin", 0x1 },
6386 { "LINE1 pin", 0x2 },
6387 { "LINE2 pin", 0x3 },
6388 { "CD pin", 0x4 },
6389 { "Mixer", 0x5 },
6390 { "LINE-OUT pin", 0x6 },
6391 { "HP-OUT pin", 0x7 },
6392 },
7cf51e48
JW
6393 },
6394};
6395static struct snd_kcontrol_new alc260_test_mixer[] = {
6396 /* Output driver widgets */
6397 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6398 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6399 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6400 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6401 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6402 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6403
a1e8d2da
JW
6404 /* Modes for retasking pin widgets
6405 * Note: the ALC260 doesn't seem to act on requests to enable mic
6406 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6407 * mention this restriction. At this stage it's not clear whether
6408 * this behaviour is intentional or is a hardware bug in chip
6409 * revisions available at least up until early 2006. Therefore for
6410 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6411 * choices, but if it turns out that the lack of mic bias for these
6412 * NIDs is intentional we could change their modes from
6413 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6414 */
7cf51e48
JW
6415 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6416 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6417 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6418 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6419 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6420 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6421
6422 /* Loopback mixer controls */
6423 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6424 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6425 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6426 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6427 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6428 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6429 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6430 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6431 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6432 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6433 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6434 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6435 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6436 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6437
6438 /* Controls for GPIO pins, assuming they are configured as outputs */
6439 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6440 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6441 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6442 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6443
92621f13
JW
6444 /* Switches to allow the digital IO pins to be enabled. The datasheet
6445 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6446 * make this output available should provide clarification.
92621f13
JW
6447 */
6448 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6449 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6450
f8225f6d
JW
6451 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6452 * this output to turn on an external amplifier.
6453 */
6454 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6455 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6456
7cf51e48
JW
6457 { } /* end */
6458};
6459static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6460 /* Enable all GPIOs as outputs with an initial value of 0 */
6461 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6462 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6463 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6464
7cf51e48
JW
6465 /* Enable retasking pins as output, initially without power amp */
6466 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6467 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6468 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6469 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6470 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6471 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6472
92621f13
JW
6473 /* Disable digital (SPDIF) pins initially, but users can enable
6474 * them via a mixer switch. In the case of SPDIF-out, this initverb
6475 * payload also sets the generation to 0, output to be in "consumer"
6476 * PCM format, copyright asserted, no pre-emphasis and no validity
6477 * control.
6478 */
7cf51e48
JW
6479 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6480 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6481
ea1fb29a 6482 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6483 * OUT1 sum bus when acting as an output.
6484 */
6485 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6486 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6487 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6488 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6489
6490 /* Start with output sum widgets muted and their output gains at min */
6491 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6492 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6493 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6494 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6495 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6496 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6497 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6498 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6499 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6500
cdcd9268
JW
6501 /* Unmute retasking pin widget output buffers since the default
6502 * state appears to be output. As the pin mode is changed by the
6503 * user the pin mode control will take care of enabling the pin's
6504 * input/output buffers as needed.
6505 */
7cf51e48
JW
6506 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6507 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6508 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6509 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6510 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6511 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6512 /* Also unmute the mono-out pin widget */
6513 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6514
7cf51e48
JW
6515 /* Mute capture amp left and right */
6516 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6517 /* Set ADC connection select to match default mixer setting (mic1
6518 * pin)
7cf51e48
JW
6519 */
6520 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6521
6522 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6523 * set ADC connection to mic1 pin
7cf51e48
JW
6524 */
6525 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6526 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6527
6528 /* Mute all inputs to mixer widget (even unconnected ones) */
6529 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6530 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6531 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6532 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6533 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6534 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6535 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6536 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6537
6538 { }
6539};
6540#endif
6541
6330079f
TI
6542#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6543#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6544
a3bcba38
TI
6545#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6546#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6547
df694daa
KY
6548/*
6549 * for BIOS auto-configuration
6550 */
16ded525 6551
df694daa 6552static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6553 const char *pfx, int *vol_bits)
df694daa
KY
6554{
6555 hda_nid_t nid_vol;
6556 unsigned long vol_val, sw_val;
df694daa
KY
6557 int err;
6558
6559 if (nid >= 0x0f && nid < 0x11) {
6560 nid_vol = nid - 0x7;
6561 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6562 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6563 } else if (nid == 0x11) {
6564 nid_vol = nid - 0x7;
6565 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6566 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6567 } else if (nid >= 0x12 && nid <= 0x15) {
6568 nid_vol = 0x08;
6569 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6570 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6571 } else
6572 return 0; /* N/A */
ea1fb29a 6573
863b4518
TI
6574 if (!(*vol_bits & (1 << nid_vol))) {
6575 /* first control for the volume widget */
0afe5f89 6576 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6577 if (err < 0)
6578 return err;
6579 *vol_bits |= (1 << nid_vol);
6580 }
0afe5f89 6581 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6582 if (err < 0)
df694daa
KY
6583 return err;
6584 return 1;
6585}
6586
6587/* add playback controls from the parsed DAC table */
6588static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6589 const struct auto_pin_cfg *cfg)
6590{
6591 hda_nid_t nid;
6592 int err;
863b4518 6593 int vols = 0;
df694daa
KY
6594
6595 spec->multiout.num_dacs = 1;
6596 spec->multiout.dac_nids = spec->private_dac_nids;
6597 spec->multiout.dac_nids[0] = 0x02;
6598
6599 nid = cfg->line_out_pins[0];
6600 if (nid) {
23112d6d
TI
6601 const char *pfx;
6602 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6603 pfx = "Master";
6604 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6605 pfx = "Speaker";
6606 else
6607 pfx = "Front";
6608 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6609 if (err < 0)
6610 return err;
6611 }
6612
82bc955f 6613 nid = cfg->speaker_pins[0];
df694daa 6614 if (nid) {
863b4518 6615 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6616 if (err < 0)
6617 return err;
6618 }
6619
eb06ed8f 6620 nid = cfg->hp_pins[0];
df694daa 6621 if (nid) {
863b4518
TI
6622 err = alc260_add_playback_controls(spec, nid, "Headphone",
6623 &vols);
df694daa
KY
6624 if (err < 0)
6625 return err;
6626 }
f12ab1e0 6627 return 0;
df694daa
KY
6628}
6629
6630/* create playback/capture controls for input pins */
05f5f477 6631static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6632 const struct auto_pin_cfg *cfg)
6633{
05f5f477 6634 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6635}
6636
6637static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6638 hda_nid_t nid, int pin_type,
6639 int sel_idx)
6640{
f6c7e546 6641 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6642 /* need the manual connection? */
6643 if (nid >= 0x12) {
6644 int idx = nid - 0x12;
6645 snd_hda_codec_write(codec, idx + 0x0b, 0,
6646 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6647 }
6648}
6649
6650static void alc260_auto_init_multi_out(struct hda_codec *codec)
6651{
6652 struct alc_spec *spec = codec->spec;
6653 hda_nid_t nid;
6654
f12ab1e0 6655 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6656 if (nid) {
6657 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6658 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6659 }
ea1fb29a 6660
82bc955f 6661 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6662 if (nid)
6663 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6664
eb06ed8f 6665 nid = spec->autocfg.hp_pins[0];
df694daa 6666 if (nid)
baba8ee9 6667 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6668}
df694daa
KY
6669
6670#define ALC260_PIN_CD_NID 0x16
6671static void alc260_auto_init_analog_input(struct hda_codec *codec)
6672{
6673 struct alc_spec *spec = codec->spec;
6674 int i;
6675
6676 for (i = 0; i < AUTO_PIN_LAST; i++) {
6677 hda_nid_t nid = spec->autocfg.input_pins[i];
6678 if (nid >= 0x12) {
23f0c048 6679 alc_set_input_pin(codec, nid, i);
e82c025b
TI
6680 if (nid != ALC260_PIN_CD_NID &&
6681 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6682 snd_hda_codec_write(codec, nid, 0,
6683 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6684 AMP_OUT_MUTE);
6685 }
6686 }
6687}
6688
7f311a46
TI
6689#define alc260_auto_init_input_src alc880_auto_init_input_src
6690
df694daa
KY
6691/*
6692 * generic initialization of ADC, input mixers and output mixers
6693 */
6694static struct hda_verb alc260_volume_init_verbs[] = {
6695 /*
6696 * Unmute ADC0-1 and set the default input to mic-in
6697 */
6698 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6699 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6700 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6701 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 6702
df694daa
KY
6703 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6704 * mixer widget
f12ab1e0
TI
6705 * Note: PASD motherboards uses the Line In 2 as the input for
6706 * front panel mic (mic 2)
df694daa
KY
6707 */
6708 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6709 /* mute analog inputs */
6710 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6711 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6712 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6713 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6714 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6715
6716 /*
6717 * Set up output mixers (0x08 - 0x0a)
6718 */
6719 /* set vol=0 to output mixers */
6720 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6721 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6722 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6723 /* set up input amps for analog loopback */
6724 /* Amp Indices: DAC = 0, mixer = 1 */
6725 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6726 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6727 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6728 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6729 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6730 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 6731
df694daa
KY
6732 { }
6733};
6734
6735static int alc260_parse_auto_config(struct hda_codec *codec)
6736{
6737 struct alc_spec *spec = codec->spec;
df694daa
KY
6738 int err;
6739 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6740
f12ab1e0
TI
6741 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6742 alc260_ignore);
6743 if (err < 0)
df694daa 6744 return err;
f12ab1e0
TI
6745 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6746 if (err < 0)
4a471b7d 6747 return err;
603c4019 6748 if (!spec->kctls.list)
df694daa 6749 return 0; /* can't find valid BIOS pin config */
05f5f477 6750 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 6751 if (err < 0)
df694daa
KY
6752 return err;
6753
6754 spec->multiout.max_channels = 2;
6755
0852d7a6 6756 if (spec->autocfg.dig_outs)
df694daa 6757 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 6758 if (spec->kctls.list)
d88897ea 6759 add_mixer(spec, spec->kctls.list);
df694daa 6760
d88897ea 6761 add_verb(spec, alc260_volume_init_verbs);
df694daa 6762
a1e8d2da 6763 spec->num_mux_defs = 1;
61b9b9b1 6764 spec->input_mux = &spec->private_imux[0];
df694daa 6765
6227cdce 6766 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 6767
df694daa
KY
6768 return 1;
6769}
6770
ae6b813a
TI
6771/* additional initialization for auto-configuration model */
6772static void alc260_auto_init(struct hda_codec *codec)
df694daa 6773{
f6c7e546 6774 struct alc_spec *spec = codec->spec;
df694daa
KY
6775 alc260_auto_init_multi_out(codec);
6776 alc260_auto_init_analog_input(codec);
7f311a46 6777 alc260_auto_init_input_src(codec);
757899ac 6778 alc_auto_init_digital(codec);
f6c7e546 6779 if (spec->unsol_event)
7fb0d78f 6780 alc_inithook(codec);
df694daa
KY
6781}
6782
cb53c626
TI
6783#ifdef CONFIG_SND_HDA_POWER_SAVE
6784static struct hda_amp_list alc260_loopbacks[] = {
6785 { 0x07, HDA_INPUT, 0 },
6786 { 0x07, HDA_INPUT, 1 },
6787 { 0x07, HDA_INPUT, 2 },
6788 { 0x07, HDA_INPUT, 3 },
6789 { 0x07, HDA_INPUT, 4 },
6790 { } /* end */
6791};
6792#endif
6793
df694daa
KY
6794/*
6795 * ALC260 configurations
6796 */
f5fcc13c
TI
6797static const char *alc260_models[ALC260_MODEL_LAST] = {
6798 [ALC260_BASIC] = "basic",
6799 [ALC260_HP] = "hp",
6800 [ALC260_HP_3013] = "hp-3013",
2922c9af 6801 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
6802 [ALC260_FUJITSU_S702X] = "fujitsu",
6803 [ALC260_ACER] = "acer",
bc9f98a9
KY
6804 [ALC260_WILL] = "will",
6805 [ALC260_REPLACER_672V] = "replacer",
cc959489 6806 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 6807#ifdef CONFIG_SND_DEBUG
f5fcc13c 6808 [ALC260_TEST] = "test",
7cf51e48 6809#endif
f5fcc13c
TI
6810 [ALC260_AUTO] = "auto",
6811};
6812
6813static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 6814 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 6815 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 6816 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 6817 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 6818 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 6819 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 6820 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 6821 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 6822 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
6823 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6824 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6825 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6826 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6827 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6828 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6829 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6830 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6831 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 6832 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 6833 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
6834 {}
6835};
6836
6837static struct alc_config_preset alc260_presets[] = {
6838 [ALC260_BASIC] = {
6839 .mixers = { alc260_base_output_mixer,
45bdd1c1 6840 alc260_input_mixer },
df694daa
KY
6841 .init_verbs = { alc260_init_verbs },
6842 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6843 .dac_nids = alc260_dac_nids,
f9e336f6 6844 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 6845 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
6846 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6847 .channel_mode = alc260_modes,
6848 .input_mux = &alc260_capture_source,
6849 },
6850 [ALC260_HP] = {
bec15c3a 6851 .mixers = { alc260_hp_output_mixer,
f9e336f6 6852 alc260_input_mixer },
bec15c3a
TI
6853 .init_verbs = { alc260_init_verbs,
6854 alc260_hp_unsol_verbs },
df694daa
KY
6855 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6856 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6857 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6858 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6859 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6860 .channel_mode = alc260_modes,
6861 .input_mux = &alc260_capture_source,
bec15c3a
TI
6862 .unsol_event = alc260_hp_unsol_event,
6863 .init_hook = alc260_hp_automute,
df694daa 6864 },
3f878308
KY
6865 [ALC260_HP_DC7600] = {
6866 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 6867 alc260_input_mixer },
3f878308
KY
6868 .init_verbs = { alc260_init_verbs,
6869 alc260_hp_dc7600_verbs },
6870 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6871 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6872 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6873 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
6874 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6875 .channel_mode = alc260_modes,
6876 .input_mux = &alc260_capture_source,
6877 .unsol_event = alc260_hp_3012_unsol_event,
6878 .init_hook = alc260_hp_3012_automute,
6879 },
df694daa
KY
6880 [ALC260_HP_3013] = {
6881 .mixers = { alc260_hp_3013_mixer,
f9e336f6 6882 alc260_input_mixer },
bec15c3a
TI
6883 .init_verbs = { alc260_hp_3013_init_verbs,
6884 alc260_hp_3013_unsol_verbs },
df694daa
KY
6885 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6886 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6887 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6888 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6889 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6890 .channel_mode = alc260_modes,
6891 .input_mux = &alc260_capture_source,
bec15c3a
TI
6892 .unsol_event = alc260_hp_3013_unsol_event,
6893 .init_hook = alc260_hp_3013_automute,
df694daa
KY
6894 },
6895 [ALC260_FUJITSU_S702X] = {
f9e336f6 6896 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
6897 .init_verbs = { alc260_fujitsu_init_verbs },
6898 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6899 .dac_nids = alc260_dac_nids,
d57fdac0
JW
6900 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6901 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
6902 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6903 .channel_mode = alc260_modes,
a1e8d2da
JW
6904 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6905 .input_mux = alc260_fujitsu_capture_sources,
df694daa 6906 },
0bfc90e9 6907 [ALC260_ACER] = {
f9e336f6 6908 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
6909 .init_verbs = { alc260_acer_init_verbs },
6910 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6911 .dac_nids = alc260_dac_nids,
6912 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6913 .adc_nids = alc260_dual_adc_nids,
6914 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6915 .channel_mode = alc260_modes,
a1e8d2da
JW
6916 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6917 .input_mux = alc260_acer_capture_sources,
0bfc90e9 6918 },
cc959489
MS
6919 [ALC260_FAVORIT100] = {
6920 .mixers = { alc260_favorit100_mixer },
6921 .init_verbs = { alc260_favorit100_init_verbs },
6922 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6923 .dac_nids = alc260_dac_nids,
6924 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6925 .adc_nids = alc260_dual_adc_nids,
6926 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6927 .channel_mode = alc260_modes,
6928 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6929 .input_mux = alc260_favorit100_capture_sources,
6930 },
bc9f98a9 6931 [ALC260_WILL] = {
f9e336f6 6932 .mixers = { alc260_will_mixer },
bc9f98a9
KY
6933 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6934 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6935 .dac_nids = alc260_dac_nids,
6936 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6937 .adc_nids = alc260_adc_nids,
6938 .dig_out_nid = ALC260_DIGOUT_NID,
6939 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6940 .channel_mode = alc260_modes,
6941 .input_mux = &alc260_capture_source,
6942 },
6943 [ALC260_REPLACER_672V] = {
f9e336f6 6944 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
6945 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6946 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6947 .dac_nids = alc260_dac_nids,
6948 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6949 .adc_nids = alc260_adc_nids,
6950 .dig_out_nid = ALC260_DIGOUT_NID,
6951 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6952 .channel_mode = alc260_modes,
6953 .input_mux = &alc260_capture_source,
6954 .unsol_event = alc260_replacer_672v_unsol_event,
6955 .init_hook = alc260_replacer_672v_automute,
6956 },
7cf51e48
JW
6957#ifdef CONFIG_SND_DEBUG
6958 [ALC260_TEST] = {
f9e336f6 6959 .mixers = { alc260_test_mixer },
7cf51e48
JW
6960 .init_verbs = { alc260_test_init_verbs },
6961 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6962 .dac_nids = alc260_test_dac_nids,
6963 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6964 .adc_nids = alc260_test_adc_nids,
6965 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6966 .channel_mode = alc260_modes,
a1e8d2da
JW
6967 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6968 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
6969 },
6970#endif
df694daa
KY
6971};
6972
6973static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
6974{
6975 struct alc_spec *spec;
df694daa 6976 int err, board_config;
1da177e4 6977
e560d8d8 6978 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
6979 if (spec == NULL)
6980 return -ENOMEM;
6981
6982 codec->spec = spec;
6983
f5fcc13c
TI
6984 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6985 alc260_models,
6986 alc260_cfg_tbl);
6987 if (board_config < 0) {
9a11f1aa 6988 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 6989 codec->chip_name);
df694daa 6990 board_config = ALC260_AUTO;
16ded525 6991 }
1da177e4 6992
df694daa
KY
6993 if (board_config == ALC260_AUTO) {
6994 /* automatic parse from the BIOS config */
6995 err = alc260_parse_auto_config(codec);
6996 if (err < 0) {
6997 alc_free(codec);
6998 return err;
f12ab1e0 6999 } else if (!err) {
9c7f852e
TI
7000 printk(KERN_INFO
7001 "hda_codec: Cannot set up configuration "
7002 "from BIOS. Using base mode...\n");
df694daa
KY
7003 board_config = ALC260_BASIC;
7004 }
a9430dd8 7005 }
e9edcee0 7006
680cd536
KK
7007 err = snd_hda_attach_beep_device(codec, 0x1);
7008 if (err < 0) {
7009 alc_free(codec);
7010 return err;
7011 }
7012
df694daa 7013 if (board_config != ALC260_AUTO)
e9c364c0 7014 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7015
1da177e4
LT
7016 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7017 spec->stream_analog_capture = &alc260_pcm_analog_capture;
7018
a3bcba38
TI
7019 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7020 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7021
4ef0ef19
TI
7022 if (!spec->adc_nids && spec->input_mux) {
7023 /* check whether NID 0x04 is valid */
7024 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7025 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7026 /* get type */
7027 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7028 spec->adc_nids = alc260_adc_nids_alt;
7029 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7030 } else {
7031 spec->adc_nids = alc260_adc_nids;
7032 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7033 }
7034 }
b59bdf3b 7035 set_capture_mixer(codec);
45bdd1c1 7036 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7037
2134ea4f
TI
7038 spec->vmaster_nid = 0x08;
7039
1da177e4 7040 codec->patch_ops = alc_patch_ops;
df694daa 7041 if (board_config == ALC260_AUTO)
ae6b813a 7042 spec->init_hook = alc260_auto_init;
cb53c626
TI
7043#ifdef CONFIG_SND_HDA_POWER_SAVE
7044 if (!spec->loopback.amplist)
7045 spec->loopback.amplist = alc260_loopbacks;
7046#endif
1da177e4
LT
7047
7048 return 0;
7049}
7050
e9edcee0 7051
1da177e4 7052/*
4953550a 7053 * ALC882/883/885/888/889 support
1da177e4
LT
7054 *
7055 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7056 * configuration. Each pin widget can choose any input DACs and a mixer.
7057 * Each ADC is connected from a mixer of all inputs. This makes possible
7058 * 6-channel independent captures.
7059 *
7060 * In addition, an independent DAC for the multi-playback (not used in this
7061 * driver yet).
7062 */
df694daa
KY
7063#define ALC882_DIGOUT_NID 0x06
7064#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7065#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7066#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7067#define ALC1200_DIGOUT_NID 0x10
7068
1da177e4 7069
d2a6d7dc 7070static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7071 { 8, NULL }
7072};
7073
4953550a 7074/* DACs */
1da177e4
LT
7075static hda_nid_t alc882_dac_nids[4] = {
7076 /* front, rear, clfe, rear_surr */
7077 0x02, 0x03, 0x04, 0x05
7078};
4953550a 7079#define alc883_dac_nids alc882_dac_nids
1da177e4 7080
4953550a 7081/* ADCs */
df694daa
KY
7082#define alc882_adc_nids alc880_adc_nids
7083#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
7084#define alc883_adc_nids alc882_adc_nids_alt
7085static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7086static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7087#define alc889_adc_nids alc880_adc_nids
1da177e4 7088
e1406348
TI
7089static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7090static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
7091#define alc883_capsrc_nids alc882_capsrc_nids_alt
7092static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7093#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7094
1da177e4
LT
7095/* input MUX */
7096/* FIXME: should be a matrix-type input source selection */
7097
7098static struct hda_input_mux alc882_capture_source = {
7099 .num_items = 4,
7100 .items = {
7101 { "Mic", 0x0 },
7102 { "Front Mic", 0x1 },
7103 { "Line", 0x2 },
7104 { "CD", 0x4 },
7105 },
7106};
41d5545d 7107
4953550a
TI
7108#define alc883_capture_source alc882_capture_source
7109
87a8c370
JK
7110static struct hda_input_mux alc889_capture_source = {
7111 .num_items = 3,
7112 .items = {
7113 { "Front Mic", 0x0 },
7114 { "Mic", 0x3 },
7115 { "Line", 0x2 },
7116 },
7117};
7118
41d5545d
KS
7119static struct hda_input_mux mb5_capture_source = {
7120 .num_items = 3,
7121 .items = {
7122 { "Mic", 0x1 },
b8f171e7 7123 { "Line", 0x7 },
41d5545d
KS
7124 { "CD", 0x4 },
7125 },
7126};
7127
e458b1fa
LY
7128static struct hda_input_mux macmini3_capture_source = {
7129 .num_items = 2,
7130 .items = {
7131 { "Line", 0x2 },
7132 { "CD", 0x4 },
7133 },
7134};
7135
4953550a
TI
7136static struct hda_input_mux alc883_3stack_6ch_intel = {
7137 .num_items = 4,
7138 .items = {
7139 { "Mic", 0x1 },
7140 { "Front Mic", 0x0 },
7141 { "Line", 0x2 },
7142 { "CD", 0x4 },
7143 },
7144};
7145
7146static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7147 .num_items = 2,
7148 .items = {
7149 { "Mic", 0x1 },
7150 { "Line", 0x2 },
7151 },
7152};
7153
7154static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7155 .num_items = 4,
7156 .items = {
7157 { "Mic", 0x0 },
150b432f 7158 { "Int Mic", 0x1 },
4953550a
TI
7159 { "Line", 0x2 },
7160 { "CD", 0x4 },
7161 },
7162};
7163
7164static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7165 .num_items = 2,
7166 .items = {
7167 { "Mic", 0x0 },
7168 { "Int Mic", 0x1 },
7169 },
7170};
7171
7172static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7173 .num_items = 3,
7174 .items = {
7175 { "Mic", 0x0 },
7176 { "Front Mic", 0x1 },
7177 { "Line", 0x4 },
7178 },
7179};
7180
7181static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7182 .num_items = 2,
7183 .items = {
7184 { "Mic", 0x0 },
7185 { "Line", 0x2 },
7186 },
7187};
7188
7189static struct hda_input_mux alc889A_mb31_capture_source = {
7190 .num_items = 2,
7191 .items = {
7192 { "Mic", 0x0 },
7193 /* Front Mic (0x01) unused */
7194 { "Line", 0x2 },
7195 /* Line 2 (0x03) unused */
af901ca1 7196 /* CD (0x04) unused? */
4953550a
TI
7197 },
7198};
7199
b7cccc52
JM
7200static struct hda_input_mux alc889A_imac91_capture_source = {
7201 .num_items = 2,
7202 .items = {
7203 { "Mic", 0x01 },
7204 { "Line", 0x2 }, /* Not sure! */
7205 },
7206};
7207
4953550a
TI
7208/*
7209 * 2ch mode
7210 */
7211static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7212 { 2, NULL }
7213};
7214
272a527c
KY
7215/*
7216 * 2ch mode
7217 */
7218static struct hda_verb alc882_3ST_ch2_init[] = {
7219 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7220 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7221 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7222 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7223 { } /* end */
7224};
7225
4953550a
TI
7226/*
7227 * 4ch mode
7228 */
7229static struct hda_verb alc882_3ST_ch4_init[] = {
7230 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7231 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7232 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7233 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7234 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7235 { } /* end */
7236};
7237
272a527c
KY
7238/*
7239 * 6ch mode
7240 */
7241static struct hda_verb alc882_3ST_ch6_init[] = {
7242 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7243 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7244 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7245 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7246 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7247 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7248 { } /* end */
7249};
7250
4953550a 7251static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7252 { 2, alc882_3ST_ch2_init },
4953550a 7253 { 4, alc882_3ST_ch4_init },
272a527c
KY
7254 { 6, alc882_3ST_ch6_init },
7255};
7256
4953550a
TI
7257#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7258
a65cc60f 7259/*
7260 * 2ch mode
7261 */
7262static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7263 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7264 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7265 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7266 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7267 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7268 { } /* end */
7269};
7270
7271/*
7272 * 4ch mode
7273 */
7274static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7275 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7276 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7277 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7278 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7279 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7280 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7281 { } /* end */
7282};
7283
7284/*
7285 * 6ch mode
7286 */
7287static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7288 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7289 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7290 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7291 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7292 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7293 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7294 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7295 { } /* end */
7296};
7297
7298static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7299 { 2, alc883_3ST_ch2_clevo_init },
7300 { 4, alc883_3ST_ch4_clevo_init },
7301 { 6, alc883_3ST_ch6_clevo_init },
7302};
7303
7304
df694daa
KY
7305/*
7306 * 6ch mode
7307 */
7308static struct hda_verb alc882_sixstack_ch6_init[] = {
7309 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7310 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7311 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7312 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7313 { } /* end */
7314};
7315
7316/*
7317 * 8ch mode
7318 */
7319static struct hda_verb alc882_sixstack_ch8_init[] = {
7320 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7321 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7322 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7323 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7324 { } /* end */
7325};
7326
7327static struct hda_channel_mode alc882_sixstack_modes[2] = {
7328 { 6, alc882_sixstack_ch6_init },
7329 { 8, alc882_sixstack_ch8_init },
7330};
7331
76e6f5a9
RH
7332
7333/* Macbook Air 2,1 */
7334
7335static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7336 { 2, NULL },
7337};
7338
87350ad0 7339/*
def319f9 7340 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7341 */
7342
7343/*
7344 * 2ch mode
7345 */
7346static struct hda_verb alc885_mbp_ch2_init[] = {
7347 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7348 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7349 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7350 { } /* end */
7351};
7352
7353/*
a3f730af 7354 * 4ch mode
87350ad0 7355 */
a3f730af 7356static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7357 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7358 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7359 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7360 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7361 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7362 { } /* end */
7363};
7364
a3f730af 7365static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7366 { 2, alc885_mbp_ch2_init },
a3f730af 7367 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7368};
7369
92b9de83
KS
7370/*
7371 * 2ch
7372 * Speakers/Woofer/HP = Front
7373 * LineIn = Input
7374 */
7375static struct hda_verb alc885_mb5_ch2_init[] = {
7376 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7377 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7378 { } /* end */
7379};
7380
7381/*
7382 * 6ch mode
7383 * Speakers/HP = Front
7384 * Woofer = LFE
7385 * LineIn = Surround
7386 */
7387static struct hda_verb alc885_mb5_ch6_init[] = {
7388 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7389 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7390 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7391 { } /* end */
7392};
7393
7394static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7395 { 2, alc885_mb5_ch2_init },
7396 { 6, alc885_mb5_ch6_init },
7397};
87350ad0 7398
d01aecdf 7399#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7400
7401/*
7402 * 2ch mode
7403 */
7404static struct hda_verb alc883_4ST_ch2_init[] = {
7405 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7406 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7407 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7408 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7409 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7410 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7411 { } /* end */
7412};
7413
7414/*
7415 * 4ch mode
7416 */
7417static struct hda_verb alc883_4ST_ch4_init[] = {
7418 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7419 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7420 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7421 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7422 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7423 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7424 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7425 { } /* end */
7426};
7427
7428/*
7429 * 6ch mode
7430 */
7431static struct hda_verb alc883_4ST_ch6_init[] = {
7432 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7433 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7434 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7435 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7436 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7437 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7438 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7439 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7440 { } /* end */
7441};
7442
7443/*
7444 * 8ch mode
7445 */
7446static struct hda_verb alc883_4ST_ch8_init[] = {
7447 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7448 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7449 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7450 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7451 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7452 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7453 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7454 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7455 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7456 { } /* end */
7457};
7458
7459static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7460 { 2, alc883_4ST_ch2_init },
7461 { 4, alc883_4ST_ch4_init },
7462 { 6, alc883_4ST_ch6_init },
7463 { 8, alc883_4ST_ch8_init },
7464};
7465
7466
7467/*
7468 * 2ch mode
7469 */
7470static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7471 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7472 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7473 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7474 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7475 { } /* end */
7476};
7477
7478/*
7479 * 4ch mode
7480 */
7481static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7482 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7483 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7484 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7485 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7486 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7487 { } /* end */
7488};
7489
7490/*
7491 * 6ch mode
7492 */
7493static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7494 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7495 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7496 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7497 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7498 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7499 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7500 { } /* end */
7501};
7502
7503static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7504 { 2, alc883_3ST_ch2_intel_init },
7505 { 4, alc883_3ST_ch4_intel_init },
7506 { 6, alc883_3ST_ch6_intel_init },
7507};
7508
dd7714c9
WF
7509/*
7510 * 2ch mode
7511 */
7512static struct hda_verb alc889_ch2_intel_init[] = {
7513 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7514 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7515 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7516 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7517 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7518 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7519 { } /* end */
7520};
7521
87a8c370
JK
7522/*
7523 * 6ch mode
7524 */
7525static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7526 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7527 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7528 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7529 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7530 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7531 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7532 { } /* end */
7533};
7534
7535/*
7536 * 8ch mode
7537 */
7538static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7539 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7540 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7541 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7542 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7543 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7544 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7545 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7546 { } /* end */
7547};
7548
dd7714c9
WF
7549static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7550 { 2, alc889_ch2_intel_init },
87a8c370
JK
7551 { 6, alc889_ch6_intel_init },
7552 { 8, alc889_ch8_intel_init },
7553};
7554
4953550a
TI
7555/*
7556 * 6ch mode
7557 */
7558static struct hda_verb alc883_sixstack_ch6_init[] = {
7559 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7560 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7561 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7562 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7563 { } /* end */
7564};
7565
7566/*
7567 * 8ch mode
7568 */
7569static struct hda_verb alc883_sixstack_ch8_init[] = {
7570 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7571 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7572 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7573 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7574 { } /* end */
7575};
7576
7577static struct hda_channel_mode alc883_sixstack_modes[2] = {
7578 { 6, alc883_sixstack_ch6_init },
7579 { 8, alc883_sixstack_ch8_init },
7580};
7581
7582
1da177e4
LT
7583/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7584 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7585 */
c8b6bf9b 7586static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7587 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7588 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7589 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7590 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7591 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7592 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7593 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7594 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7595 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7596 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7597 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7598 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7599 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7600 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7601 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7602 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7603 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
7604 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7605 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7606 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4 7607 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7608 { } /* end */
7609};
7610
76e6f5a9
RH
7611/* Macbook Air 2,1 same control for HP and internal Speaker */
7612
7613static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7614 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7615 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7616 { }
7617};
7618
7619
87350ad0 7620static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7621 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7622 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7623 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7624 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7625 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7626 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7627 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7628 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7629 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 7630 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
7631 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7632 { } /* end */
7633};
41d5545d
KS
7634
7635static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
7636 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7637 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7638 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7639 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7640 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7641 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
7642 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7643 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
7644 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7645 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
7646 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7647 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7648 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7649 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7650 { } /* end */
7651};
92b9de83 7652
e458b1fa
LY
7653static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7654 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7655 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7656 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7657 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7658 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7659 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7660 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7661 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7662 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7663 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7664 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7665 { } /* end */
7666};
7667
4b7e1803 7668static struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
7669 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7670 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
7671 { } /* end */
7672};
7673
7674
bdd148a3
KY
7675static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7676 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7677 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7678 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7679 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7680 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7681 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7682 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7683 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7684 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
7685 { } /* end */
7686};
7687
272a527c
KY
7688static struct snd_kcontrol_new alc882_targa_mixer[] = {
7689 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7690 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7691 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7692 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7693 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7694 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7695 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7696 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7697 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7698 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7699 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7700 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 7701 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
7702 { } /* end */
7703};
7704
7705/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7706 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7707 */
7708static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7709 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7710 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7711 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7712 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7713 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7714 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7715 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7716 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7717 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7718 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7719 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7720 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7721 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7722 { } /* end */
7723};
7724
914759b7
TI
7725static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7726 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7727 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7728 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7729 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7730 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7731 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7732 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7733 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7734 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7735 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
7736 { } /* end */
7737};
7738
df694daa
KY
7739static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7740 {
7741 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7742 .name = "Channel Mode",
7743 .info = alc_ch_mode_info,
7744 .get = alc_ch_mode_get,
7745 .put = alc_ch_mode_put,
7746 },
7747 { } /* end */
7748};
7749
4953550a 7750static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 7751 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
7752 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7753 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7754 /* Rear mixer */
05acb863
TI
7755 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7756 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7757 /* CLFE mixer */
05acb863
TI
7758 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7759 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7760 /* Side mixer */
05acb863
TI
7761 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7762 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7763
e9edcee0 7764 /* Front Pin: output 0 (0x0c) */
05acb863 7765 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7766 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7767 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 7768 /* Rear Pin: output 1 (0x0d) */
05acb863 7769 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7770 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7771 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 7772 /* CLFE Pin: output 2 (0x0e) */
05acb863 7773 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7774 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7775 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 7776 /* Side Pin: output 3 (0x0f) */
05acb863 7777 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7778 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7779 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 7780 /* Mic (rear) pin: input vref at 80% */
16ded525 7781 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7782 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7783 /* Front Mic pin: input vref at 80% */
16ded525 7784 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7785 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7786 /* Line In pin: input */
05acb863 7787 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
7788 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7789 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7790 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7791 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7792 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 7793 /* CD pin widget for input */
05acb863 7794 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
7795
7796 /* FIXME: use matrix-type input source selection */
7797 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 7798 /* Input mixer2 */
05acb863 7799 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 7800 /* Input mixer3 */
05acb863 7801 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
7802 /* ADC2: mute amp left and right */
7803 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7804 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
7805 /* ADC3: mute amp left and right */
7806 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7807 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
7808
7809 { }
7810};
7811
4953550a
TI
7812static struct hda_verb alc882_adc1_init_verbs[] = {
7813 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7814 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7815 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7816 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7817 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7818 /* ADC1: mute amp left and right */
7819 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7820 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7821 { }
7822};
7823
4b146cb0
TI
7824static struct hda_verb alc882_eapd_verbs[] = {
7825 /* change to EAPD mode */
7826 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 7827 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 7828 { }
4b146cb0
TI
7829};
7830
87a8c370
JK
7831static struct hda_verb alc889_eapd_verbs[] = {
7832 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7833 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7834 { }
7835};
7836
6732bd0d
WF
7837static struct hda_verb alc_hp15_unsol_verbs[] = {
7838 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7839 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7840 {}
7841};
87a8c370
JK
7842
7843static struct hda_verb alc885_init_verbs[] = {
7844 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
7845 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7846 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7847 /* Rear mixer */
88102f3f
KY
7848 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7849 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7850 /* CLFE mixer */
88102f3f
KY
7851 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7852 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7853 /* Side mixer */
88102f3f
KY
7854 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7855 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
7856
7857 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 7858 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
7859 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7860 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7861 /* Front Pin: output 0 (0x0c) */
7862 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7863 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7864 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7865 /* Rear Pin: output 1 (0x0d) */
7866 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7867 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7868 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
7869 /* CLFE Pin: output 2 (0x0e) */
7870 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7871 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7872 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7873 /* Side Pin: output 3 (0x0f) */
7874 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7875 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7876 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7877 /* Mic (rear) pin: input vref at 80% */
7878 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7879 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7880 /* Front Mic pin: input vref at 80% */
7881 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7882 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7883 /* Line In pin: input */
7884 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7885 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7886
7887 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7888 /* Input mixer1 */
88102f3f 7889 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
7890 /* Input mixer2 */
7891 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 7892 /* Input mixer3 */
88102f3f 7893 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
7894 /* ADC2: mute amp left and right */
7895 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7896 /* ADC3: mute amp left and right */
7897 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7898
7899 { }
7900};
7901
7902static struct hda_verb alc885_init_input_verbs[] = {
7903 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7904 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7905 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7906 { }
7907};
7908
7909
7910/* Unmute Selector 24h and set the default input to front mic */
7911static struct hda_verb alc889_init_input_verbs[] = {
7912 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7913 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7914 { }
7915};
7916
7917
4953550a
TI
7918#define alc883_init_verbs alc882_base_init_verbs
7919
9102cd1c
TD
7920/* Mac Pro test */
7921static struct snd_kcontrol_new alc882_macpro_mixer[] = {
7922 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7923 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7924 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
7925 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7926 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 7927 /* FIXME: this looks suspicious...
d355c82a
JK
7928 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
7929 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 7930 */
9102cd1c
TD
7931 { } /* end */
7932};
7933
7934static struct hda_verb alc882_macpro_init_verbs[] = {
7935 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7936 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7937 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7938 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7939 /* Front Pin: output 0 (0x0c) */
7940 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7941 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7942 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7943 /* Front Mic pin: input vref at 80% */
7944 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7945 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7946 /* Speaker: output */
7947 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7948 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7949 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
7950 /* Headphone output (output 0 - 0x0c) */
7951 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7952 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7953 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7954
7955 /* FIXME: use matrix-type input source selection */
7956 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7957 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7958 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7959 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7960 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7961 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7962 /* Input mixer2 */
7963 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7964 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7965 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7966 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7967 /* Input mixer3 */
7968 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7969 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7970 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7971 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7972 /* ADC1: mute amp left and right */
7973 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7974 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7975 /* ADC2: mute amp left and right */
7976 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7977 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7978 /* ADC3: mute amp left and right */
7979 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7980 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7981
7982 { }
7983};
f12ab1e0 7984
41d5545d
KS
7985/* Macbook 5,1 */
7986static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
7987 /* DACs */
7988 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7989 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7990 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7991 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 7992 /* Front mixer */
41d5545d
KS
7993 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7994 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7995 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
7996 /* Surround mixer */
7997 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7998 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7999 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8000 /* LFE mixer */
8001 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8002 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8003 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8004 /* HP mixer */
8005 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8006 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8007 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8008 /* Front Pin (0x0c) */
41d5545d
KS
8009 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8010 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8011 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8012 /* LFE Pin (0x0e) */
8013 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8014 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8015 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8016 /* HP Pin (0x0f) */
41d5545d
KS
8017 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8018 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8019 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8020 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8021 /* Front Mic pin: input vref at 80% */
8022 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8023 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8024 /* Line In pin */
8025 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8026 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8027
b8f171e7
AM
8028 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8029 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8030 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8031 { }
8032};
8033
e458b1fa
LY
8034/* Macmini 3,1 */
8035static struct hda_verb alc885_macmini3_init_verbs[] = {
8036 /* DACs */
8037 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8038 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8039 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8040 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8041 /* Front mixer */
8042 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8043 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8044 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8045 /* Surround mixer */
8046 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8047 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8048 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8049 /* LFE mixer */
8050 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8051 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8052 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8053 /* HP mixer */
8054 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8055 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8056 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8057 /* Front Pin (0x0c) */
8058 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8059 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8060 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8061 /* LFE Pin (0x0e) */
8062 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8063 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8064 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8065 /* HP Pin (0x0f) */
8066 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8067 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8068 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8069 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8070 /* Line In pin */
8071 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8072 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8073
8074 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8075 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8076 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8077 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8078 { }
8079};
8080
76e6f5a9
RH
8081
8082static struct hda_verb alc885_mba21_init_verbs[] = {
8083 /*Internal and HP Speaker Mixer*/
8084 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8085 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8086 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8087 /*Internal Speaker Pin (0x0c)*/
8088 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8089 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8090 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8091 /* HP Pin: output 0 (0x0e) */
8092 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8093 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8094 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8095 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8096 /* Line in (is hp when jack connected)*/
8097 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8098 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8099
8100 { }
8101 };
8102
8103
87350ad0
TI
8104/* Macbook Pro rev3 */
8105static struct hda_verb alc885_mbp3_init_verbs[] = {
8106 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8107 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8108 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8109 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8110 /* Rear mixer */
8111 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8112 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8113 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8114 /* HP mixer */
8115 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8116 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8117 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8118 /* Front Pin: output 0 (0x0c) */
8119 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8120 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8121 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8122 /* HP Pin: output 0 (0x0e) */
87350ad0 8123 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8124 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8125 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8126 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8127 /* Mic (rear) pin: input vref at 80% */
8128 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8129 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8130 /* Front Mic pin: input vref at 80% */
8131 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8132 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8133 /* Line In pin: use output 1 when in LineOut mode */
8134 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8135 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8136 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8137
8138 /* FIXME: use matrix-type input source selection */
8139 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8140 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8141 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8142 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8143 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8144 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8145 /* Input mixer2 */
8146 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8147 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8148 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8149 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8150 /* Input mixer3 */
8151 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8152 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8153 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8154 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8155 /* ADC1: mute amp left and right */
8156 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8157 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8158 /* ADC2: mute amp left and right */
8159 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8160 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8161 /* ADC3: mute amp left and right */
8162 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8163 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8164
8165 { }
8166};
8167
4b7e1803
JM
8168/* iMac 9,1 */
8169static struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8170 /* Internal Speaker Pin (0x0c) */
8171 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8172 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8173 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8174 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8175 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8176 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8177 /* HP Pin: Rear */
4b7e1803
JM
8178 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8179 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8180 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8181 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8182 /* Line in Rear */
8183 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8184 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8185 /* Front Mic pin: input vref at 80% */
8186 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8187 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8188 /* Rear mixer */
8189 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8190 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8191 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8192 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8193 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8194 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8195 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8196 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8197 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8198 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8199 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8200 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8201 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8202 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8203 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8204 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8205 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8206 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8207 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8208 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8209 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8210 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8211 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8212 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8213 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8214 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8215 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8216 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8217 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8218 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8219 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8220 { }
8221};
8222
c54728d8
NF
8223/* iMac 24 mixer. */
8224static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8225 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8226 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8227 { } /* end */
8228};
8229
8230/* iMac 24 init verbs. */
8231static struct hda_verb alc885_imac24_init_verbs[] = {
8232 /* Internal speakers: output 0 (0x0c) */
8233 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8234 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8235 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8236 /* Internal speakers: output 0 (0x0c) */
8237 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8238 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8239 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8240 /* Headphone: output 0 (0x0c) */
8241 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8242 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8243 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8244 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8245 /* Front Mic: input vref at 80% */
8246 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8247 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8248 { }
8249};
8250
8251/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8252static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8253{
a9fd4f3f 8254 struct alc_spec *spec = codec->spec;
c54728d8 8255
a9fd4f3f
TI
8256 spec->autocfg.hp_pins[0] = 0x14;
8257 spec->autocfg.speaker_pins[0] = 0x18;
8258 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8259}
8260
9d54f08b
TI
8261#define alc885_mb5_setup alc885_imac24_setup
8262#define alc885_macmini3_setup alc885_imac24_setup
8263
76e6f5a9
RH
8264/* Macbook Air 2,1 */
8265static void alc885_mba21_setup(struct hda_codec *codec)
8266{
8267 struct alc_spec *spec = codec->spec;
8268
8269 spec->autocfg.hp_pins[0] = 0x14;
8270 spec->autocfg.speaker_pins[0] = 0x18;
8271}
8272
8273
8274
4f5d1706 8275static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8276{
a9fd4f3f 8277 struct alc_spec *spec = codec->spec;
87350ad0 8278
a9fd4f3f
TI
8279 spec->autocfg.hp_pins[0] = 0x15;
8280 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8281}
8282
9d54f08b 8283static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8284{
9d54f08b 8285 struct alc_spec *spec = codec->spec;
4b7e1803 8286
9d54f08b 8287 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8288 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8289 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8290}
87350ad0 8291
272a527c
KY
8292static struct hda_verb alc882_targa_verbs[] = {
8293 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8294 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8295
8296 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8297 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8298
272a527c
KY
8299 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8300 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8301 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8302
8303 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8304 { } /* end */
8305};
8306
8307/* toggle speaker-output according to the hp-jack state */
8308static void alc882_targa_automute(struct hda_codec *codec)
8309{
a9fd4f3f
TI
8310 struct alc_spec *spec = codec->spec;
8311 alc_automute_amp(codec);
82beb8fd 8312 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8313 spec->jack_present ? 1 : 3);
8314}
8315
4f5d1706 8316static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8317{
8318 struct alc_spec *spec = codec->spec;
8319
8320 spec->autocfg.hp_pins[0] = 0x14;
8321 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8322}
8323
8324static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8325{
a9fd4f3f 8326 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8327 alc882_targa_automute(codec);
272a527c
KY
8328}
8329
8330static struct hda_verb alc882_asus_a7j_verbs[] = {
8331 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8332 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8333
8334 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8335 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8336 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8337
272a527c
KY
8338 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8339 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8340 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8341
8342 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8343 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8344 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8345 { } /* end */
8346};
8347
914759b7
TI
8348static struct hda_verb alc882_asus_a7m_verbs[] = {
8349 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8350 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8351
8352 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8353 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8354 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8355
914759b7
TI
8356 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8357 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8358 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8359
8360 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8361 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8362 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8363 { } /* end */
8364};
8365
9102cd1c
TD
8366static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8367{
8368 unsigned int gpiostate, gpiomask, gpiodir;
8369
8370 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8371 AC_VERB_GET_GPIO_DATA, 0);
8372
8373 if (!muted)
8374 gpiostate |= (1 << pin);
8375 else
8376 gpiostate &= ~(1 << pin);
8377
8378 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8379 AC_VERB_GET_GPIO_MASK, 0);
8380 gpiomask |= (1 << pin);
8381
8382 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8383 AC_VERB_GET_GPIO_DIRECTION, 0);
8384 gpiodir |= (1 << pin);
8385
8386
8387 snd_hda_codec_write(codec, codec->afg, 0,
8388 AC_VERB_SET_GPIO_MASK, gpiomask);
8389 snd_hda_codec_write(codec, codec->afg, 0,
8390 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8391
8392 msleep(1);
8393
8394 snd_hda_codec_write(codec, codec->afg, 0,
8395 AC_VERB_SET_GPIO_DATA, gpiostate);
8396}
8397
7debbe51
TI
8398/* set up GPIO at initialization */
8399static void alc885_macpro_init_hook(struct hda_codec *codec)
8400{
8401 alc882_gpio_mute(codec, 0, 0);
8402 alc882_gpio_mute(codec, 1, 0);
8403}
8404
8405/* set up GPIO and update auto-muting at initialization */
8406static void alc885_imac24_init_hook(struct hda_codec *codec)
8407{
8408 alc885_macpro_init_hook(codec);
4f5d1706 8409 alc_automute_amp(codec);
7debbe51
TI
8410}
8411
df694daa
KY
8412/*
8413 * generic initialization of ADC, input mixers and output mixers
8414 */
4953550a 8415static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8416 /*
8417 * Unmute ADC0-2 and set the default input to mic-in
8418 */
4953550a
TI
8419 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8420 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8421 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8422 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8423
4953550a
TI
8424 /*
8425 * Set up output mixers (0x0c - 0x0f)
8426 */
8427 /* set vol=0 to output mixers */
8428 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8429 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8430 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8431 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8432 /* set up input amps for analog loopback */
8433 /* Amp Indices: DAC = 0, mixer = 1 */
8434 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8435 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8436 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8437 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8438 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8439 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8440 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8441 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8442 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8443 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8444
4953550a
TI
8445 /* FIXME: use matrix-type input source selection */
8446 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8447 /* Input mixer2 */
88102f3f 8448 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8449 /* Input mixer3 */
88102f3f 8450 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8451 { }
9c7f852e
TI
8452};
8453
eb4c41d3
TS
8454/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8455static struct hda_verb alc889A_mb31_ch2_init[] = {
8456 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8457 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8458 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8459 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8460 { } /* end */
8461};
8462
8463/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8464static struct hda_verb alc889A_mb31_ch4_init[] = {
8465 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8466 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8467 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8468 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8469 { } /* end */
8470};
8471
8472/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8473static struct hda_verb alc889A_mb31_ch5_init[] = {
8474 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8475 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8476 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8477 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8478 { } /* end */
8479};
8480
8481/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8482static struct hda_verb alc889A_mb31_ch6_init[] = {
8483 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8484 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8485 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8486 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8487 { } /* end */
8488};
8489
8490static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8491 { 2, alc889A_mb31_ch2_init },
8492 { 4, alc889A_mb31_ch4_init },
8493 { 5, alc889A_mb31_ch5_init },
8494 { 6, alc889A_mb31_ch6_init },
8495};
8496
b373bdeb
AN
8497static struct hda_verb alc883_medion_eapd_verbs[] = {
8498 /* eanable EAPD on medion laptop */
8499 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8500 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8501 { }
8502};
8503
4953550a 8504#define alc883_base_mixer alc882_base_mixer
834be88d 8505
a8848bd6
AS
8506static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8507 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8508 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8509 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8510 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8511 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8512 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8513 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8514 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8515 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8516 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8517 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8518 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8519 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8520 { } /* end */
8521};
8522
0c4cc443 8523static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8524 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8525 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8526 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8527 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8528 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8529 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8530 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8531 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8532 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8533 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8534 { } /* end */
8535};
8536
fb97dc67
J
8537static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8538 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8539 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8540 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8541 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8542 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8543 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8544 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8545 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8546 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8547 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8548 { } /* end */
8549};
8550
9c7f852e
TI
8551static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8552 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8553 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8554 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8555 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8556 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8557 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8558 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8559 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8560 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8561 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8562 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8563 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8564 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8565 { } /* end */
8566};
df694daa 8567
9c7f852e
TI
8568static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8569 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8570 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8571 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8572 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8573 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8574 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8575 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8576 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8577 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8578 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8579 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8580 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8581 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8582 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8583 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8584 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8585 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8586 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8587 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8588 { } /* end */
8589};
8590
17bba1b7
J
8591static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8592 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8593 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8594 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8595 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8596 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8597 HDA_OUTPUT),
8598 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8599 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8600 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8601 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8602 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8603 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8604 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8605 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8606 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8607 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8608 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8609 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8610 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8611 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8612 { } /* end */
8613};
8614
87a8c370
JK
8615static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8616 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8617 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8618 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8619 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8620 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8621 HDA_OUTPUT),
8622 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8623 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8624 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8625 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8626 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8627 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8628 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8629 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8630 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8631 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
8632 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8633 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8634 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8635 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8636 { } /* end */
8637};
8638
d1d985f0 8639static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8640 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8641 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8642 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8643 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8644 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8645 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8646 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8647 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8648 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8649 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8650 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8651 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8652 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8653 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8654 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
8655 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8656 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8657 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8 8658 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
8659 { } /* end */
8660};
8661
c259249f 8662static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 8663 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8664 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8665 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8666 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8667 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8668 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8669 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8670 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8671 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8672 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8673 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8674 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8675 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8676 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8677 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8678 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8679 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 8680 { } /* end */
f12ab1e0 8681};
ccc656ce 8682
c259249f 8683static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 8684 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8685 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8686 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8687 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8688 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8689 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8690 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8691 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8692 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
8693 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8694 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8695 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 8696 { } /* end */
f12ab1e0 8697};
ccc656ce 8698
b99dba34
TI
8699static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8700 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8701 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8702 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8703 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8704 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8705 { } /* end */
8706};
8707
bc9f98a9
KY
8708static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8709 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8710 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
8711 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8712 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
8713 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8714 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8715 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8716 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 8717 { } /* end */
f12ab1e0 8718};
bc9f98a9 8719
272a527c
KY
8720static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8721 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8722 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8723 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8724 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8725 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8726 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8727 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
150b432f
DH
8728 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8729 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
8730 { } /* end */
8731};
8732
8733static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8734 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8735 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8736 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8737 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8738 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8739 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8740 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8741 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8742 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
272a527c 8743 { } /* end */
ea1fb29a 8744};
272a527c 8745
7ad7b218
MC
8746static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
8747 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8748 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8749 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8750 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
8751 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
8752 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
8753 { } /* end */
8754};
8755
8756static struct hda_verb alc883_medion_wim2160_verbs[] = {
8757 /* Unmute front mixer */
8758 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8759 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8760
8761 /* Set speaker pin to front mixer */
8762 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8763
8764 /* Init headphone pin */
8765 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8766 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8767 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8768 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8769
8770 { } /* end */
8771};
8772
8773/* toggle speaker-output according to the hp-jack state */
8774static void alc883_medion_wim2160_setup(struct hda_codec *codec)
8775{
8776 struct alc_spec *spec = codec->spec;
8777
8778 spec->autocfg.hp_pins[0] = 0x1a;
8779 spec->autocfg.speaker_pins[0] = 0x15;
8780}
8781
2880a867 8782static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
8783 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8784 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 8785 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
8786 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8787 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
8788 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8789 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8790 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 8791 { } /* end */
d1a991a6 8792};
2880a867 8793
d2fd4b09
TV
8794static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8795 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 8796 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
8797 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8798 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
8799 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8800 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8801 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8802 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8803 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8804 { } /* end */
8805};
8806
e2757d5e
KY
8807static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8808 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8809 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8810 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8811 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8812 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8813 0x0d, 1, 0x0, HDA_OUTPUT),
8814 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8815 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8816 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8817 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8818 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
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),
8824 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8825 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8826 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8827 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8828 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
8829 { } /* end */
8830};
8831
eb4c41d3
TS
8832static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8833 /* Output mixers */
8834 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8835 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8836 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8837 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8838 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8839 HDA_OUTPUT),
8840 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8841 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8842 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8843 /* Output switches */
8844 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8845 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8846 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8847 /* Boost mixers */
8848 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8849 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8850 /* Input mixers */
8851 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8852 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8853 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8854 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8855 { } /* end */
8856};
8857
3e1647c5
GG
8858static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8859 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8860 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8861 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8862 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8863 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8864 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8865 { } /* end */
8866};
8867
e2757d5e
KY
8868static struct hda_bind_ctls alc883_bind_cap_vol = {
8869 .ops = &snd_hda_bind_vol,
8870 .values = {
8871 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8872 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8873 0
8874 },
8875};
8876
8877static struct hda_bind_ctls alc883_bind_cap_switch = {
8878 .ops = &snd_hda_bind_sw,
8879 .values = {
8880 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8881 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8882 0
8883 },
8884};
8885
8886static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8887 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8888 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8889 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8890 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8891 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8892 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4953550a
TI
8893 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8894 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8895 { } /* end */
8896};
df694daa 8897
4953550a
TI
8898static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8899 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8900 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8901 {
8902 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8903 /* .name = "Capture Source", */
8904 .name = "Input Source",
8905 .count = 1,
8906 .info = alc_mux_enum_info,
8907 .get = alc_mux_enum_get,
8908 .put = alc_mux_enum_put,
8909 },
8910 { } /* end */
8911};
9c7f852e 8912
4953550a
TI
8913static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8914 {
8915 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8916 .name = "Channel Mode",
8917 .info = alc_ch_mode_info,
8918 .get = alc_ch_mode_get,
8919 .put = alc_ch_mode_put,
8920 },
8921 { } /* end */
9c7f852e
TI
8922};
8923
a8848bd6 8924/* toggle speaker-output according to the hp-jack state */
4f5d1706 8925static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 8926{
a9fd4f3f 8927 struct alc_spec *spec = codec->spec;
a8848bd6 8928
a9fd4f3f
TI
8929 spec->autocfg.hp_pins[0] = 0x15;
8930 spec->autocfg.speaker_pins[0] = 0x14;
8931 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
8932}
8933
8934/* auto-toggle front mic */
8935/*
8936static void alc883_mitac_mic_automute(struct hda_codec *codec)
8937{
864f92be 8938 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
a8848bd6 8939
a8848bd6
AS
8940 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8941}
8942*/
8943
a8848bd6
AS
8944static struct hda_verb alc883_mitac_verbs[] = {
8945 /* HP */
8946 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8947 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8948 /* Subwoofer */
8949 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8950 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8951
8952 /* enable unsolicited event */
8953 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8954 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8955
8956 { } /* end */
8957};
8958
a65cc60f 8959static struct hda_verb alc883_clevo_m540r_verbs[] = {
8960 /* HP */
8961 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8962 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8963 /* Int speaker */
8964 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
8965
8966 /* enable unsolicited event */
8967 /*
8968 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8969 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8970 */
8971
8972 { } /* end */
8973};
8974
0c4cc443 8975static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
8976 /* HP */
8977 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8978 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8979 /* Int speaker */
8980 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8981 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8982
8983 /* enable unsolicited event */
8984 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 8985 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
8986
8987 { } /* end */
8988};
8989
fb97dc67
J
8990static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8991 /* HP */
8992 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8993 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8994 /* Subwoofer */
8995 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8996 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8997
8998 /* enable unsolicited event */
8999 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9000
9001 { } /* end */
9002};
9003
c259249f 9004static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9005 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9006 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9007
9008 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9009 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9010
64a8be74
DH
9011/* Connect Line-Out side jack (SPDIF) to Side */
9012 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9013 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9014 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9015/* Connect Mic jack to CLFE */
9016 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9017 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9018 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9019/* Connect Line-in jack to Surround */
9020 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9021 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9022 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9023/* Connect HP out jack to Front */
9024 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9025 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9026 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9027
9028 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9029
9030 { } /* end */
9031};
9032
bc9f98a9
KY
9033static struct hda_verb alc883_lenovo_101e_verbs[] = {
9034 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9035 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9036 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9037 { } /* end */
9038};
9039
272a527c
KY
9040static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9041 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9042 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9043 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9044 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9045 { } /* end */
9046};
9047
9048static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9049 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9050 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9051 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9052 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9053 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9054 { } /* end */
9055};
9056
189609ae
KY
9057static struct hda_verb alc883_haier_w66_verbs[] = {
9058 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9059 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9060
9061 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9062
9063 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9064 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9065 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9066 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9067 { } /* end */
9068};
9069
e2757d5e
KY
9070static struct hda_verb alc888_lenovo_sky_verbs[] = {
9071 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9072 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9073 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9074 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9075 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9076 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9077 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9078 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9079 { } /* end */
9080};
9081
8718b700
HRK
9082static struct hda_verb alc888_6st_dell_verbs[] = {
9083 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9084 { }
9085};
9086
3e1647c5
GG
9087static struct hda_verb alc883_vaiott_verbs[] = {
9088 /* HP */
9089 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9090 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9091
9092 /* enable unsolicited event */
9093 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9094
9095 { } /* end */
9096};
9097
4f5d1706 9098static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9099{
a9fd4f3f 9100 struct alc_spec *spec = codec->spec;
8718b700 9101
a9fd4f3f
TI
9102 spec->autocfg.hp_pins[0] = 0x1b;
9103 spec->autocfg.speaker_pins[0] = 0x14;
9104 spec->autocfg.speaker_pins[1] = 0x16;
9105 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
9106}
9107
4723c022 9108static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9109 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9110 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9111 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9112 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9113 { } /* end */
5795b9e6
CM
9114};
9115
3ea0d7cf
HRK
9116/*
9117 * 2ch mode
9118 */
4723c022 9119static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9120 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9121 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9122 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9123 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9124 { } /* end */
8341de60
CM
9125};
9126
3ea0d7cf
HRK
9127/*
9128 * 4ch mode
9129 */
9130static struct hda_verb alc888_3st_hp_4ch_init[] = {
9131 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9132 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9133 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9134 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9135 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9136 { } /* end */
9137};
9138
9139/*
9140 * 6ch mode
9141 */
4723c022 9142static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9143 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9144 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9145 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9146 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9147 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9148 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9149 { } /* end */
8341de60
CM
9150};
9151
3ea0d7cf 9152static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9153 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9154 { 4, alc888_3st_hp_4ch_init },
4723c022 9155 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9156};
9157
272a527c
KY
9158/* toggle front-jack and RCA according to the hp-jack state */
9159static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9160{
864f92be 9161 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 9162
47fd830a
TI
9163 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9164 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9165 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9166 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
9167}
9168
9169/* toggle RCA according to the front-jack state */
9170static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9171{
864f92be 9172 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 9173
47fd830a
TI
9174 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9175 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 9176}
47fd830a 9177
272a527c
KY
9178static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9179 unsigned int res)
9180{
9181 if ((res >> 26) == ALC880_HP_EVENT)
9182 alc888_lenovo_ms7195_front_automute(codec);
9183 if ((res >> 26) == ALC880_FRONT_EVENT)
9184 alc888_lenovo_ms7195_rca_automute(codec);
9185}
9186
9187static struct hda_verb alc883_medion_md2_verbs[] = {
9188 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9189 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9190
9191 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9192
9193 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9194 { } /* end */
9195};
9196
9197/* toggle speaker-output according to the hp-jack state */
4f5d1706 9198static void alc883_medion_md2_setup(struct hda_codec *codec)
272a527c 9199{
a9fd4f3f 9200 struct alc_spec *spec = codec->spec;
272a527c 9201
a9fd4f3f
TI
9202 spec->autocfg.hp_pins[0] = 0x14;
9203 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
9204}
9205
ccc656ce 9206/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9207#define alc883_targa_init_hook alc882_targa_init_hook
9208#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9209
0c4cc443
HRK
9210static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
9211{
9212 unsigned int present;
9213
d56757ab 9214 present = snd_hda_jack_detect(codec, 0x18);
0c4cc443
HRK
9215 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
9216 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9217}
9218
4f5d1706 9219static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9220{
a9fd4f3f
TI
9221 struct alc_spec *spec = codec->spec;
9222
9223 spec->autocfg.hp_pins[0] = 0x15;
9224 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
9225}
9226
9227static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9228{
a9fd4f3f 9229 alc_automute_amp(codec);
0c4cc443
HRK
9230 alc883_clevo_m720_mic_automute(codec);
9231}
9232
9233static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9234 unsigned int res)
9235{
0c4cc443 9236 switch (res >> 26) {
0c4cc443
HRK
9237 case ALC880_MIC_EVENT:
9238 alc883_clevo_m720_mic_automute(codec);
9239 break;
a9fd4f3f
TI
9240 default:
9241 alc_automute_amp_unsol_event(codec, res);
9242 break;
0c4cc443 9243 }
368c7a95
J
9244}
9245
fb97dc67 9246/* toggle speaker-output according to the hp-jack state */
4f5d1706 9247static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9248{
a9fd4f3f 9249 struct alc_spec *spec = codec->spec;
fb97dc67 9250
a9fd4f3f
TI
9251 spec->autocfg.hp_pins[0] = 0x14;
9252 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9253}
9254
4f5d1706 9255static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9256{
a9fd4f3f 9257 struct alc_spec *spec = codec->spec;
189609ae 9258
a9fd4f3f
TI
9259 spec->autocfg.hp_pins[0] = 0x1b;
9260 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9261}
9262
bc9f98a9
KY
9263static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9264{
864f92be 9265 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9266
47fd830a
TI
9267 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9268 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9269}
9270
9271static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9272{
864f92be 9273 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9274
47fd830a
TI
9275 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9276 HDA_AMP_MUTE, bits);
9277 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9278 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9279}
9280
9281static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9282 unsigned int res)
9283{
9284 if ((res >> 26) == ALC880_HP_EVENT)
9285 alc883_lenovo_101e_all_automute(codec);
9286 if ((res >> 26) == ALC880_FRONT_EVENT)
9287 alc883_lenovo_101e_ispeaker_automute(codec);
9288}
9289
676a9b53 9290/* toggle speaker-output according to the hp-jack state */
4f5d1706 9291static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9292{
a9fd4f3f 9293 struct alc_spec *spec = codec->spec;
676a9b53 9294
a9fd4f3f
TI
9295 spec->autocfg.hp_pins[0] = 0x14;
9296 spec->autocfg.speaker_pins[0] = 0x15;
9297 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9298}
9299
d1a991a6
KY
9300static struct hda_verb alc883_acer_eapd_verbs[] = {
9301 /* HP Pin: output 0 (0x0c) */
9302 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9303 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9304 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9305 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9306 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9307 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9308 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9309 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9310 /* eanable EAPD on medion laptop */
9311 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9312 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9313 /* enable unsolicited event */
9314 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9315 { }
9316};
9317
fc86f954
DK
9318static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
9319 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9320 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9321 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9322 { } /* end */
9323};
9324
4f5d1706 9325static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9326{
a9fd4f3f 9327 struct alc_spec *spec = codec->spec;
5795b9e6 9328
a9fd4f3f
TI
9329 spec->autocfg.hp_pins[0] = 0x1b;
9330 spec->autocfg.speaker_pins[0] = 0x14;
9331 spec->autocfg.speaker_pins[1] = 0x15;
9332 spec->autocfg.speaker_pins[2] = 0x16;
9333 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9334}
9335
4f5d1706 9336static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9337{
a9fd4f3f 9338 struct alc_spec *spec = codec->spec;
e2757d5e 9339
a9fd4f3f
TI
9340 spec->autocfg.hp_pins[0] = 0x1b;
9341 spec->autocfg.speaker_pins[0] = 0x14;
9342 spec->autocfg.speaker_pins[1] = 0x15;
9343 spec->autocfg.speaker_pins[2] = 0x16;
9344 spec->autocfg.speaker_pins[3] = 0x17;
9345 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9346}
9347
4f5d1706 9348static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9349{
9350 struct alc_spec *spec = codec->spec;
9351
9352 spec->autocfg.hp_pins[0] = 0x15;
9353 spec->autocfg.speaker_pins[0] = 0x14;
9354 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9355}
9356
e2757d5e
KY
9357static struct hda_verb alc888_asus_m90v_verbs[] = {
9358 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9359 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9360 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9361 /* enable unsolicited event */
9362 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9363 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9364 { } /* end */
9365};
9366
4f5d1706 9367static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9368{
a9fd4f3f 9369 struct alc_spec *spec = codec->spec;
e2757d5e 9370
a9fd4f3f
TI
9371 spec->autocfg.hp_pins[0] = 0x1b;
9372 spec->autocfg.speaker_pins[0] = 0x14;
9373 spec->autocfg.speaker_pins[1] = 0x15;
9374 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9375 spec->ext_mic.pin = 0x18;
9376 spec->int_mic.pin = 0x19;
9377 spec->ext_mic.mux_idx = 0;
9378 spec->int_mic.mux_idx = 1;
9379 spec->auto_mic = 1;
e2757d5e
KY
9380}
9381
9382static struct hda_verb alc888_asus_eee1601_verbs[] = {
9383 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9384 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9385 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9386 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9387 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9388 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9389 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9390 /* enable unsolicited event */
9391 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9392 { } /* end */
9393};
9394
e2757d5e
KY
9395static void alc883_eee1601_inithook(struct hda_codec *codec)
9396{
a9fd4f3f
TI
9397 struct alc_spec *spec = codec->spec;
9398
9399 spec->autocfg.hp_pins[0] = 0x14;
9400 spec->autocfg.speaker_pins[0] = 0x1b;
9401 alc_automute_pin(codec);
e2757d5e
KY
9402}
9403
eb4c41d3
TS
9404static struct hda_verb alc889A_mb31_verbs[] = {
9405 /* Init rear pin (used as headphone output) */
9406 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9407 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9408 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9409 /* Init line pin (used as output in 4ch and 6ch mode) */
9410 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9411 /* Init line 2 pin (used as headphone out by default) */
9412 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9413 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9414 { } /* end */
9415};
9416
9417/* Mute speakers according to the headphone jack state */
9418static void alc889A_mb31_automute(struct hda_codec *codec)
9419{
9420 unsigned int present;
9421
9422 /* Mute only in 2ch or 4ch mode */
9423 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9424 == 0x00) {
864f92be 9425 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9426 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9427 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9428 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9429 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9430 }
9431}
9432
9433static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9434{
9435 if ((res >> 26) == ALC880_HP_EVENT)
9436 alc889A_mb31_automute(codec);
9437}
9438
4953550a 9439
cb53c626 9440#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9441#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9442#endif
9443
def319f9 9444/* pcm configuration: identical with ALC880 */
4953550a
TI
9445#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9446#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9447#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9448#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9449
9450static hda_nid_t alc883_slave_dig_outs[] = {
9451 ALC1200_DIGOUT_NID, 0,
9452};
9453
9454static hda_nid_t alc1200_slave_dig_outs[] = {
9455 ALC883_DIGOUT_NID, 0,
9456};
9c7f852e
TI
9457
9458/*
9459 * configuration and preset
9460 */
4953550a
TI
9461static const char *alc882_models[ALC882_MODEL_LAST] = {
9462 [ALC882_3ST_DIG] = "3stack-dig",
9463 [ALC882_6ST_DIG] = "6stack-dig",
9464 [ALC882_ARIMA] = "arima",
9465 [ALC882_W2JC] = "w2jc",
9466 [ALC882_TARGA] = "targa",
9467 [ALC882_ASUS_A7J] = "asus-a7j",
9468 [ALC882_ASUS_A7M] = "asus-a7m",
9469 [ALC885_MACPRO] = "macpro",
9470 [ALC885_MB5] = "mb5",
e458b1fa 9471 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9472 [ALC885_MBA21] = "mba21",
4953550a
TI
9473 [ALC885_MBP3] = "mbp3",
9474 [ALC885_IMAC24] = "imac24",
4b7e1803 9475 [ALC885_IMAC91] = "imac91",
4953550a 9476 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9477 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9478 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9479 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9480 [ALC883_TARGA_DIG] = "targa-dig",
9481 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9482 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9483 [ALC883_ACER] = "acer",
2880a867 9484 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9485 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9486 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9487 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9488 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9489 [ALC883_MEDION] = "medion",
272a527c 9490 [ALC883_MEDION_MD2] = "medion-md2",
7ad7b218 9491 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9492 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9493 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9494 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9495 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9496 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9497 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9498 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9499 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9500 [ALC883_MITAC] = "mitac",
a65cc60f 9501 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9502 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9503 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9504 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9505 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9506 [ALC889A_INTEL] = "intel-alc889a",
9507 [ALC889_INTEL] = "intel-x58",
3ab90935 9508 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9509 [ALC889A_MB31] = "mb31",
3e1647c5 9510 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9511 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9512};
9513
4953550a
TI
9514static struct snd_pci_quirk alc882_cfg_tbl[] = {
9515 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9516
ac3e3741 9517 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9518 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9519 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9520 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9521 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9522 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9523 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9524 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9525 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9526 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9527 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9528 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9529 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9530 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9531 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9532 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9533 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9534 ALC888_ACER_ASPIRE_6530G),
cc374c47 9535 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9536 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9537 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9538 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9539 /* default Acer -- disabled as it causes more problems.
9540 * model=auto should work fine now
9541 */
9542 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9543
5795b9e6 9544 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9545
febe3375 9546 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9547 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9548 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9549 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9550 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9551 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9552
9553 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9554 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9555 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9556 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9557 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9558 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9559 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9560 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9561 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9562 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9563 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9564
9565 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9566 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9567 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9568 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9569 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9570 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9571 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9572 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9573 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9574
6f3bf657 9575 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9576 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9577 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9578 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9579 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9580 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9581 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9582 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9583 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9584 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9585 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9586 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9587 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9588 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9589 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9590 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9591 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9592 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9593 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9594 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9595 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9596 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9597 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9598 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9599 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9600 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9601 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9602 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9603 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9604 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9605 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9606
ac3e3741 9607 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9608 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9609 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9610 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9611 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9612 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9613 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9614 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9615 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9616 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9617 ALC883_FUJITSU_PI2515),
bfb53037 9618 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9619 ALC888_FUJITSU_XA3530),
272a527c 9620 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9621 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9622 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9623 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9624 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
272a527c 9625 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
959973b9 9626 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9627 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9628 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9629
17bba1b7
J
9630 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9631 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9632 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9633 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9634 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9635 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9636 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9637
4953550a 9638 {}
f3cd3f5d
WF
9639};
9640
4953550a
TI
9641/* codec SSID table for Intel Mac */
9642static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9643 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9644 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9645 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9646 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9647 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9648 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9649 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 9650 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 9651 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 9652 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 9653 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
9654 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9655 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9656 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9657 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9658 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 9659 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
9660 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9661 * so apparently no perfect solution yet
4953550a
TI
9662 */
9663 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9664 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9665 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9666 {} /* terminator */
b25c9da1
WF
9667};
9668
4953550a
TI
9669static struct alc_config_preset alc882_presets[] = {
9670 [ALC882_3ST_DIG] = {
9671 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9672 .init_verbs = { alc882_base_init_verbs,
9673 alc882_adc1_init_verbs },
4953550a
TI
9674 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9675 .dac_nids = alc882_dac_nids,
9676 .dig_out_nid = ALC882_DIGOUT_NID,
9677 .dig_in_nid = ALC882_DIGIN_NID,
9678 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9679 .channel_mode = alc882_ch_modes,
9680 .need_dac_fix = 1,
9681 .input_mux = &alc882_capture_source,
9682 },
9683 [ALC882_6ST_DIG] = {
9684 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9685 .init_verbs = { alc882_base_init_verbs,
9686 alc882_adc1_init_verbs },
4953550a
TI
9687 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9688 .dac_nids = alc882_dac_nids,
9689 .dig_out_nid = ALC882_DIGOUT_NID,
9690 .dig_in_nid = ALC882_DIGIN_NID,
9691 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9692 .channel_mode = alc882_sixstack_modes,
9693 .input_mux = &alc882_capture_source,
9694 },
9695 [ALC882_ARIMA] = {
9696 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9697 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9698 alc882_eapd_verbs },
4953550a
TI
9699 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9700 .dac_nids = alc882_dac_nids,
9701 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9702 .channel_mode = alc882_sixstack_modes,
9703 .input_mux = &alc882_capture_source,
9704 },
9705 [ALC882_W2JC] = {
9706 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9707 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9708 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
9709 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9710 .dac_nids = alc882_dac_nids,
9711 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9712 .channel_mode = alc880_threestack_modes,
9713 .need_dac_fix = 1,
9714 .input_mux = &alc882_capture_source,
9715 .dig_out_nid = ALC882_DIGOUT_NID,
9716 },
76e6f5a9
RH
9717 [ALC885_MBA21] = {
9718 .mixers = { alc885_mba21_mixer },
9719 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9720 .num_dacs = 2,
9721 .dac_nids = alc882_dac_nids,
9722 .channel_mode = alc885_mba21_ch_modes,
9723 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9724 .input_mux = &alc882_capture_source,
9725 .unsol_event = alc_automute_amp_unsol_event,
9726 .setup = alc885_mba21_setup,
9727 .init_hook = alc_automute_amp,
9728 },
4953550a
TI
9729 [ALC885_MBP3] = {
9730 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9731 .init_verbs = { alc885_mbp3_init_verbs,
9732 alc880_gpio1_init_verbs },
be0ae923 9733 .num_dacs = 2,
4953550a 9734 .dac_nids = alc882_dac_nids,
be0ae923
TI
9735 .hp_nid = 0x04,
9736 .channel_mode = alc885_mbp_4ch_modes,
9737 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
9738 .input_mux = &alc882_capture_source,
9739 .dig_out_nid = ALC882_DIGOUT_NID,
9740 .dig_in_nid = ALC882_DIGIN_NID,
9741 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9742 .setup = alc885_mbp3_setup,
9743 .init_hook = alc_automute_amp,
4953550a
TI
9744 },
9745 [ALC885_MB5] = {
9746 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
9747 .init_verbs = { alc885_mb5_init_verbs,
9748 alc880_gpio1_init_verbs },
9749 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9750 .dac_nids = alc882_dac_nids,
9751 .channel_mode = alc885_mb5_6ch_modes,
9752 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
9753 .input_mux = &mb5_capture_source,
9754 .dig_out_nid = ALC882_DIGOUT_NID,
9755 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9756 .unsol_event = alc_automute_amp_unsol_event,
9757 .setup = alc885_mb5_setup,
9758 .init_hook = alc_automute_amp,
4953550a 9759 },
e458b1fa
LY
9760 [ALC885_MACMINI3] = {
9761 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9762 .init_verbs = { alc885_macmini3_init_verbs,
9763 alc880_gpio1_init_verbs },
9764 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9765 .dac_nids = alc882_dac_nids,
9766 .channel_mode = alc885_macmini3_6ch_modes,
9767 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9768 .input_mux = &macmini3_capture_source,
9769 .dig_out_nid = ALC882_DIGOUT_NID,
9770 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9771 .unsol_event = alc_automute_amp_unsol_event,
9772 .setup = alc885_macmini3_setup,
9773 .init_hook = alc_automute_amp,
e458b1fa 9774 },
4953550a
TI
9775 [ALC885_MACPRO] = {
9776 .mixers = { alc882_macpro_mixer },
9777 .init_verbs = { alc882_macpro_init_verbs },
9778 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9779 .dac_nids = alc882_dac_nids,
9780 .dig_out_nid = ALC882_DIGOUT_NID,
9781 .dig_in_nid = ALC882_DIGIN_NID,
9782 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9783 .channel_mode = alc882_ch_modes,
9784 .input_mux = &alc882_capture_source,
9785 .init_hook = alc885_macpro_init_hook,
9786 },
9787 [ALC885_IMAC24] = {
9788 .mixers = { alc885_imac24_mixer },
9789 .init_verbs = { alc885_imac24_init_verbs },
9790 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9791 .dac_nids = alc882_dac_nids,
9792 .dig_out_nid = ALC882_DIGOUT_NID,
9793 .dig_in_nid = ALC882_DIGIN_NID,
9794 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9795 .channel_mode = alc882_ch_modes,
9796 .input_mux = &alc882_capture_source,
9797 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 9798 .setup = alc885_imac24_setup,
4953550a
TI
9799 .init_hook = alc885_imac24_init_hook,
9800 },
4b7e1803 9801 [ALC885_IMAC91] = {
b7cccc52 9802 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
9803 .init_verbs = { alc885_imac91_init_verbs,
9804 alc880_gpio1_init_verbs },
9805 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9806 .dac_nids = alc882_dac_nids,
b7cccc52
JM
9807 .channel_mode = alc885_mba21_ch_modes,
9808 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9809 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
9810 .dig_out_nid = ALC882_DIGOUT_NID,
9811 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9812 .unsol_event = alc_automute_amp_unsol_event,
9813 .setup = alc885_imac91_setup,
9814 .init_hook = alc_automute_amp,
4b7e1803 9815 },
4953550a
TI
9816 [ALC882_TARGA] = {
9817 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 9818 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 9819 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
9820 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9821 .dac_nids = alc882_dac_nids,
9822 .dig_out_nid = ALC882_DIGOUT_NID,
9823 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9824 .adc_nids = alc882_adc_nids,
9825 .capsrc_nids = alc882_capsrc_nids,
9826 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9827 .channel_mode = alc882_3ST_6ch_modes,
9828 .need_dac_fix = 1,
9829 .input_mux = &alc882_capture_source,
9830 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
9831 .setup = alc882_targa_setup,
9832 .init_hook = alc882_targa_automute,
4953550a
TI
9833 },
9834 [ALC882_ASUS_A7J] = {
9835 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9836 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9837 alc882_asus_a7j_verbs},
4953550a
TI
9838 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9839 .dac_nids = alc882_dac_nids,
9840 .dig_out_nid = ALC882_DIGOUT_NID,
9841 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9842 .adc_nids = alc882_adc_nids,
9843 .capsrc_nids = alc882_capsrc_nids,
9844 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9845 .channel_mode = alc882_3ST_6ch_modes,
9846 .need_dac_fix = 1,
9847 .input_mux = &alc882_capture_source,
9848 },
9849 [ALC882_ASUS_A7M] = {
9850 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9851 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9852 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
9853 alc882_asus_a7m_verbs },
9854 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9855 .dac_nids = alc882_dac_nids,
9856 .dig_out_nid = ALC882_DIGOUT_NID,
9857 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9858 .channel_mode = alc880_threestack_modes,
9859 .need_dac_fix = 1,
9860 .input_mux = &alc882_capture_source,
9861 },
9c7f852e
TI
9862 [ALC883_3ST_2ch_DIG] = {
9863 .mixers = { alc883_3ST_2ch_mixer },
9864 .init_verbs = { alc883_init_verbs },
9865 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9866 .dac_nids = alc883_dac_nids,
9867 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9868 .dig_in_nid = ALC883_DIGIN_NID,
9869 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9870 .channel_mode = alc883_3ST_2ch_modes,
9871 .input_mux = &alc883_capture_source,
9872 },
9873 [ALC883_3ST_6ch_DIG] = {
9874 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9875 .init_verbs = { alc883_init_verbs },
9876 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9877 .dac_nids = alc883_dac_nids,
9878 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9879 .dig_in_nid = ALC883_DIGIN_NID,
9880 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9881 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9882 .need_dac_fix = 1,
9c7f852e 9883 .input_mux = &alc883_capture_source,
f12ab1e0 9884 },
9c7f852e
TI
9885 [ALC883_3ST_6ch] = {
9886 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9887 .init_verbs = { alc883_init_verbs },
9888 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9889 .dac_nids = alc883_dac_nids,
9c7f852e
TI
9890 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9891 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9892 .need_dac_fix = 1,
9c7f852e 9893 .input_mux = &alc883_capture_source,
f12ab1e0 9894 },
17bba1b7
J
9895 [ALC883_3ST_6ch_INTEL] = {
9896 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
9897 .init_verbs = { alc883_init_verbs },
9898 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9899 .dac_nids = alc883_dac_nids,
9900 .dig_out_nid = ALC883_DIGOUT_NID,
9901 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 9902 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
9903 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
9904 .channel_mode = alc883_3ST_6ch_intel_modes,
9905 .need_dac_fix = 1,
9906 .input_mux = &alc883_3stack_6ch_intel,
9907 },
87a8c370
JK
9908 [ALC889A_INTEL] = {
9909 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
9910 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
9911 alc_hp15_unsol_verbs },
87a8c370
JK
9912 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9913 .dac_nids = alc883_dac_nids,
9914 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9915 .adc_nids = alc889_adc_nids,
9916 .dig_out_nid = ALC883_DIGOUT_NID,
9917 .dig_in_nid = ALC883_DIGIN_NID,
9918 .slave_dig_outs = alc883_slave_dig_outs,
9919 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9920 .channel_mode = alc889_8ch_intel_modes,
9921 .capsrc_nids = alc889_capsrc_nids,
9922 .input_mux = &alc889_capture_source,
4f5d1706
TI
9923 .setup = alc889_automute_setup,
9924 .init_hook = alc_automute_amp,
6732bd0d 9925 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
9926 .need_dac_fix = 1,
9927 },
9928 [ALC889_INTEL] = {
9929 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9930 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 9931 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
9932 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9933 .dac_nids = alc883_dac_nids,
9934 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9935 .adc_nids = alc889_adc_nids,
9936 .dig_out_nid = ALC883_DIGOUT_NID,
9937 .dig_in_nid = ALC883_DIGIN_NID,
9938 .slave_dig_outs = alc883_slave_dig_outs,
9939 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9940 .channel_mode = alc889_8ch_intel_modes,
9941 .capsrc_nids = alc889_capsrc_nids,
9942 .input_mux = &alc889_capture_source,
4f5d1706 9943 .setup = alc889_automute_setup,
6732bd0d
WF
9944 .init_hook = alc889_intel_init_hook,
9945 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
9946 .need_dac_fix = 1,
9947 },
9c7f852e
TI
9948 [ALC883_6ST_DIG] = {
9949 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9950 .init_verbs = { alc883_init_verbs },
9951 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9952 .dac_nids = alc883_dac_nids,
9953 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9954 .dig_in_nid = ALC883_DIGIN_NID,
9955 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9956 .channel_mode = alc883_sixstack_modes,
9957 .input_mux = &alc883_capture_source,
9958 },
ccc656ce 9959 [ALC883_TARGA_DIG] = {
c259249f 9960 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
9961 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9962 alc883_targa_verbs},
ccc656ce
KY
9963 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9964 .dac_nids = alc883_dac_nids,
9965 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9966 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9967 .channel_mode = alc883_3ST_6ch_modes,
9968 .need_dac_fix = 1,
9969 .input_mux = &alc883_capture_source,
c259249f 9970 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9971 .setup = alc882_targa_setup,
9972 .init_hook = alc882_targa_automute,
ccc656ce
KY
9973 },
9974 [ALC883_TARGA_2ch_DIG] = {
c259249f 9975 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
9976 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9977 alc883_targa_verbs},
ccc656ce
KY
9978 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9979 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9980 .adc_nids = alc883_adc_nids_alt,
9981 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 9982 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 9983 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9984 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9985 .channel_mode = alc883_3ST_2ch_modes,
9986 .input_mux = &alc883_capture_source,
c259249f 9987 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9988 .setup = alc882_targa_setup,
9989 .init_hook = alc882_targa_automute,
ccc656ce 9990 },
64a8be74 9991 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
9992 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
9993 alc883_chmode_mixer },
64a8be74 9994 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 9995 alc883_targa_verbs },
64a8be74
DH
9996 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9997 .dac_nids = alc883_dac_nids,
9998 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9999 .adc_nids = alc883_adc_nids_rev,
10000 .capsrc_nids = alc883_capsrc_nids_rev,
10001 .dig_out_nid = ALC883_DIGOUT_NID,
10002 .dig_in_nid = ALC883_DIGIN_NID,
10003 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10004 .channel_mode = alc883_4ST_8ch_modes,
10005 .need_dac_fix = 1,
10006 .input_mux = &alc883_capture_source,
c259249f 10007 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10008 .setup = alc882_targa_setup,
10009 .init_hook = alc882_targa_automute,
64a8be74 10010 },
bab282b9 10011 [ALC883_ACER] = {
676a9b53 10012 .mixers = { alc883_base_mixer },
bab282b9
VA
10013 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10014 * and the headphone jack. Turn this on and rely on the
10015 * standard mute methods whenever the user wants to turn
10016 * these outputs off.
10017 */
10018 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10019 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10020 .dac_nids = alc883_dac_nids,
bab282b9
VA
10021 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10022 .channel_mode = alc883_3ST_2ch_modes,
10023 .input_mux = &alc883_capture_source,
10024 },
2880a867 10025 [ALC883_ACER_ASPIRE] = {
676a9b53 10026 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10027 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10028 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10029 .dac_nids = alc883_dac_nids,
10030 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10031 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10032 .channel_mode = alc883_3ST_2ch_modes,
10033 .input_mux = &alc883_capture_source,
a9fd4f3f 10034 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10035 .setup = alc883_acer_aspire_setup,
10036 .init_hook = alc_automute_amp,
d1a991a6 10037 },
5b2d1eca 10038 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 10039 .mixers = { alc888_base_mixer,
5b2d1eca
VP
10040 alc883_chmode_mixer },
10041 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10042 alc888_acer_aspire_4930g_verbs },
10043 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10044 .dac_nids = alc883_dac_nids,
10045 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10046 .adc_nids = alc883_adc_nids_rev,
10047 .capsrc_nids = alc883_capsrc_nids_rev,
10048 .dig_out_nid = ALC883_DIGOUT_NID,
10049 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10050 .channel_mode = alc883_3ST_6ch_modes,
10051 .need_dac_fix = 1,
973b8cb0 10052 .const_channel_count = 6,
5b2d1eca 10053 .num_mux_defs =
ef8ef5fb
VP
10054 ARRAY_SIZE(alc888_2_capture_sources),
10055 .input_mux = alc888_2_capture_sources,
d2fd4b09 10056 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10057 .setup = alc888_acer_aspire_4930g_setup,
10058 .init_hook = alc_automute_amp,
d2fd4b09
TV
10059 },
10060 [ALC888_ACER_ASPIRE_6530G] = {
10061 .mixers = { alc888_acer_aspire_6530_mixer },
10062 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10063 alc888_acer_aspire_6530g_verbs },
10064 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10065 .dac_nids = alc883_dac_nids,
10066 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10067 .adc_nids = alc883_adc_nids_rev,
10068 .capsrc_nids = alc883_capsrc_nids_rev,
10069 .dig_out_nid = ALC883_DIGOUT_NID,
10070 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10071 .channel_mode = alc883_3ST_2ch_modes,
10072 .num_mux_defs =
10073 ARRAY_SIZE(alc888_2_capture_sources),
10074 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 10075 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10076 .setup = alc888_acer_aspire_6530g_setup,
10077 .init_hook = alc_automute_amp,
5b2d1eca 10078 },
3b315d70 10079 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10080 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10081 alc883_chmode_mixer },
10082 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10083 alc889_acer_aspire_8930g_verbs,
10084 alc889_eapd_verbs},
3b315d70
HM
10085 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10086 .dac_nids = alc883_dac_nids,
018df418
HM
10087 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10088 .adc_nids = alc889_adc_nids,
10089 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10090 .dig_out_nid = ALC883_DIGOUT_NID,
10091 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10092 .channel_mode = alc883_3ST_6ch_modes,
10093 .need_dac_fix = 1,
10094 .const_channel_count = 6,
10095 .num_mux_defs =
018df418
HM
10096 ARRAY_SIZE(alc889_capture_sources),
10097 .input_mux = alc889_capture_sources,
3b315d70 10098 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10099 .setup = alc889_acer_aspire_8930g_setup,
10100 .init_hook = alc_automute_amp,
f5de24b0 10101#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10102 .power_hook = alc_power_eapd,
f5de24b0 10103#endif
3b315d70 10104 },
fc86f954
DK
10105 [ALC888_ACER_ASPIRE_7730G] = {
10106 .mixers = { alc883_3ST_6ch_mixer,
10107 alc883_chmode_mixer },
10108 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10109 alc888_acer_aspire_7730G_verbs },
10110 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10111 .dac_nids = alc883_dac_nids,
10112 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10113 .adc_nids = alc883_adc_nids_rev,
10114 .capsrc_nids = alc883_capsrc_nids_rev,
10115 .dig_out_nid = ALC883_DIGOUT_NID,
10116 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10117 .channel_mode = alc883_3ST_6ch_modes,
10118 .need_dac_fix = 1,
10119 .const_channel_count = 6,
10120 .input_mux = &alc883_capture_source,
10121 .unsol_event = alc_automute_amp_unsol_event,
10122 .setup = alc888_acer_aspire_6530g_setup,
10123 .init_hook = alc_automute_amp,
10124 },
c07584c8
TD
10125 [ALC883_MEDION] = {
10126 .mixers = { alc883_fivestack_mixer,
10127 alc883_chmode_mixer },
10128 .init_verbs = { alc883_init_verbs,
b373bdeb 10129 alc883_medion_eapd_verbs },
c07584c8
TD
10130 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10131 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10132 .adc_nids = alc883_adc_nids_alt,
10133 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10134 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10135 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10136 .channel_mode = alc883_sixstack_modes,
10137 .input_mux = &alc883_capture_source,
b373bdeb 10138 },
272a527c
KY
10139 [ALC883_MEDION_MD2] = {
10140 .mixers = { alc883_medion_md2_mixer},
10141 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
10142 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10143 .dac_nids = alc883_dac_nids,
10144 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10145 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10146 .channel_mode = alc883_3ST_2ch_modes,
10147 .input_mux = &alc883_capture_source,
a9fd4f3f 10148 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10149 .setup = alc883_medion_md2_setup,
10150 .init_hook = alc_automute_amp,
ea1fb29a 10151 },
7ad7b218
MC
10152 [ALC883_MEDION_WIM2160] = {
10153 .mixers = { alc883_medion_wim2160_mixer },
10154 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10155 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10156 .dac_nids = alc883_dac_nids,
10157 .dig_out_nid = ALC883_DIGOUT_NID,
10158 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10159 .adc_nids = alc883_adc_nids,
10160 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10161 .channel_mode = alc883_3ST_2ch_modes,
10162 .input_mux = &alc883_capture_source,
10163 .unsol_event = alc_automute_amp_unsol_event,
10164 .setup = alc883_medion_wim2160_setup,
10165 .init_hook = alc_automute_amp,
10166 },
b373bdeb 10167 [ALC883_LAPTOP_EAPD] = {
676a9b53 10168 .mixers = { alc883_base_mixer },
b373bdeb
AN
10169 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10170 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10171 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10172 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10173 .channel_mode = alc883_3ST_2ch_modes,
10174 .input_mux = &alc883_capture_source,
10175 },
a65cc60f 10176 [ALC883_CLEVO_M540R] = {
10177 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10178 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10179 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10180 .dac_nids = alc883_dac_nids,
10181 .dig_out_nid = ALC883_DIGOUT_NID,
10182 .dig_in_nid = ALC883_DIGIN_NID,
10183 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10184 .channel_mode = alc883_3ST_6ch_clevo_modes,
10185 .need_dac_fix = 1,
10186 .input_mux = &alc883_capture_source,
10187 /* This machine has the hardware HP auto-muting, thus
10188 * we need no software mute via unsol event
10189 */
10190 },
0c4cc443
HRK
10191 [ALC883_CLEVO_M720] = {
10192 .mixers = { alc883_clevo_m720_mixer },
10193 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10194 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10195 .dac_nids = alc883_dac_nids,
10196 .dig_out_nid = ALC883_DIGOUT_NID,
10197 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10198 .channel_mode = alc883_3ST_2ch_modes,
10199 .input_mux = &alc883_capture_source,
0c4cc443 10200 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10201 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10202 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10203 },
bc9f98a9
KY
10204 [ALC883_LENOVO_101E_2ch] = {
10205 .mixers = { alc883_lenovo_101e_2ch_mixer},
10206 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10207 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10208 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10209 .adc_nids = alc883_adc_nids_alt,
10210 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10211 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10212 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10213 .channel_mode = alc883_3ST_2ch_modes,
10214 .input_mux = &alc883_lenovo_101e_capture_source,
10215 .unsol_event = alc883_lenovo_101e_unsol_event,
10216 .init_hook = alc883_lenovo_101e_all_automute,
10217 },
272a527c
KY
10218 [ALC883_LENOVO_NB0763] = {
10219 .mixers = { alc883_lenovo_nb0763_mixer },
10220 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10221 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10222 .dac_nids = alc883_dac_nids,
272a527c
KY
10223 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10224 .channel_mode = alc883_3ST_2ch_modes,
10225 .need_dac_fix = 1,
10226 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 10227 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10228 .setup = alc883_medion_md2_setup,
10229 .init_hook = alc_automute_amp,
272a527c
KY
10230 },
10231 [ALC888_LENOVO_MS7195_DIG] = {
10232 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10233 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10234 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10235 .dac_nids = alc883_dac_nids,
10236 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10237 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10238 .channel_mode = alc883_3ST_6ch_modes,
10239 .need_dac_fix = 1,
10240 .input_mux = &alc883_capture_source,
10241 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10242 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
10243 },
10244 [ALC883_HAIER_W66] = {
c259249f 10245 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10246 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10247 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10248 .dac_nids = alc883_dac_nids,
10249 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10250 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10251 .channel_mode = alc883_3ST_2ch_modes,
10252 .input_mux = &alc883_capture_source,
a9fd4f3f 10253 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10254 .setup = alc883_haier_w66_setup,
10255 .init_hook = alc_automute_amp,
eea6419e 10256 },
4723c022 10257 [ALC888_3ST_HP] = {
eea6419e 10258 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10259 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10260 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10261 .dac_nids = alc883_dac_nids,
4723c022
CM
10262 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10263 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10264 .need_dac_fix = 1,
10265 .input_mux = &alc883_capture_source,
a9fd4f3f 10266 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10267 .setup = alc888_3st_hp_setup,
10268 .init_hook = alc_automute_amp,
8341de60 10269 },
5795b9e6 10270 [ALC888_6ST_DELL] = {
f24dbdc6 10271 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10272 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10273 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10274 .dac_nids = alc883_dac_nids,
10275 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10276 .dig_in_nid = ALC883_DIGIN_NID,
10277 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10278 .channel_mode = alc883_sixstack_modes,
10279 .input_mux = &alc883_capture_source,
a9fd4f3f 10280 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10281 .setup = alc888_6st_dell_setup,
10282 .init_hook = alc_automute_amp,
5795b9e6 10283 },
a8848bd6
AS
10284 [ALC883_MITAC] = {
10285 .mixers = { alc883_mitac_mixer },
10286 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10287 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10288 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10289 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10290 .channel_mode = alc883_3ST_2ch_modes,
10291 .input_mux = &alc883_capture_source,
a9fd4f3f 10292 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10293 .setup = alc883_mitac_setup,
10294 .init_hook = alc_automute_amp,
a8848bd6 10295 },
fb97dc67
J
10296 [ALC883_FUJITSU_PI2515] = {
10297 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10298 .init_verbs = { alc883_init_verbs,
10299 alc883_2ch_fujitsu_pi2515_verbs},
10300 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10301 .dac_nids = alc883_dac_nids,
10302 .dig_out_nid = ALC883_DIGOUT_NID,
10303 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10304 .channel_mode = alc883_3ST_2ch_modes,
10305 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10306 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10307 .setup = alc883_2ch_fujitsu_pi2515_setup,
10308 .init_hook = alc_automute_amp,
fb97dc67 10309 },
ef8ef5fb
VP
10310 [ALC888_FUJITSU_XA3530] = {
10311 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10312 .init_verbs = { alc883_init_verbs,
10313 alc888_fujitsu_xa3530_verbs },
10314 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10315 .dac_nids = alc883_dac_nids,
10316 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10317 .adc_nids = alc883_adc_nids_rev,
10318 .capsrc_nids = alc883_capsrc_nids_rev,
10319 .dig_out_nid = ALC883_DIGOUT_NID,
10320 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10321 .channel_mode = alc888_4ST_8ch_intel_modes,
10322 .num_mux_defs =
10323 ARRAY_SIZE(alc888_2_capture_sources),
10324 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10325 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10326 .setup = alc888_fujitsu_xa3530_setup,
10327 .init_hook = alc_automute_amp,
ef8ef5fb 10328 },
e2757d5e
KY
10329 [ALC888_LENOVO_SKY] = {
10330 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10331 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10332 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10333 .dac_nids = alc883_dac_nids,
10334 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10335 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10336 .channel_mode = alc883_sixstack_modes,
10337 .need_dac_fix = 1,
10338 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10339 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10340 .setup = alc888_lenovo_sky_setup,
10341 .init_hook = alc_automute_amp,
e2757d5e
KY
10342 },
10343 [ALC888_ASUS_M90V] = {
10344 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10345 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10346 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10347 .dac_nids = alc883_dac_nids,
10348 .dig_out_nid = ALC883_DIGOUT_NID,
10349 .dig_in_nid = ALC883_DIGIN_NID,
10350 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10351 .channel_mode = alc883_3ST_6ch_modes,
10352 .need_dac_fix = 1,
10353 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10354 .unsol_event = alc_sku_unsol_event,
10355 .setup = alc883_mode2_setup,
10356 .init_hook = alc_inithook,
e2757d5e
KY
10357 },
10358 [ALC888_ASUS_EEE1601] = {
10359 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10360 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10361 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10362 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10363 .dac_nids = alc883_dac_nids,
10364 .dig_out_nid = ALC883_DIGOUT_NID,
10365 .dig_in_nid = ALC883_DIGIN_NID,
10366 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10367 .channel_mode = alc883_3ST_2ch_modes,
10368 .need_dac_fix = 1,
10369 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10370 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10371 .init_hook = alc883_eee1601_inithook,
10372 },
3ab90935
WF
10373 [ALC1200_ASUS_P5Q] = {
10374 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10375 .init_verbs = { alc883_init_verbs },
10376 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10377 .dac_nids = alc883_dac_nids,
10378 .dig_out_nid = ALC1200_DIGOUT_NID,
10379 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10380 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10381 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10382 .channel_mode = alc883_sixstack_modes,
10383 .input_mux = &alc883_capture_source,
10384 },
eb4c41d3
TS
10385 [ALC889A_MB31] = {
10386 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10387 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10388 alc880_gpio1_init_verbs },
10389 .adc_nids = alc883_adc_nids,
10390 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10391 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10392 .dac_nids = alc883_dac_nids,
10393 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10394 .channel_mode = alc889A_mb31_6ch_modes,
10395 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10396 .input_mux = &alc889A_mb31_capture_source,
10397 .dig_out_nid = ALC883_DIGOUT_NID,
10398 .unsol_event = alc889A_mb31_unsol_event,
10399 .init_hook = alc889A_mb31_automute,
10400 },
3e1647c5
GG
10401 [ALC883_SONY_VAIO_TT] = {
10402 .mixers = { alc883_vaiott_mixer },
10403 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10404 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10405 .dac_nids = alc883_dac_nids,
10406 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10407 .channel_mode = alc883_3ST_2ch_modes,
10408 .input_mux = &alc883_capture_source,
10409 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10410 .setup = alc883_vaiott_setup,
10411 .init_hook = alc_automute_amp,
3e1647c5 10412 },
9c7f852e
TI
10413};
10414
10415
4953550a
TI
10416/*
10417 * Pin config fixes
10418 */
10419enum {
954a29c8
TI
10420 PINFIX_ABIT_AW9D_MAX,
10421 PINFIX_PB_M5210,
4953550a
TI
10422};
10423
10424static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
10425 { 0x15, 0x01080104 }, /* side */
10426 { 0x16, 0x01011012 }, /* rear */
10427 { 0x17, 0x01016011 }, /* clfe */
10428 { }
10429};
10430
954a29c8
TI
10431static const struct hda_verb pb_m5210_verbs[] = {
10432 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10433 {}
10434};
10435
f8f25ba3
TI
10436static const struct alc_fixup alc882_fixups[] = {
10437 [PINFIX_ABIT_AW9D_MAX] = {
10438 .pins = alc882_abit_aw9d_pinfix
10439 },
954a29c8
TI
10440 [PINFIX_PB_M5210] = {
10441 .verbs = pb_m5210_verbs
10442 },
4953550a
TI
10443};
10444
f8f25ba3 10445static struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10446 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
4953550a
TI
10447 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10448 {}
10449};
10450
9c7f852e
TI
10451/*
10452 * BIOS auto configuration
10453 */
05f5f477
TI
10454static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10455 const struct auto_pin_cfg *cfg)
10456{
10457 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10458}
10459
4953550a 10460static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10461 hda_nid_t nid, int pin_type,
489008cd 10462 hda_nid_t dac)
9c7f852e 10463{
f12ab1e0
TI
10464 int idx;
10465
489008cd 10466 /* set as output */
f6c7e546 10467 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10468
10469 if (dac == 0x25)
9c7f852e 10470 idx = 4;
489008cd
TI
10471 else if (dac >= 0x02 && dac <= 0x05)
10472 idx = dac - 2;
f9700d5a 10473 else
489008cd 10474 return;
9c7f852e 10475 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
10476}
10477
4953550a 10478static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10479{
10480 struct alc_spec *spec = codec->spec;
10481 int i;
10482
10483 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10484 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10485 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10486 if (nid)
4953550a 10487 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 10488 spec->multiout.dac_nids[i]);
9c7f852e
TI
10489 }
10490}
10491
4953550a 10492static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10493{
10494 struct alc_spec *spec = codec->spec;
489008cd 10495 hda_nid_t pin, dac;
9c7f852e 10496
eb06ed8f 10497 pin = spec->autocfg.hp_pins[0];
489008cd
TI
10498 if (pin) {
10499 dac = spec->multiout.hp_nid;
10500 if (!dac)
10501 dac = spec->multiout.dac_nids[0]; /* to front */
10502 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10503 }
f6c7e546 10504 pin = spec->autocfg.speaker_pins[0];
489008cd
TI
10505 if (pin) {
10506 dac = spec->multiout.extra_out_nid[0];
10507 if (!dac)
10508 dac = spec->multiout.dac_nids[0]; /* to front */
10509 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10510 }
9c7f852e
TI
10511}
10512
4953550a 10513static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10514{
10515 struct alc_spec *spec = codec->spec;
10516 int i;
10517
10518 for (i = 0; i < AUTO_PIN_LAST; i++) {
10519 hda_nid_t nid = spec->autocfg.input_pins[i];
4953550a
TI
10520 if (!nid)
10521 continue;
0d971c9f 10522 alc_set_input_pin(codec, nid, i);
4953550a
TI
10523 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10524 snd_hda_codec_write(codec, nid, 0,
10525 AC_VERB_SET_AMP_GAIN_MUTE,
10526 AMP_OUT_MUTE);
10527 }
10528}
10529
10530static void alc882_auto_init_input_src(struct hda_codec *codec)
10531{
10532 struct alc_spec *spec = codec->spec;
10533 int c;
10534
10535 for (c = 0; c < spec->num_adc_nids; c++) {
10536 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10537 hda_nid_t nid = spec->capsrc_nids[c];
10538 unsigned int mux_idx;
10539 const struct hda_input_mux *imux;
10540 int conns, mute, idx, item;
10541
10542 conns = snd_hda_get_connections(codec, nid, conn_list,
10543 ARRAY_SIZE(conn_list));
10544 if (conns < 0)
10545 continue;
10546 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10547 imux = &spec->input_mux[mux_idx];
5311114d
TI
10548 if (!imux->num_items && mux_idx > 0)
10549 imux = &spec->input_mux[0];
4953550a
TI
10550 for (idx = 0; idx < conns; idx++) {
10551 /* if the current connection is the selected one,
10552 * unmute it as default - otherwise mute it
10553 */
10554 mute = AMP_IN_MUTE(idx);
10555 for (item = 0; item < imux->num_items; item++) {
10556 if (imux->items[item].index == idx) {
10557 if (spec->cur_mux[c] == item)
10558 mute = AMP_IN_UNMUTE(idx);
10559 break;
10560 }
10561 }
10562 /* check if we have a selector or mixer
10563 * we could check for the widget type instead, but
10564 * just check for Amp-In presence (in case of mixer
10565 * without amp-in there is something wrong, this
10566 * function shouldn't be used or capsrc nid is wrong)
10567 */
10568 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10569 snd_hda_codec_write(codec, nid, 0,
10570 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10571 mute);
10572 else if (mute != AMP_IN_MUTE(idx))
10573 snd_hda_codec_write(codec, nid, 0,
10574 AC_VERB_SET_CONNECT_SEL,
10575 idx);
9c7f852e
TI
10576 }
10577 }
10578}
10579
4953550a
TI
10580/* add mic boosts if needed */
10581static int alc_auto_add_mic_boost(struct hda_codec *codec)
10582{
10583 struct alc_spec *spec = codec->spec;
10584 int err;
10585 hda_nid_t nid;
10586
10587 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
10588 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10589 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10590 "Mic Boost",
10591 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10592 if (err < 0)
10593 return err;
10594 }
10595 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
10596 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10597 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10598 "Front Mic Boost",
10599 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10600 if (err < 0)
10601 return err;
10602 }
10603 return 0;
10604}
f511b01c 10605
9c7f852e 10606/* almost identical with ALC880 parser... */
4953550a 10607static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10608{
10609 struct alc_spec *spec = codec->spec;
05f5f477 10610 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 10611 int err;
9c7f852e 10612
05f5f477
TI
10613 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10614 alc882_ignore);
9c7f852e
TI
10615 if (err < 0)
10616 return err;
05f5f477
TI
10617 if (!spec->autocfg.line_outs)
10618 return 0; /* can't find valid BIOS pin config */
776e184e 10619
05f5f477
TI
10620 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10621 if (err < 0)
10622 return err;
10623 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
10624 if (err < 0)
10625 return err;
10626 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10627 "Headphone");
05f5f477
TI
10628 if (err < 0)
10629 return err;
10630 err = alc880_auto_create_extra_out(spec,
10631 spec->autocfg.speaker_pins[0],
10632 "Speaker");
10633 if (err < 0)
10634 return err;
05f5f477 10635 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10636 if (err < 0)
10637 return err;
10638
05f5f477
TI
10639 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10640
757899ac 10641 alc_auto_parse_digital(codec);
05f5f477
TI
10642
10643 if (spec->kctls.list)
10644 add_mixer(spec, spec->kctls.list);
10645
10646 add_verb(spec, alc883_auto_init_verbs);
4953550a 10647 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10648 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10649 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10650
05f5f477
TI
10651 spec->num_mux_defs = 1;
10652 spec->input_mux = &spec->private_imux[0];
10653
6227cdce 10654 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10655
10656 err = alc_auto_add_mic_boost(codec);
10657 if (err < 0)
10658 return err;
61b9b9b1 10659
776e184e 10660 return 1; /* config found */
9c7f852e
TI
10661}
10662
10663/* additional initialization for auto-configuration model */
4953550a 10664static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10665{
f6c7e546 10666 struct alc_spec *spec = codec->spec;
4953550a
TI
10667 alc882_auto_init_multi_out(codec);
10668 alc882_auto_init_hp_out(codec);
10669 alc882_auto_init_analog_input(codec);
10670 alc882_auto_init_input_src(codec);
757899ac 10671 alc_auto_init_digital(codec);
f6c7e546 10672 if (spec->unsol_event)
7fb0d78f 10673 alc_inithook(codec);
9c7f852e
TI
10674}
10675
4953550a 10676static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10677{
10678 struct alc_spec *spec;
10679 int err, board_config;
10680
10681 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10682 if (spec == NULL)
10683 return -ENOMEM;
10684
10685 codec->spec = spec;
10686
da00c244
KY
10687 alc_auto_parse_customize_define(codec);
10688
4953550a
TI
10689 switch (codec->vendor_id) {
10690 case 0x10ec0882:
10691 case 0x10ec0885:
10692 break;
10693 default:
10694 /* ALC883 and variants */
10695 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10696 break;
10697 }
2c3bf9ab 10698
4953550a
TI
10699 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10700 alc882_models,
10701 alc882_cfg_tbl);
10702
10703 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10704 board_config = snd_hda_check_board_codec_sid_config(codec,
10705 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10706
10707 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 10708 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
10709 codec->chip_name);
10710 board_config = ALC882_AUTO;
9c7f852e
TI
10711 }
10712
7fa90e87
TI
10713 if (board_config == ALC882_AUTO)
10714 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
4953550a
TI
10715
10716 if (board_config == ALC882_AUTO) {
9c7f852e 10717 /* automatic parse from the BIOS config */
4953550a 10718 err = alc882_parse_auto_config(codec);
9c7f852e
TI
10719 if (err < 0) {
10720 alc_free(codec);
10721 return err;
f12ab1e0 10722 } else if (!err) {
9c7f852e
TI
10723 printk(KERN_INFO
10724 "hda_codec: Cannot set up configuration "
10725 "from BIOS. Using base mode...\n");
4953550a 10726 board_config = ALC882_3ST_DIG;
9c7f852e
TI
10727 }
10728 }
10729
dc1eae25 10730 if (has_cdefine_beep(codec)) {
8af2591d
TI
10731 err = snd_hda_attach_beep_device(codec, 0x1);
10732 if (err < 0) {
10733 alc_free(codec);
10734 return err;
10735 }
680cd536
KK
10736 }
10737
4953550a 10738 if (board_config != ALC882_AUTO)
e9c364c0 10739 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 10740
4953550a
TI
10741 spec->stream_analog_playback = &alc882_pcm_analog_playback;
10742 spec->stream_analog_capture = &alc882_pcm_analog_capture;
10743 /* FIXME: setup DAC5 */
10744 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
10745 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
10746
10747 spec->stream_digital_playback = &alc882_pcm_digital_playback;
10748 spec->stream_digital_capture = &alc882_pcm_digital_capture;
10749
4953550a 10750 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 10751 int i, j;
4953550a
TI
10752 spec->num_adc_nids = 0;
10753 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 10754 const struct hda_input_mux *imux = spec->input_mux;
4953550a 10755 hda_nid_t cap;
d11f74c6 10756 hda_nid_t items[16];
4953550a
TI
10757 hda_nid_t nid = alc882_adc_nids[i];
10758 unsigned int wcap = get_wcaps(codec, nid);
10759 /* get type */
a22d543a 10760 wcap = get_wcaps_type(wcap);
4953550a
TI
10761 if (wcap != AC_WID_AUD_IN)
10762 continue;
10763 spec->private_adc_nids[spec->num_adc_nids] = nid;
10764 err = snd_hda_get_connections(codec, nid, &cap, 1);
10765 if (err < 0)
10766 continue;
d11f74c6
TI
10767 err = snd_hda_get_connections(codec, cap, items,
10768 ARRAY_SIZE(items));
10769 if (err < 0)
10770 continue;
10771 for (j = 0; j < imux->num_items; j++)
10772 if (imux->items[j].index >= err)
10773 break;
10774 if (j < imux->num_items)
10775 continue;
4953550a
TI
10776 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
10777 spec->num_adc_nids++;
61b9b9b1 10778 }
4953550a
TI
10779 spec->adc_nids = spec->private_adc_nids;
10780 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
10781 }
10782
b59bdf3b 10783 set_capture_mixer(codec);
da00c244 10784
dc1eae25 10785 if (has_cdefine_beep(codec))
da00c244 10786 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 10787
7fa90e87
TI
10788 if (board_config == ALC882_AUTO)
10789 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
10790
2134ea4f
TI
10791 spec->vmaster_nid = 0x0c;
10792
9c7f852e 10793 codec->patch_ops = alc_patch_ops;
4953550a
TI
10794 if (board_config == ALC882_AUTO)
10795 spec->init_hook = alc882_auto_init;
cb53c626
TI
10796#ifdef CONFIG_SND_HDA_POWER_SAVE
10797 if (!spec->loopback.amplist)
4953550a 10798 spec->loopback.amplist = alc882_loopbacks;
cb53c626 10799#endif
9c7f852e
TI
10800
10801 return 0;
10802}
10803
4953550a 10804
9c7f852e
TI
10805/*
10806 * ALC262 support
10807 */
10808
10809#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
10810#define ALC262_DIGIN_NID ALC880_DIGIN_NID
10811
10812#define alc262_dac_nids alc260_dac_nids
10813#define alc262_adc_nids alc882_adc_nids
10814#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
10815#define alc262_capsrc_nids alc882_capsrc_nids
10816#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
10817
10818#define alc262_modes alc260_modes
10819#define alc262_capture_source alc882_capture_source
10820
4e555fe5
KY
10821static hda_nid_t alc262_dmic_adc_nids[1] = {
10822 /* ADC0 */
10823 0x09
10824};
10825
10826static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
10827
9c7f852e
TI
10828static struct snd_kcontrol_new alc262_base_mixer[] = {
10829 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10830 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10831 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10832 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10833 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10834 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10835 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10836 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10837 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
10838 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10839 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 10840 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
10841 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
10842 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10843 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
10844 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10845 { } /* end */
10846};
10847
ce875f07
TI
10848/* update HP, line and mono-out pins according to the master switch */
10849static void alc262_hp_master_update(struct hda_codec *codec)
10850{
10851 struct alc_spec *spec = codec->spec;
10852 int val = spec->master_sw;
10853
10854 /* HP & line-out */
10855 snd_hda_codec_write_cache(codec, 0x1b, 0,
10856 AC_VERB_SET_PIN_WIDGET_CONTROL,
10857 val ? PIN_HP : 0);
10858 snd_hda_codec_write_cache(codec, 0x15, 0,
10859 AC_VERB_SET_PIN_WIDGET_CONTROL,
10860 val ? PIN_HP : 0);
10861 /* mono (speaker) depending on the HP jack sense */
10862 val = val && !spec->jack_present;
10863 snd_hda_codec_write_cache(codec, 0x16, 0,
10864 AC_VERB_SET_PIN_WIDGET_CONTROL,
10865 val ? PIN_OUT : 0);
10866}
10867
10868static void alc262_hp_bpc_automute(struct hda_codec *codec)
10869{
10870 struct alc_spec *spec = codec->spec;
864f92be
WF
10871
10872 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
10873 alc262_hp_master_update(codec);
10874}
10875
10876static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
10877{
10878 if ((res >> 26) != ALC880_HP_EVENT)
10879 return;
10880 alc262_hp_bpc_automute(codec);
10881}
10882
10883static void alc262_hp_wildwest_automute(struct hda_codec *codec)
10884{
10885 struct alc_spec *spec = codec->spec;
864f92be
WF
10886
10887 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
10888 alc262_hp_master_update(codec);
10889}
10890
10891static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
10892 unsigned int res)
10893{
10894 if ((res >> 26) != ALC880_HP_EVENT)
10895 return;
10896 alc262_hp_wildwest_automute(codec);
10897}
10898
b72519b5 10899#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
10900
10901static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10902 struct snd_ctl_elem_value *ucontrol)
10903{
10904 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10905 struct alc_spec *spec = codec->spec;
10906 int val = !!*ucontrol->value.integer.value;
10907
10908 if (val == spec->master_sw)
10909 return 0;
10910 spec->master_sw = val;
10911 alc262_hp_master_update(codec);
10912 return 1;
10913}
10914
b72519b5
TI
10915#define ALC262_HP_MASTER_SWITCH \
10916 { \
10917 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10918 .name = "Master Playback Switch", \
10919 .info = snd_ctl_boolean_mono_info, \
10920 .get = alc262_hp_master_sw_get, \
10921 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
10922 }, \
10923 { \
10924 .iface = NID_MAPPING, \
10925 .name = "Master Playback Switch", \
10926 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
10927 }
10928
5b0cb1d8 10929
9c7f852e 10930static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 10931 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
10932 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10933 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10934 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
10935 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10936 HDA_OUTPUT),
10937 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10938 HDA_OUTPUT),
9c7f852e
TI
10939 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10940 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10941 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
10942 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10943 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 10944 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
10945 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10946 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10947 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10948 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
10949 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
10950 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
10951 { } /* end */
10952};
10953
cd7509a4 10954static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 10955 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
10956 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10957 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10958 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10959 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
10960 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10961 HDA_OUTPUT),
10962 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10963 HDA_OUTPUT),
cd7509a4
KY
10964 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
10965 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 10966 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
10967 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10968 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10969 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10970 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
10971 { } /* end */
10972};
10973
10974static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
10975 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10976 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10977 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
10978 { } /* end */
10979};
10980
66d2a9d6 10981/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 10982static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
10983{
10984 struct alc_spec *spec = codec->spec;
66d2a9d6 10985
a9fd4f3f 10986 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 10987 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
10988}
10989
66d2a9d6 10990static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
10991 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10992 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
10993 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10994 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10997 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10998 { } /* end */
10999};
11000
11001static struct hda_verb alc262_hp_t5735_verbs[] = {
11002 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11003 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11004
11005 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11006 { }
11007};
11008
8c427226 11009static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11010 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11011 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11012 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11013 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11014 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11015 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11016 { } /* end */
11017};
11018
11019static struct hda_verb alc262_hp_rp5700_verbs[] = {
11020 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11021 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11022 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11023 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11024 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11025 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11026 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11027 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11028 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11029 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11030 {}
11031};
11032
11033static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11034 .num_items = 1,
11035 .items = {
11036 { "Line", 0x1 },
11037 },
11038};
11039
42171c17
TI
11040/* bind hp and internal speaker mute (with plug check) as master switch */
11041static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 11042{
42171c17
TI
11043 struct alc_spec *spec = codec->spec;
11044 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11045 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11046 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11047 unsigned int mute;
0724ea2a 11048
42171c17
TI
11049 /* HP */
11050 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11051 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11052 HDA_AMP_MUTE, mute);
11053 /* mute internal speaker per jack sense */
11054 if (spec->jack_present)
11055 mute = HDA_AMP_MUTE;
11056 if (line_nid)
11057 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11058 HDA_AMP_MUTE, mute);
11059 if (speaker_nid && speaker_nid != line_nid)
11060 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 11061 HDA_AMP_MUTE, mute);
42171c17
TI
11062}
11063
11064#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11065
11066static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11067 struct snd_ctl_elem_value *ucontrol)
11068{
11069 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11070 struct alc_spec *spec = codec->spec;
11071 int val = !!*ucontrol->value.integer.value;
11072
11073 if (val == spec->master_sw)
11074 return 0;
11075 spec->master_sw = val;
11076 alc262_hippo_master_update(codec);
11077 return 1;
11078}
11079
11080#define ALC262_HIPPO_MASTER_SWITCH \
11081 { \
11082 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11083 .name = "Master Playback Switch", \
11084 .info = snd_ctl_boolean_mono_info, \
11085 .get = alc262_hippo_master_sw_get, \
11086 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11087 }, \
11088 { \
11089 .iface = NID_MAPPING, \
11090 .name = "Master Playback Switch", \
11091 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11092 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11093 }
42171c17
TI
11094
11095static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11096 ALC262_HIPPO_MASTER_SWITCH,
11097 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11098 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11099 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11100 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11101 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11102 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11103 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11104 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11105 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11106 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11107 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11108 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11109 { } /* end */
11110};
11111
11112static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11113 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11114 ALC262_HIPPO_MASTER_SWITCH,
11115 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11116 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11117 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11118 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11119 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11120 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11121 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11122 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11123 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11124 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11125 { } /* end */
11126};
11127
11128/* mute/unmute internal speaker according to the hp jack and mute state */
11129static void alc262_hippo_automute(struct hda_codec *codec)
11130{
11131 struct alc_spec *spec = codec->spec;
11132 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 11133
864f92be 11134 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 11135 alc262_hippo_master_update(codec);
0724ea2a 11136}
5b31954e 11137
42171c17
TI
11138static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11139{
11140 if ((res >> 26) != ALC880_HP_EVENT)
11141 return;
11142 alc262_hippo_automute(codec);
11143}
11144
4f5d1706 11145static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11146{
11147 struct alc_spec *spec = codec->spec;
11148
11149 spec->autocfg.hp_pins[0] = 0x15;
11150 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11151}
11152
4f5d1706 11153static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11154{
11155 struct alc_spec *spec = codec->spec;
11156
11157 spec->autocfg.hp_pins[0] = 0x1b;
11158 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11159}
11160
11161
272a527c 11162static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11163 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11164 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11165 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11166 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11167 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11168 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11169 { } /* end */
11170};
11171
83c34218 11172static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11173 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11174 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11175 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11176 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11177 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11178 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11179 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11180 { } /* end */
11181};
272a527c 11182
ba340e82
TV
11183static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11184 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11185 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11186 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11187 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11188 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11189 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11190 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11191 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11192 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11193 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11194 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11195 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11196 { } /* end */
11197};
11198
11199static struct hda_verb alc262_tyan_verbs[] = {
11200 /* Headphone automute */
11201 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11202 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11203 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11204
11205 /* P11 AUX_IN, white 4-pin connector */
11206 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11207 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11208 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11209 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11210
11211 {}
11212};
11213
11214/* unsolicited event for HP jack sensing */
4f5d1706 11215static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11216{
a9fd4f3f 11217 struct alc_spec *spec = codec->spec;
ba340e82 11218
a9fd4f3f
TI
11219 spec->autocfg.hp_pins[0] = 0x1b;
11220 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
11221}
11222
ba340e82 11223
9c7f852e
TI
11224#define alc262_capture_mixer alc882_capture_mixer
11225#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11226
11227/*
11228 * generic initialization of ADC, input mixers and output mixers
11229 */
11230static struct hda_verb alc262_init_verbs[] = {
11231 /*
11232 * Unmute ADC0-2 and set the default input to mic-in
11233 */
11234 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11235 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11236 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11237 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11238 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11239 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11240
cb53c626 11241 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11242 * mixer widget
f12ab1e0
TI
11243 * Note: PASD motherboards uses the Line In 2 as the input for
11244 * front panel mic (mic 2)
9c7f852e
TI
11245 */
11246 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11247 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11248 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11249 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11250 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11251 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11252
11253 /*
df694daa
KY
11254 * Set up output mixers (0x0c - 0x0e)
11255 */
11256 /* set vol=0 to output mixers */
11257 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11258 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11259 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11260 /* set up input amps for analog loopback */
11261 /* Amp Indices: DAC = 0, mixer = 1 */
11262 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11263 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11264 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11265 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11266 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11267 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11268
11269 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11270 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11271 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11272 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11273 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11274 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11275
11276 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11277 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11278 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11279 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11280 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11281
df694daa
KY
11282 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11283 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11284
df694daa
KY
11285 /* FIXME: use matrix-type input source selection */
11286 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11287 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11288 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11289 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11290 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11291 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11292 /* Input mixer2 */
11293 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11294 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11295 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11296 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11297 /* Input mixer3 */
11298 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11299 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11300 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11301 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11302
11303 { }
11304};
1da177e4 11305
4e555fe5
KY
11306static struct hda_verb alc262_eapd_verbs[] = {
11307 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11308 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11309 { }
11310};
11311
ccc656ce
KY
11312static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11313 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11314 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11315 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11316
11317 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11318 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11319 {}
11320};
11321
272a527c
KY
11322static struct hda_verb alc262_sony_unsol_verbs[] = {
11323 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11324 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11325 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11326
11327 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11328 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11329 {}
272a527c
KY
11330};
11331
4e555fe5
KY
11332static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11333 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11334 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11335 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11336 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11337 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11338 { } /* end */
11339};
11340
11341static struct hda_verb alc262_toshiba_s06_verbs[] = {
11342 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11343 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11344 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11345 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11346 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11347 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11348 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11349 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11350 {}
11351};
11352
4f5d1706 11353static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11354{
a9fd4f3f
TI
11355 struct alc_spec *spec = codec->spec;
11356
11357 spec->autocfg.hp_pins[0] = 0x15;
11358 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11359 spec->ext_mic.pin = 0x18;
11360 spec->ext_mic.mux_idx = 0;
11361 spec->int_mic.pin = 0x12;
11362 spec->int_mic.mux_idx = 9;
11363 spec->auto_mic = 1;
4e555fe5
KY
11364}
11365
e8f9ae2a
PT
11366/*
11367 * nec model
11368 * 0x15 = headphone
11369 * 0x16 = internal speaker
11370 * 0x18 = external mic
11371 */
11372
11373static struct snd_kcontrol_new alc262_nec_mixer[] = {
11374 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11375 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11376
11377 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11378 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11379 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11380
11381 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11382 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11383 { } /* end */
11384};
11385
11386static struct hda_verb alc262_nec_verbs[] = {
11387 /* Unmute Speaker */
11388 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11389
11390 /* Headphone */
11391 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11392 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11393
11394 /* External mic to headphone */
11395 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11396 /* External mic to speaker */
11397 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11398 {}
11399};
11400
834be88d
TI
11401/*
11402 * fujitsu model
5d9fab2d
TV
11403 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11404 * 0x1b = port replicator headphone out
834be88d
TI
11405 */
11406
11407#define ALC_HP_EVENT 0x37
11408
11409static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11410 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11411 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11412 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11413 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11414 {}
11415};
11416
0e31daf7
J
11417static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11418 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11419 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11420 {}
11421};
11422
e2595322
DC
11423static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11424 /* Front Mic pin: input vref at 50% */
11425 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11426 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11427 {}
11428};
11429
834be88d 11430static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11431 .num_items = 3,
834be88d
TI
11432 .items = {
11433 { "Mic", 0x0 },
39d3ed38 11434 { "Int Mic", 0x1 },
834be88d
TI
11435 { "CD", 0x4 },
11436 },
11437};
11438
9c7f852e
TI
11439static struct hda_input_mux alc262_HP_capture_source = {
11440 .num_items = 5,
11441 .items = {
11442 { "Mic", 0x0 },
accbe498 11443 { "Front Mic", 0x1 },
9c7f852e
TI
11444 { "Line", 0x2 },
11445 { "CD", 0x4 },
11446 { "AUX IN", 0x6 },
11447 },
11448};
11449
accbe498 11450static struct hda_input_mux alc262_HP_D7000_capture_source = {
11451 .num_items = 4,
11452 .items = {
11453 { "Mic", 0x0 },
11454 { "Front Mic", 0x2 },
11455 { "Line", 0x1 },
11456 { "CD", 0x4 },
11457 },
11458};
11459
ebc7a406 11460/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11461static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11462{
11463 struct alc_spec *spec = codec->spec;
11464 unsigned int mute;
11465
f12ab1e0 11466 if (force || !spec->sense_updated) {
864f92be
WF
11467 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11468 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11469 spec->sense_updated = 1;
11470 }
ebc7a406
TI
11471 /* unmute internal speaker only if both HPs are unplugged and
11472 * master switch is on
11473 */
11474 if (spec->jack_present)
11475 mute = HDA_AMP_MUTE;
11476 else
834be88d 11477 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11478 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11479 HDA_AMP_MUTE, mute);
834be88d
TI
11480}
11481
11482/* unsolicited event for HP jack sensing */
11483static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11484 unsigned int res)
11485{
11486 if ((res >> 26) != ALC_HP_EVENT)
11487 return;
11488 alc262_fujitsu_automute(codec, 1);
11489}
11490
ebc7a406
TI
11491static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11492{
11493 alc262_fujitsu_automute(codec, 1);
11494}
11495
834be88d 11496/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11497static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11498 .ops = &snd_hda_bind_vol,
11499 .values = {
11500 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11501 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11502 0
11503 },
11504};
834be88d 11505
0e31daf7
J
11506/* mute/unmute internal speaker according to the hp jack and mute state */
11507static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11508{
11509 struct alc_spec *spec = codec->spec;
11510 unsigned int mute;
11511
11512 if (force || !spec->sense_updated) {
864f92be 11513 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11514 spec->sense_updated = 1;
11515 }
11516 if (spec->jack_present) {
11517 /* mute internal speaker */
11518 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11519 HDA_AMP_MUTE, HDA_AMP_MUTE);
11520 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11521 HDA_AMP_MUTE, HDA_AMP_MUTE);
11522 } else {
11523 /* unmute internal speaker if necessary */
11524 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11525 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11526 HDA_AMP_MUTE, mute);
11527 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11528 HDA_AMP_MUTE, mute);
11529 }
11530}
11531
11532/* unsolicited event for HP jack sensing */
11533static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11534 unsigned int res)
11535{
11536 if ((res >> 26) != ALC_HP_EVENT)
11537 return;
11538 alc262_lenovo_3000_automute(codec, 1);
11539}
11540
8de56b7d
TI
11541static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11542 int dir, int idx, long *valp)
11543{
11544 int i, change = 0;
11545
11546 for (i = 0; i < 2; i++, valp++)
11547 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11548 HDA_AMP_MUTE,
11549 *valp ? 0 : HDA_AMP_MUTE);
11550 return change;
11551}
11552
834be88d
TI
11553/* bind hp and internal speaker mute (with plug check) */
11554static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11555 struct snd_ctl_elem_value *ucontrol)
11556{
11557 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11558 long *valp = ucontrol->value.integer.value;
11559 int change;
11560
8de56b7d
TI
11561 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11562 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11563 if (change)
11564 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11565 return change;
11566}
11567
11568static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11569 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11570 {
11571 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11572 .name = "Master Playback Switch",
5e26dfd0 11573 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11574 .info = snd_hda_mixer_amp_switch_info,
11575 .get = snd_hda_mixer_amp_switch_get,
11576 .put = alc262_fujitsu_master_sw_put,
11577 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11578 },
5b0cb1d8
JK
11579 {
11580 .iface = NID_MAPPING,
11581 .name = "Master Playback Switch",
11582 .private_value = 0x1b,
11583 },
834be88d
TI
11584 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11585 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11586 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11587 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11588 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
11589 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11590 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11591 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11592 { } /* end */
11593};
11594
0e31daf7
J
11595/* bind hp and internal speaker mute (with plug check) */
11596static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11597 struct snd_ctl_elem_value *ucontrol)
11598{
11599 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11600 long *valp = ucontrol->value.integer.value;
11601 int change;
11602
8de56b7d 11603 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11604 if (change)
11605 alc262_lenovo_3000_automute(codec, 0);
11606 return change;
11607}
11608
11609static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11610 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11611 {
11612 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11613 .name = "Master Playback Switch",
5e26dfd0 11614 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11615 .info = snd_hda_mixer_amp_switch_info,
11616 .get = snd_hda_mixer_amp_switch_get,
11617 .put = alc262_lenovo_3000_master_sw_put,
11618 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11619 },
11620 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11621 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11622 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11623 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11624 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11625 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11626 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11627 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11628 { } /* end */
11629};
11630
9f99a638
HM
11631static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11632 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11633 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11634 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11635 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11636 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11637 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11638 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11639 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11640 { } /* end */
11641};
11642
304dcaac
TI
11643/* additional init verbs for Benq laptops */
11644static struct hda_verb alc262_EAPD_verbs[] = {
11645 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11646 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11647 {}
11648};
11649
83c34218
KY
11650static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11651 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11652 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11653
11654 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11655 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11656 {}
11657};
11658
f651b50b
TD
11659/* Samsung Q1 Ultra Vista model setup */
11660static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11661 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11662 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11663 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11664 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11665 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 11666 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
11667 { } /* end */
11668};
11669
11670static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11671 /* output mixer */
11672 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11673 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11674 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11675 /* speaker */
11676 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11677 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11678 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11679 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11680 /* HP */
f651b50b 11681 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11682 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11683 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11684 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11685 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11686 /* internal mic */
11687 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11688 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11689 /* ADC, choose mic */
11690 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11691 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11692 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11693 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11694 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11695 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11696 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11697 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11698 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11699 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
11700 {}
11701};
11702
f651b50b
TD
11703/* mute/unmute internal speaker according to the hp jack and mute state */
11704static void alc262_ultra_automute(struct hda_codec *codec)
11705{
11706 struct alc_spec *spec = codec->spec;
11707 unsigned int mute;
f651b50b 11708
bb9f76cd
TI
11709 mute = 0;
11710 /* auto-mute only when HP is used as HP */
11711 if (!spec->cur_mux[0]) {
864f92be 11712 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
11713 if (spec->jack_present)
11714 mute = HDA_AMP_MUTE;
f651b50b 11715 }
bb9f76cd
TI
11716 /* mute/unmute internal speaker */
11717 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11718 HDA_AMP_MUTE, mute);
11719 /* mute/unmute HP */
11720 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11721 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
11722}
11723
11724/* unsolicited event for HP jack sensing */
11725static void alc262_ultra_unsol_event(struct hda_codec *codec,
11726 unsigned int res)
11727{
11728 if ((res >> 26) != ALC880_HP_EVENT)
11729 return;
11730 alc262_ultra_automute(codec);
11731}
11732
bb9f76cd
TI
11733static struct hda_input_mux alc262_ultra_capture_source = {
11734 .num_items = 2,
11735 .items = {
11736 { "Mic", 0x1 },
11737 { "Headphone", 0x7 },
11738 },
11739};
11740
11741static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11742 struct snd_ctl_elem_value *ucontrol)
11743{
11744 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11745 struct alc_spec *spec = codec->spec;
11746 int ret;
11747
54cbc9ab 11748 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
11749 if (!ret)
11750 return 0;
11751 /* reprogram the HP pin as mic or HP according to the input source */
11752 snd_hda_codec_write_cache(codec, 0x15, 0,
11753 AC_VERB_SET_PIN_WIDGET_CONTROL,
11754 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11755 alc262_ultra_automute(codec); /* mute/unmute HP */
11756 return ret;
11757}
11758
11759static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11760 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11761 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11762 {
11763 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11764 .name = "Capture Source",
54cbc9ab
TI
11765 .info = alc_mux_enum_info,
11766 .get = alc_mux_enum_get,
bb9f76cd
TI
11767 .put = alc262_ultra_mux_enum_put,
11768 },
5b0cb1d8
JK
11769 {
11770 .iface = NID_MAPPING,
11771 .name = "Capture Source",
11772 .private_value = 0x15,
11773 },
bb9f76cd
TI
11774 { } /* end */
11775};
11776
c3fc1f50
TI
11777/* We use two mixers depending on the output pin; 0x16 is a mono output
11778 * and thus it's bound with a different mixer.
11779 * This function returns which mixer amp should be used.
11780 */
11781static int alc262_check_volbit(hda_nid_t nid)
11782{
11783 if (!nid)
11784 return 0;
11785 else if (nid == 0x16)
11786 return 2;
11787 else
11788 return 1;
11789}
11790
11791static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
11792 const char *pfx, int *vbits)
11793{
c3fc1f50
TI
11794 unsigned long val;
11795 int vbit;
11796
11797 vbit = alc262_check_volbit(nid);
11798 if (!vbit)
11799 return 0;
11800 if (*vbits & vbit) /* a volume control for this mixer already there */
11801 return 0;
11802 *vbits |= vbit;
c3fc1f50
TI
11803 if (vbit == 2)
11804 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11805 else
11806 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
0afe5f89 11807 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val);
c3fc1f50
TI
11808}
11809
11810static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
11811 const char *pfx)
11812{
c3fc1f50
TI
11813 unsigned long val;
11814
11815 if (!nid)
11816 return 0;
c3fc1f50
TI
11817 if (nid == 0x16)
11818 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11819 else
11820 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
0afe5f89 11821 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
c3fc1f50
TI
11822}
11823
df694daa 11824/* add playback controls from the parsed DAC table */
f12ab1e0
TI
11825static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11826 const struct auto_pin_cfg *cfg)
df694daa 11827{
c3fc1f50
TI
11828 const char *pfx;
11829 int vbits;
df694daa
KY
11830 int err;
11831
11832 spec->multiout.num_dacs = 1; /* only use one dac */
11833 spec->multiout.dac_nids = spec->private_dac_nids;
11834 spec->multiout.dac_nids[0] = 2;
11835
c3fc1f50
TI
11836 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
11837 pfx = "Master";
11838 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11839 pfx = "Speaker";
11840 else
11841 pfx = "Front";
11842 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx);
11843 if (err < 0)
11844 return err;
11845 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker");
11846 if (err < 0)
11847 return err;
11848 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone");
11849 if (err < 0)
11850 return err;
df694daa 11851
c3fc1f50
TI
11852 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
11853 alc262_check_volbit(cfg->speaker_pins[0]) |
11854 alc262_check_volbit(cfg->hp_pins[0]);
11855 if (vbits == 1 || vbits == 2)
11856 pfx = "Master"; /* only one mixer is used */
11857 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11858 pfx = "Speaker";
11859 else
11860 pfx = "Front";
11861 vbits = 0;
11862 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits);
11863 if (err < 0)
11864 return err;
11865 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker",
11866 &vbits);
11867 if (err < 0)
11868 return err;
11869 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone",
11870 &vbits);
11871 if (err < 0)
11872 return err;
f12ab1e0 11873 return 0;
df694daa
KY
11874}
11875
05f5f477 11876#define alc262_auto_create_input_ctls \
eaa9b3a7 11877 alc882_auto_create_input_ctls
df694daa
KY
11878
11879/*
11880 * generic initialization of ADC, input mixers and output mixers
11881 */
11882static struct hda_verb alc262_volume_init_verbs[] = {
11883 /*
11884 * Unmute ADC0-2 and set the default input to mic-in
11885 */
11886 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11887 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11888 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11889 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11890 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11891 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11892
cb53c626 11893 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 11894 * mixer widget
f12ab1e0
TI
11895 * Note: PASD motherboards uses the Line In 2 as the input for
11896 * front panel mic (mic 2)
df694daa
KY
11897 */
11898 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11899 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11900 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11901 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11902 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11903 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
11904
11905 /*
11906 * Set up output mixers (0x0c - 0x0f)
11907 */
11908 /* set vol=0 to output mixers */
11909 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11910 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11911 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 11912
df694daa
KY
11913 /* set up input amps for analog loopback */
11914 /* Amp Indices: DAC = 0, mixer = 1 */
11915 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11916 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11917 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11918 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11919 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11920 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11921
11922 /* FIXME: use matrix-type input source selection */
11923 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11924 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11925 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11926 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11927 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11928 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11929 /* Input mixer2 */
11930 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11931 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11932 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11933 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11934 /* Input mixer3 */
11935 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11936 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11937 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11938 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11939
11940 { }
11941};
11942
9c7f852e
TI
11943static struct hda_verb alc262_HP_BPC_init_verbs[] = {
11944 /*
11945 * Unmute ADC0-2 and set the default input to mic-in
11946 */
11947 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11948 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11949 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11950 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11951 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11952 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11953
cb53c626 11954 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11955 * mixer widget
f12ab1e0
TI
11956 * Note: PASD motherboards uses the Line In 2 as the input for
11957 * front panel mic (mic 2)
9c7f852e
TI
11958 */
11959 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11960 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11961 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11962 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11963 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11964 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11965 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11966 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 11967
9c7f852e
TI
11968 /*
11969 * Set up output mixers (0x0c - 0x0e)
11970 */
11971 /* set vol=0 to output mixers */
11972 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11973 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11974 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11975
11976 /* set up input amps for analog loopback */
11977 /* Amp Indices: DAC = 0, mixer = 1 */
11978 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11979 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11980 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11981 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11982 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11983 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11984
ce875f07 11985 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
11986 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11987 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11988
11989 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11990 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11991
11992 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11993 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11994
11995 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11996 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11997 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11998 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11999 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12000
0e4835c1 12001 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12002 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12003 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12004 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12005 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12006 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12007
12008
12009 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12010 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12011 /* Input mixer1: only unmute Mic */
9c7f852e 12012 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12013 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12014 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12015 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12016 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12017 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12018 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12019 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12020 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12021 /* Input mixer2 */
12022 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12023 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12024 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12025 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12026 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12027 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12028 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12029 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12030 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12031 /* Input mixer3 */
12032 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12033 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12034 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12035 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12036 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12037 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12038 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12039 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12040 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12041
ce875f07
TI
12042 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12043
9c7f852e
TI
12044 { }
12045};
12046
cd7509a4
KY
12047static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12048 /*
12049 * Unmute ADC0-2 and set the default input to mic-in
12050 */
12051 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12052 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12053 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12054 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12055 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12056 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12057
cb53c626 12058 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12059 * mixer widget
12060 * Note: PASD motherboards uses the Line In 2 as the input for front
12061 * panel mic (mic 2)
12062 */
12063 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12064 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12065 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12066 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12067 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12068 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12069 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12070 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12071 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12072 /*
12073 * Set up output mixers (0x0c - 0x0e)
12074 */
12075 /* set vol=0 to output mixers */
12076 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12077 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12078 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12079
12080 /* set up input amps for analog loopback */
12081 /* Amp Indices: DAC = 0, mixer = 1 */
12082 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12083 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12084 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12085 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12086 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12087 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12088
12089
12090 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12091 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12092 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12093 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12094 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12095 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12096 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12097
12098 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12099 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12100
12101 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12102 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12103
12104 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12105 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12106 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12107 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12108 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12109 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12110
12111 /* FIXME: use matrix-type input source selection */
12112 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12113 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12114 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12115 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12116 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12117 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12118 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12119 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12120 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12121 /* Input mixer2 */
12122 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12123 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12124 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12125 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12126 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12127 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12128 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12129 /* Input mixer3 */
12130 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12131 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12132 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12133 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12134 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12135 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12136 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12137
ce875f07
TI
12138 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12139
cd7509a4
KY
12140 { }
12141};
12142
9f99a638
HM
12143static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12144
12145 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12146 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12147 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12148
12149 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12150 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12151 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12152 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12153
12154 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12155 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12156 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12157 {}
12158};
12159
12160
cb53c626
TI
12161#ifdef CONFIG_SND_HDA_POWER_SAVE
12162#define alc262_loopbacks alc880_loopbacks
12163#endif
12164
def319f9 12165/* pcm configuration: identical with ALC880 */
df694daa
KY
12166#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12167#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12168#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12169#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12170
12171/*
12172 * BIOS auto configuration
12173 */
12174static int alc262_parse_auto_config(struct hda_codec *codec)
12175{
12176 struct alc_spec *spec = codec->spec;
12177 int err;
12178 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12179
f12ab1e0
TI
12180 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12181 alc262_ignore);
12182 if (err < 0)
df694daa 12183 return err;
e64f14f4 12184 if (!spec->autocfg.line_outs) {
0852d7a6 12185 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12186 spec->multiout.max_channels = 2;
12187 spec->no_analog = 1;
12188 goto dig_only;
12189 }
df694daa 12190 return 0; /* can't find valid BIOS pin config */
e64f14f4 12191 }
f12ab1e0
TI
12192 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12193 if (err < 0)
12194 return err;
05f5f477 12195 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12196 if (err < 0)
df694daa
KY
12197 return err;
12198
12199 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12200
e64f14f4 12201 dig_only:
757899ac 12202 alc_auto_parse_digital(codec);
df694daa 12203
603c4019 12204 if (spec->kctls.list)
d88897ea 12205 add_mixer(spec, spec->kctls.list);
df694daa 12206
d88897ea 12207 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12208 spec->num_mux_defs = 1;
61b9b9b1 12209 spec->input_mux = &spec->private_imux[0];
df694daa 12210
776e184e
TI
12211 err = alc_auto_add_mic_boost(codec);
12212 if (err < 0)
12213 return err;
12214
6227cdce 12215 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12216
df694daa
KY
12217 return 1;
12218}
12219
12220#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12221#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12222#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12223#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12224
12225
12226/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12227static void alc262_auto_init(struct hda_codec *codec)
df694daa 12228{
f6c7e546 12229 struct alc_spec *spec = codec->spec;
df694daa
KY
12230 alc262_auto_init_multi_out(codec);
12231 alc262_auto_init_hp_out(codec);
12232 alc262_auto_init_analog_input(codec);
f511b01c 12233 alc262_auto_init_input_src(codec);
757899ac 12234 alc_auto_init_digital(codec);
f6c7e546 12235 if (spec->unsol_event)
7fb0d78f 12236 alc_inithook(codec);
df694daa
KY
12237}
12238
12239/*
12240 * configuration and preset
12241 */
f5fcc13c
TI
12242static const char *alc262_models[ALC262_MODEL_LAST] = {
12243 [ALC262_BASIC] = "basic",
12244 [ALC262_HIPPO] = "hippo",
12245 [ALC262_HIPPO_1] = "hippo_1",
12246 [ALC262_FUJITSU] = "fujitsu",
12247 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12248 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12249 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12250 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12251 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12252 [ALC262_BENQ_T31] = "benq-t31",
12253 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12254 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12255 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12256 [ALC262_ULTRA] = "ultra",
0e31daf7 12257 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12258 [ALC262_NEC] = "nec",
ba340e82 12259 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12260 [ALC262_AUTO] = "auto",
12261};
12262
12263static struct snd_pci_quirk alc262_cfg_tbl[] = {
12264 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12265 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12266 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12267 ALC262_HP_BPC),
12268 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12269 ALC262_HP_BPC),
53eff7e1
TI
12270 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12271 ALC262_HP_BPC),
cd7509a4 12272 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12273 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12274 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12275 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12276 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12277 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12278 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12279 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12280 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12281 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12282 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12283 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12284 ALC262_HP_TC_T5735),
8c427226 12285 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12286 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12287 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12288 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12289 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12290 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12291 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12292 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12293#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12294 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12295 ALC262_SONY_ASSAMD),
c5b5165c 12296#endif
36ca6e13 12297 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12298 ALC262_TOSHIBA_RX1),
80ffe869 12299 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12300 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12301 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12302 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12303 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12304 ALC262_ULTRA),
3e420e78 12305 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12306 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12307 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12308 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12309 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12310 {}
12311};
12312
12313static struct alc_config_preset alc262_presets[] = {
12314 [ALC262_BASIC] = {
12315 .mixers = { alc262_base_mixer },
12316 .init_verbs = { alc262_init_verbs },
12317 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12318 .dac_nids = alc262_dac_nids,
12319 .hp_nid = 0x03,
12320 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12321 .channel_mode = alc262_modes,
a3bcba38 12322 .input_mux = &alc262_capture_source,
df694daa 12323 },
ccc656ce 12324 [ALC262_HIPPO] = {
42171c17 12325 .mixers = { alc262_hippo_mixer },
6732bd0d 12326 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12327 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12328 .dac_nids = alc262_dac_nids,
12329 .hp_nid = 0x03,
12330 .dig_out_nid = ALC262_DIGOUT_NID,
12331 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12332 .channel_mode = alc262_modes,
12333 .input_mux = &alc262_capture_source,
12334 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12335 .setup = alc262_hippo_setup,
12336 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12337 },
12338 [ALC262_HIPPO_1] = {
12339 .mixers = { alc262_hippo1_mixer },
12340 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12341 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12342 .dac_nids = alc262_dac_nids,
12343 .hp_nid = 0x02,
12344 .dig_out_nid = ALC262_DIGOUT_NID,
12345 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12346 .channel_mode = alc262_modes,
12347 .input_mux = &alc262_capture_source,
42171c17 12348 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12349 .setup = alc262_hippo1_setup,
12350 .init_hook = alc262_hippo_automute,
ccc656ce 12351 },
834be88d
TI
12352 [ALC262_FUJITSU] = {
12353 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12354 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12355 alc262_fujitsu_unsol_verbs },
834be88d
TI
12356 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12357 .dac_nids = alc262_dac_nids,
12358 .hp_nid = 0x03,
12359 .dig_out_nid = ALC262_DIGOUT_NID,
12360 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12361 .channel_mode = alc262_modes,
12362 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12363 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12364 .init_hook = alc262_fujitsu_init_hook,
834be88d 12365 },
9c7f852e
TI
12366 [ALC262_HP_BPC] = {
12367 .mixers = { alc262_HP_BPC_mixer },
12368 .init_verbs = { alc262_HP_BPC_init_verbs },
12369 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12370 .dac_nids = alc262_dac_nids,
12371 .hp_nid = 0x03,
12372 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12373 .channel_mode = alc262_modes,
12374 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12375 .unsol_event = alc262_hp_bpc_unsol_event,
12376 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12377 },
cd7509a4
KY
12378 [ALC262_HP_BPC_D7000_WF] = {
12379 .mixers = { alc262_HP_BPC_WildWest_mixer },
12380 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12381 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12382 .dac_nids = alc262_dac_nids,
12383 .hp_nid = 0x03,
12384 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12385 .channel_mode = alc262_modes,
accbe498 12386 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12387 .unsol_event = alc262_hp_wildwest_unsol_event,
12388 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12389 },
cd7509a4
KY
12390 [ALC262_HP_BPC_D7000_WL] = {
12391 .mixers = { alc262_HP_BPC_WildWest_mixer,
12392 alc262_HP_BPC_WildWest_option_mixer },
12393 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12394 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12395 .dac_nids = alc262_dac_nids,
12396 .hp_nid = 0x03,
12397 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12398 .channel_mode = alc262_modes,
accbe498 12399 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12400 .unsol_event = alc262_hp_wildwest_unsol_event,
12401 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12402 },
66d2a9d6
KY
12403 [ALC262_HP_TC_T5735] = {
12404 .mixers = { alc262_hp_t5735_mixer },
12405 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12406 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12407 .dac_nids = alc262_dac_nids,
12408 .hp_nid = 0x03,
12409 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12410 .channel_mode = alc262_modes,
12411 .input_mux = &alc262_capture_source,
dc99be47 12412 .unsol_event = alc_sku_unsol_event,
4f5d1706 12413 .setup = alc262_hp_t5735_setup,
dc99be47 12414 .init_hook = alc_inithook,
8c427226
KY
12415 },
12416 [ALC262_HP_RP5700] = {
12417 .mixers = { alc262_hp_rp5700_mixer },
12418 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12419 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12420 .dac_nids = alc262_dac_nids,
12421 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12422 .channel_mode = alc262_modes,
12423 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12424 },
304dcaac
TI
12425 [ALC262_BENQ_ED8] = {
12426 .mixers = { alc262_base_mixer },
12427 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12428 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12429 .dac_nids = alc262_dac_nids,
12430 .hp_nid = 0x03,
12431 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12432 .channel_mode = alc262_modes,
12433 .input_mux = &alc262_capture_source,
f12ab1e0 12434 },
272a527c
KY
12435 [ALC262_SONY_ASSAMD] = {
12436 .mixers = { alc262_sony_mixer },
12437 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12438 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12439 .dac_nids = alc262_dac_nids,
12440 .hp_nid = 0x02,
12441 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12442 .channel_mode = alc262_modes,
12443 .input_mux = &alc262_capture_source,
12444 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12445 .setup = alc262_hippo_setup,
12446 .init_hook = alc262_hippo_automute,
83c34218
KY
12447 },
12448 [ALC262_BENQ_T31] = {
12449 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12450 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12451 alc_hp15_unsol_verbs },
83c34218
KY
12452 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12453 .dac_nids = alc262_dac_nids,
12454 .hp_nid = 0x03,
12455 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12456 .channel_mode = alc262_modes,
12457 .input_mux = &alc262_capture_source,
12458 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12459 .setup = alc262_hippo_setup,
12460 .init_hook = alc262_hippo_automute,
ea1fb29a 12461 },
f651b50b 12462 [ALC262_ULTRA] = {
f9e336f6
TI
12463 .mixers = { alc262_ultra_mixer },
12464 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12465 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12466 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12467 .dac_nids = alc262_dac_nids,
f651b50b
TD
12468 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12469 .channel_mode = alc262_modes,
12470 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12471 .adc_nids = alc262_adc_nids, /* ADC0 */
12472 .capsrc_nids = alc262_capsrc_nids,
12473 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12474 .unsol_event = alc262_ultra_unsol_event,
12475 .init_hook = alc262_ultra_automute,
12476 },
0e31daf7
J
12477 [ALC262_LENOVO_3000] = {
12478 .mixers = { alc262_lenovo_3000_mixer },
12479 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12480 alc262_lenovo_3000_unsol_verbs,
12481 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12482 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12483 .dac_nids = alc262_dac_nids,
12484 .hp_nid = 0x03,
12485 .dig_out_nid = ALC262_DIGOUT_NID,
12486 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12487 .channel_mode = alc262_modes,
12488 .input_mux = &alc262_fujitsu_capture_source,
12489 .unsol_event = alc262_lenovo_3000_unsol_event,
12490 },
e8f9ae2a
PT
12491 [ALC262_NEC] = {
12492 .mixers = { alc262_nec_mixer },
12493 .init_verbs = { alc262_nec_verbs },
12494 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12495 .dac_nids = alc262_dac_nids,
12496 .hp_nid = 0x03,
12497 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12498 .channel_mode = alc262_modes,
12499 .input_mux = &alc262_capture_source,
12500 },
4e555fe5
KY
12501 [ALC262_TOSHIBA_S06] = {
12502 .mixers = { alc262_toshiba_s06_mixer },
12503 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12504 alc262_eapd_verbs },
12505 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12506 .capsrc_nids = alc262_dmic_capsrc_nids,
12507 .dac_nids = alc262_dac_nids,
12508 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12509 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12510 .dig_out_nid = ALC262_DIGOUT_NID,
12511 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12512 .channel_mode = alc262_modes,
4f5d1706
TI
12513 .unsol_event = alc_sku_unsol_event,
12514 .setup = alc262_toshiba_s06_setup,
12515 .init_hook = alc_inithook,
4e555fe5 12516 },
9f99a638
HM
12517 [ALC262_TOSHIBA_RX1] = {
12518 .mixers = { alc262_toshiba_rx1_mixer },
12519 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12520 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12521 .dac_nids = alc262_dac_nids,
12522 .hp_nid = 0x03,
12523 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12524 .channel_mode = alc262_modes,
12525 .input_mux = &alc262_capture_source,
12526 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12527 .setup = alc262_hippo_setup,
12528 .init_hook = alc262_hippo_automute,
9f99a638 12529 },
ba340e82
TV
12530 [ALC262_TYAN] = {
12531 .mixers = { alc262_tyan_mixer },
12532 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12533 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12534 .dac_nids = alc262_dac_nids,
12535 .hp_nid = 0x02,
12536 .dig_out_nid = ALC262_DIGOUT_NID,
12537 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12538 .channel_mode = alc262_modes,
12539 .input_mux = &alc262_capture_source,
a9fd4f3f 12540 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12541 .setup = alc262_tyan_setup,
12542 .init_hook = alc_automute_amp,
ba340e82 12543 },
df694daa
KY
12544};
12545
12546static int patch_alc262(struct hda_codec *codec)
12547{
12548 struct alc_spec *spec;
12549 int board_config;
12550 int err;
12551
dc041e0b 12552 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12553 if (spec == NULL)
12554 return -ENOMEM;
12555
12556 codec->spec = spec;
12557#if 0
f12ab1e0
TI
12558 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12559 * under-run
12560 */
df694daa
KY
12561 {
12562 int tmp;
12563 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12564 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12565 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12566 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12567 }
12568#endif
da00c244 12569 alc_auto_parse_customize_define(codec);
df694daa 12570
2c3bf9ab
TI
12571 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12572
f5fcc13c
TI
12573 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12574 alc262_models,
12575 alc262_cfg_tbl);
cd7509a4 12576
f5fcc13c 12577 if (board_config < 0) {
9a11f1aa
TI
12578 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12579 codec->chip_name);
df694daa
KY
12580 board_config = ALC262_AUTO;
12581 }
12582
12583 if (board_config == ALC262_AUTO) {
12584 /* automatic parse from the BIOS config */
12585 err = alc262_parse_auto_config(codec);
12586 if (err < 0) {
12587 alc_free(codec);
12588 return err;
f12ab1e0 12589 } else if (!err) {
9c7f852e
TI
12590 printk(KERN_INFO
12591 "hda_codec: Cannot set up configuration "
12592 "from BIOS. Using base mode...\n");
df694daa
KY
12593 board_config = ALC262_BASIC;
12594 }
12595 }
12596
dc1eae25 12597 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12598 err = snd_hda_attach_beep_device(codec, 0x1);
12599 if (err < 0) {
12600 alc_free(codec);
12601 return err;
12602 }
680cd536
KK
12603 }
12604
df694daa 12605 if (board_config != ALC262_AUTO)
e9c364c0 12606 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12607
df694daa
KY
12608 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12609 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12610
df694daa
KY
12611 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12612 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12613
f12ab1e0 12614 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12615 int i;
12616 /* check whether the digital-mic has to be supported */
12617 for (i = 0; i < spec->input_mux->num_items; i++) {
12618 if (spec->input_mux->items[i].index >= 9)
12619 break;
12620 }
12621 if (i < spec->input_mux->num_items) {
12622 /* use only ADC0 */
12623 spec->adc_nids = alc262_dmic_adc_nids;
12624 spec->num_adc_nids = 1;
12625 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12626 } else {
8c927b4a
TI
12627 /* all analog inputs */
12628 /* check whether NID 0x07 is valid */
12629 unsigned int wcap = get_wcaps(codec, 0x07);
12630
12631 /* get type */
a22d543a 12632 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12633 if (wcap != AC_WID_AUD_IN) {
12634 spec->adc_nids = alc262_adc_nids_alt;
12635 spec->num_adc_nids =
12636 ARRAY_SIZE(alc262_adc_nids_alt);
12637 spec->capsrc_nids = alc262_capsrc_nids_alt;
12638 } else {
12639 spec->adc_nids = alc262_adc_nids;
12640 spec->num_adc_nids =
12641 ARRAY_SIZE(alc262_adc_nids);
12642 spec->capsrc_nids = alc262_capsrc_nids;
12643 }
df694daa
KY
12644 }
12645 }
e64f14f4 12646 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12647 set_capture_mixer(codec);
dc1eae25 12648 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 12649 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12650
2134ea4f
TI
12651 spec->vmaster_nid = 0x0c;
12652
df694daa
KY
12653 codec->patch_ops = alc_patch_ops;
12654 if (board_config == ALC262_AUTO)
ae6b813a 12655 spec->init_hook = alc262_auto_init;
cb53c626
TI
12656#ifdef CONFIG_SND_HDA_POWER_SAVE
12657 if (!spec->loopback.amplist)
12658 spec->loopback.amplist = alc262_loopbacks;
12659#endif
ea1fb29a 12660
df694daa
KY
12661 return 0;
12662}
12663
a361d84b
KY
12664/*
12665 * ALC268 channel source setting (2 channel)
12666 */
12667#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12668#define alc268_modes alc260_modes
ea1fb29a 12669
a361d84b
KY
12670static hda_nid_t alc268_dac_nids[2] = {
12671 /* front, hp */
12672 0x02, 0x03
12673};
12674
12675static hda_nid_t alc268_adc_nids[2] = {
12676 /* ADC0-1 */
12677 0x08, 0x07
12678};
12679
12680static hda_nid_t alc268_adc_nids_alt[1] = {
12681 /* ADC0 */
12682 0x08
12683};
12684
e1406348
TI
12685static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12686
a361d84b
KY
12687static struct snd_kcontrol_new alc268_base_mixer[] = {
12688 /* output mixer control */
12689 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12690 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12691 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12692 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
12693 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12694 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12695 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
12696 { }
12697};
12698
42171c17
TI
12699static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12700 /* output mixer control */
12701 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12702 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12703 ALC262_HIPPO_MASTER_SWITCH,
12704 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12705 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12706 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12707 { }
12708};
12709
aef9d318
TI
12710/* bind Beep switches of both NID 0x0f and 0x10 */
12711static struct hda_bind_ctls alc268_bind_beep_sw = {
12712 .ops = &snd_hda_bind_sw,
12713 .values = {
12714 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12715 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12716 0
12717 },
12718};
12719
12720static struct snd_kcontrol_new alc268_beep_mixer[] = {
12721 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12722 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12723 { }
12724};
12725
d1a991a6
KY
12726static struct hda_verb alc268_eapd_verbs[] = {
12727 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12728 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12729 { }
12730};
12731
d273809e 12732/* Toshiba specific */
d273809e
TI
12733static struct hda_verb alc268_toshiba_verbs[] = {
12734 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12735 { } /* end */
12736};
12737
12738/* Acer specific */
889c4395 12739/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
12740static struct hda_bind_ctls alc268_acer_bind_master_vol = {
12741 .ops = &snd_hda_bind_vol,
12742 .values = {
12743 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12744 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12745 0
12746 },
12747};
12748
889c4395
TI
12749/* mute/unmute internal speaker according to the hp jack and mute state */
12750static void alc268_acer_automute(struct hda_codec *codec, int force)
12751{
12752 struct alc_spec *spec = codec->spec;
12753 unsigned int mute;
12754
12755 if (force || !spec->sense_updated) {
864f92be 12756 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
12757 spec->sense_updated = 1;
12758 }
12759 if (spec->jack_present)
12760 mute = HDA_AMP_MUTE; /* mute internal speaker */
12761 else /* unmute internal speaker if necessary */
12762 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
12763 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12764 HDA_AMP_MUTE, mute);
12765}
12766
12767
12768/* bind hp and internal speaker mute (with plug check) */
12769static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
12770 struct snd_ctl_elem_value *ucontrol)
12771{
12772 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12773 long *valp = ucontrol->value.integer.value;
12774 int change;
12775
8de56b7d 12776 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
12777 if (change)
12778 alc268_acer_automute(codec, 0);
12779 return change;
12780}
d273809e 12781
8ef355da
KY
12782static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12783 /* output mixer control */
12784 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12785 {
12786 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12787 .name = "Master Playback Switch",
5e26dfd0 12788 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
12789 .info = snd_hda_mixer_amp_switch_info,
12790 .get = snd_hda_mixer_amp_switch_get,
12791 .put = alc268_acer_master_sw_put,
12792 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12793 },
12794 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12795 { }
12796};
12797
d273809e
TI
12798static struct snd_kcontrol_new alc268_acer_mixer[] = {
12799 /* output mixer control */
12800 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12801 {
12802 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12803 .name = "Master Playback Switch",
5e26dfd0 12804 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
12805 .info = snd_hda_mixer_amp_switch_info,
12806 .get = snd_hda_mixer_amp_switch_get,
12807 .put = alc268_acer_master_sw_put,
12808 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12809 },
33bf17ab
TI
12810 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12811 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12812 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
12813 { }
12814};
12815
c238b4f4
TI
12816static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12817 /* output mixer control */
12818 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12819 {
12820 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12821 .name = "Master Playback Switch",
5e26dfd0 12822 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
12823 .info = snd_hda_mixer_amp_switch_info,
12824 .get = snd_hda_mixer_amp_switch_get,
12825 .put = alc268_acer_master_sw_put,
12826 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12827 },
12828 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12829 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12830 { }
12831};
12832
8ef355da
KY
12833static struct hda_verb alc268_acer_aspire_one_verbs[] = {
12834 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12835 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12836 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12837 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12838 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12839 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12840 { }
12841};
12842
d273809e 12843static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
12844 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12845 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
12846 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12847 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
12848 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12849 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
12850 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12851 { }
12852};
12853
12854/* unsolicited event for HP jack sensing */
42171c17 12855#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
12856#define alc268_toshiba_setup alc262_hippo_setup
12857#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
12858
12859static void alc268_acer_unsol_event(struct hda_codec *codec,
12860 unsigned int res)
12861{
889c4395 12862 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
12863 return;
12864 alc268_acer_automute(codec, 1);
12865}
12866
889c4395
TI
12867static void alc268_acer_init_hook(struct hda_codec *codec)
12868{
12869 alc268_acer_automute(codec, 1);
12870}
12871
8ef355da
KY
12872/* toggle speaker-output according to the hp-jack state */
12873static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
12874{
12875 unsigned int present;
12876 unsigned char bits;
12877
864f92be 12878 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 12879 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 12880 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 12881 HDA_AMP_MUTE, bits);
8ef355da 12882 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 12883 HDA_AMP_MUTE, bits);
8ef355da
KY
12884}
12885
8ef355da
KY
12886static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
12887 unsigned int res)
12888{
4f5d1706
TI
12889 switch (res >> 26) {
12890 case ALC880_HP_EVENT:
8ef355da 12891 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
12892 break;
12893 case ALC880_MIC_EVENT:
12894 alc_mic_automute(codec);
12895 break;
12896 }
12897}
12898
12899static void alc268_acer_lc_setup(struct hda_codec *codec)
12900{
12901 struct alc_spec *spec = codec->spec;
12902 spec->ext_mic.pin = 0x18;
12903 spec->ext_mic.mux_idx = 0;
12904 spec->int_mic.pin = 0x12;
12905 spec->int_mic.mux_idx = 6;
12906 spec->auto_mic = 1;
8ef355da
KY
12907}
12908
12909static void alc268_acer_lc_init_hook(struct hda_codec *codec)
12910{
12911 alc268_aspire_one_speaker_automute(codec);
4f5d1706 12912 alc_mic_automute(codec);
8ef355da
KY
12913}
12914
3866f0b0
TI
12915static struct snd_kcontrol_new alc268_dell_mixer[] = {
12916 /* output mixer control */
12917 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12918 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12919 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12920 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12921 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12922 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12923 { }
12924};
12925
12926static struct hda_verb alc268_dell_verbs[] = {
12927 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12928 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12929 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 12930 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
12931 { }
12932};
12933
12934/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 12935static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 12936{
a9fd4f3f 12937 struct alc_spec *spec = codec->spec;
3866f0b0 12938
a9fd4f3f
TI
12939 spec->autocfg.hp_pins[0] = 0x15;
12940 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12941 spec->ext_mic.pin = 0x18;
12942 spec->ext_mic.mux_idx = 0;
12943 spec->int_mic.pin = 0x19;
12944 spec->int_mic.mux_idx = 1;
12945 spec->auto_mic = 1;
3866f0b0
TI
12946}
12947
eb5a6621
HRK
12948static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12949 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12950 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12951 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12952 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12953 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12954 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12955 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12956 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12957 { }
12958};
12959
12960static struct hda_verb alc267_quanta_il1_verbs[] = {
12961 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12962 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12963 { }
12964};
12965
4f5d1706 12966static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 12967{
a9fd4f3f 12968 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
12969 spec->autocfg.hp_pins[0] = 0x15;
12970 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12971 spec->ext_mic.pin = 0x18;
12972 spec->ext_mic.mux_idx = 0;
12973 spec->int_mic.pin = 0x19;
12974 spec->int_mic.mux_idx = 1;
12975 spec->auto_mic = 1;
eb5a6621
HRK
12976}
12977
a361d84b
KY
12978/*
12979 * generic initialization of ADC, input mixers and output mixers
12980 */
12981static struct hda_verb alc268_base_init_verbs[] = {
12982 /* Unmute DAC0-1 and set vol = 0 */
12983 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 12984 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
12985
12986 /*
12987 * Set up output mixers (0x0c - 0x0e)
12988 */
12989 /* set vol=0 to output mixers */
12990 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
12991 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12992
12993 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12994 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12995
12996 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12997 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12998 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12999 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13000 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13001 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13002 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13003 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13004
13005 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13006 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13007 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13008 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13009 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13010
13011 /* set PCBEEP vol = 0, mute connections */
13012 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13013 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13014 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13015
a9b3aa8a 13016 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13017
a9b3aa8a
JZ
13018 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13019 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13020 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13021 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13022
a361d84b
KY
13023 { }
13024};
13025
13026/*
13027 * generic initialization of ADC, input mixers and output mixers
13028 */
13029static struct hda_verb alc268_volume_init_verbs[] = {
13030 /* set output DAC */
4cfb91c6
TI
13031 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13032 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13033
13034 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13035 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13036 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13037 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13038 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13039
a361d84b 13040 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13041 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13042 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13043
13044 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13045 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13046
aef9d318
TI
13047 /* set PCBEEP vol = 0, mute connections */
13048 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13049 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13050 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13051
13052 { }
13053};
13054
fdbc6626
TI
13055static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13056 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13057 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13058 { } /* end */
13059};
13060
a361d84b
KY
13061static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13062 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13063 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13064 _DEFINE_CAPSRC(1),
a361d84b
KY
13065 { } /* end */
13066};
13067
13068static struct snd_kcontrol_new alc268_capture_mixer[] = {
13069 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13070 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13071 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13072 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13073 _DEFINE_CAPSRC(2),
a361d84b
KY
13074 { } /* end */
13075};
13076
13077static struct hda_input_mux alc268_capture_source = {
13078 .num_items = 4,
13079 .items = {
13080 { "Mic", 0x0 },
13081 { "Front Mic", 0x1 },
13082 { "Line", 0x2 },
13083 { "CD", 0x3 },
13084 },
13085};
13086
0ccb541c 13087static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13088 .num_items = 3,
13089 .items = {
13090 { "Mic", 0x0 },
13091 { "Internal Mic", 0x1 },
13092 { "Line", 0x2 },
13093 },
13094};
13095
13096static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13097 .num_items = 3,
13098 .items = {
13099 { "Mic", 0x0 },
13100 { "Internal Mic", 0x6 },
13101 { "Line", 0x2 },
13102 },
13103};
13104
86c53bd2
JW
13105#ifdef CONFIG_SND_DEBUG
13106static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13107 /* Volume widgets */
13108 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13109 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13110 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13111 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13112 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13113 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13114 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13115 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13116 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13117 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13118 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13119 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13120 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13121 /* The below appears problematic on some hardwares */
13122 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13123 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13124 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13125 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13126 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13127
13128 /* Modes for retasking pin widgets */
13129 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13130 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13131 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13132 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13133
13134 /* Controls for GPIO pins, assuming they are configured as outputs */
13135 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13136 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13137 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13138 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13139
13140 /* Switches to allow the digital SPDIF output pin to be enabled.
13141 * The ALC268 does not have an SPDIF input.
13142 */
13143 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13144
13145 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13146 * this output to turn on an external amplifier.
13147 */
13148 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13149 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13150
13151 { } /* end */
13152};
13153#endif
13154
a361d84b
KY
13155/* create input playback/capture controls for the given pin */
13156static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13157 const char *ctlname, int idx)
13158{
3f3b7c1a 13159 hda_nid_t dac;
a361d84b
KY
13160 int err;
13161
3f3b7c1a
TI
13162 switch (nid) {
13163 case 0x14:
13164 case 0x16:
13165 dac = 0x02;
13166 break;
13167 case 0x15:
b08b1637
TI
13168 case 0x1a: /* ALC259/269 only */
13169 case 0x1b: /* ALC259/269 only */
531d8791 13170 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13171 dac = 0x03;
13172 break;
13173 default:
c7a9434d
TI
13174 snd_printd(KERN_WARNING "hda_codec: "
13175 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13176 return 0;
13177 }
13178 if (spec->multiout.dac_nids[0] != dac &&
13179 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13180 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13181 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13182 HDA_OUTPUT));
13183 if (err < 0)
13184 return err;
3f3b7c1a
TI
13185 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13186 }
13187
3f3b7c1a 13188 if (nid != 0x16)
0afe5f89 13189 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13190 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13191 else /* mono */
0afe5f89 13192 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13193 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13194 if (err < 0)
13195 return err;
13196 return 0;
13197}
13198
13199/* add playback controls from the parsed DAC table */
13200static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13201 const struct auto_pin_cfg *cfg)
13202{
13203 hda_nid_t nid;
13204 int err;
13205
a361d84b 13206 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13207
13208 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13209 if (nid) {
13210 const char *name;
13211 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13212 name = "Speaker";
13213 else
13214 name = "Front";
13215 err = alc268_new_analog_output(spec, nid, name, 0);
13216 if (err < 0)
13217 return err;
13218 }
a361d84b
KY
13219
13220 nid = cfg->speaker_pins[0];
13221 if (nid == 0x1d) {
0afe5f89 13222 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13223 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13224 if (err < 0)
13225 return err;
7bfb9c03 13226 } else if (nid) {
3f3b7c1a
TI
13227 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13228 if (err < 0)
13229 return err;
a361d84b
KY
13230 }
13231 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13232 if (nid) {
13233 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13234 if (err < 0)
13235 return err;
13236 }
a361d84b
KY
13237
13238 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13239 if (nid == 0x16) {
0afe5f89 13240 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13241 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13242 if (err < 0)
13243 return err;
13244 }
ea1fb29a 13245 return 0;
a361d84b
KY
13246}
13247
13248/* create playback/capture controls for input pins */
05f5f477 13249static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13250 const struct auto_pin_cfg *cfg)
13251{
05f5f477 13252 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13253}
13254
e9af4f36
TI
13255static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13256 hda_nid_t nid, int pin_type)
13257{
13258 int idx;
13259
13260 alc_set_pin_output(codec, nid, pin_type);
13261 if (nid == 0x14 || nid == 0x16)
13262 idx = 0;
13263 else
13264 idx = 1;
13265 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13266}
13267
13268static void alc268_auto_init_multi_out(struct hda_codec *codec)
13269{
13270 struct alc_spec *spec = codec->spec;
13271 hda_nid_t nid = spec->autocfg.line_out_pins[0];
13272 if (nid) {
13273 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13274 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13275 }
13276}
13277
13278static void alc268_auto_init_hp_out(struct hda_codec *codec)
13279{
13280 struct alc_spec *spec = codec->spec;
13281 hda_nid_t pin;
13282
13283 pin = spec->autocfg.hp_pins[0];
13284 if (pin)
13285 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13286 pin = spec->autocfg.speaker_pins[0];
13287 if (pin)
13288 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13289}
13290
a361d84b
KY
13291static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13292{
13293 struct alc_spec *spec = codec->spec;
13294 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13295 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13296 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13297 unsigned int dac_vol1, dac_vol2;
13298
e9af4f36 13299 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13300 snd_hda_codec_write(codec, speaker_nid, 0,
13301 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13302 /* mute mixer inputs from 0x1d */
a361d84b
KY
13303 snd_hda_codec_write(codec, 0x0f, 0,
13304 AC_VERB_SET_AMP_GAIN_MUTE,
13305 AMP_IN_UNMUTE(1));
13306 snd_hda_codec_write(codec, 0x10, 0,
13307 AC_VERB_SET_AMP_GAIN_MUTE,
13308 AMP_IN_UNMUTE(1));
13309 } else {
e9af4f36 13310 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13311 snd_hda_codec_write(codec, 0x0f, 0,
13312 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13313 snd_hda_codec_write(codec, 0x10, 0,
13314 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13315 }
13316
13317 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13318 if (line_nid == 0x14)
a361d84b
KY
13319 dac_vol2 = AMP_OUT_ZERO;
13320 else if (line_nid == 0x15)
13321 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13322 if (hp_nid == 0x14)
a361d84b
KY
13323 dac_vol2 = AMP_OUT_ZERO;
13324 else if (hp_nid == 0x15)
13325 dac_vol1 = AMP_OUT_ZERO;
13326 if (line_nid != 0x16 || hp_nid != 0x16 ||
13327 spec->autocfg.line_out_pins[1] != 0x16 ||
13328 spec->autocfg.line_out_pins[2] != 0x16)
13329 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13330
13331 snd_hda_codec_write(codec, 0x02, 0,
13332 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13333 snd_hda_codec_write(codec, 0x03, 0,
13334 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13335}
13336
def319f9 13337/* pcm configuration: identical with ALC880 */
a361d84b
KY
13338#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13339#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13340#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13341#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13342
13343/*
13344 * BIOS auto configuration
13345 */
13346static int alc268_parse_auto_config(struct hda_codec *codec)
13347{
13348 struct alc_spec *spec = codec->spec;
13349 int err;
13350 static hda_nid_t alc268_ignore[] = { 0 };
13351
13352 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13353 alc268_ignore);
13354 if (err < 0)
13355 return err;
7e0e44d4
TI
13356 if (!spec->autocfg.line_outs) {
13357 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13358 spec->multiout.max_channels = 2;
13359 spec->no_analog = 1;
13360 goto dig_only;
13361 }
a361d84b 13362 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13363 }
a361d84b
KY
13364 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13365 if (err < 0)
13366 return err;
05f5f477 13367 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13368 if (err < 0)
13369 return err;
13370
13371 spec->multiout.max_channels = 2;
13372
7e0e44d4 13373 dig_only:
a361d84b 13374 /* digital only support output */
757899ac 13375 alc_auto_parse_digital(codec);
603c4019 13376 if (spec->kctls.list)
d88897ea 13377 add_mixer(spec, spec->kctls.list);
a361d84b 13378
892981ff 13379 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13380 add_mixer(spec, alc268_beep_mixer);
aef9d318 13381
d88897ea 13382 add_verb(spec, alc268_volume_init_verbs);
5908589f 13383 spec->num_mux_defs = 2;
61b9b9b1 13384 spec->input_mux = &spec->private_imux[0];
a361d84b 13385
776e184e
TI
13386 err = alc_auto_add_mic_boost(codec);
13387 if (err < 0)
13388 return err;
13389
6227cdce 13390 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13391
a361d84b
KY
13392 return 1;
13393}
13394
a361d84b
KY
13395#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13396
13397/* init callback for auto-configuration model -- overriding the default init */
13398static void alc268_auto_init(struct hda_codec *codec)
13399{
f6c7e546 13400 struct alc_spec *spec = codec->spec;
a361d84b
KY
13401 alc268_auto_init_multi_out(codec);
13402 alc268_auto_init_hp_out(codec);
13403 alc268_auto_init_mono_speaker_out(codec);
13404 alc268_auto_init_analog_input(codec);
757899ac 13405 alc_auto_init_digital(codec);
f6c7e546 13406 if (spec->unsol_event)
7fb0d78f 13407 alc_inithook(codec);
a361d84b
KY
13408}
13409
13410/*
13411 * configuration and preset
13412 */
13413static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13414 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13415 [ALC268_3ST] = "3stack",
983f8ae4 13416 [ALC268_TOSHIBA] = "toshiba",
d273809e 13417 [ALC268_ACER] = "acer",
c238b4f4 13418 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13419 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13420 [ALC268_DELL] = "dell",
f12462c5 13421 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13422#ifdef CONFIG_SND_DEBUG
13423 [ALC268_TEST] = "test",
13424#endif
a361d84b
KY
13425 [ALC268_AUTO] = "auto",
13426};
13427
13428static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13429 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13430 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13431 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13432 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13433 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13434 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13435 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13436 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13437 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13438 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13439 /* almost compatible with toshiba but with optional digital outs;
13440 * auto-probing seems working fine
13441 */
8871e5b9 13442 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13443 ALC268_AUTO),
a361d84b 13444 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13445 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13446 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13447 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13448 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
8871e5b9 13449 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
a361d84b
KY
13450 {}
13451};
13452
3abf2f36
TI
13453/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13454static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13455 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13456 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13457 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13458 ALC268_TOSHIBA),
13459 {}
13460};
13461
a361d84b 13462static struct alc_config_preset alc268_presets[] = {
eb5a6621 13463 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13464 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13465 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13466 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13467 alc267_quanta_il1_verbs },
13468 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13469 .dac_nids = alc268_dac_nids,
13470 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13471 .adc_nids = alc268_adc_nids_alt,
13472 .hp_nid = 0x03,
13473 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13474 .channel_mode = alc268_modes,
4f5d1706
TI
13475 .unsol_event = alc_sku_unsol_event,
13476 .setup = alc267_quanta_il1_setup,
13477 .init_hook = alc_inithook,
eb5a6621 13478 },
a361d84b 13479 [ALC268_3ST] = {
aef9d318
TI
13480 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13481 alc268_beep_mixer },
a361d84b
KY
13482 .init_verbs = { alc268_base_init_verbs },
13483 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13484 .dac_nids = alc268_dac_nids,
13485 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13486 .adc_nids = alc268_adc_nids_alt,
e1406348 13487 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13488 .hp_nid = 0x03,
13489 .dig_out_nid = ALC268_DIGOUT_NID,
13490 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13491 .channel_mode = alc268_modes,
13492 .input_mux = &alc268_capture_source,
13493 },
d1a991a6 13494 [ALC268_TOSHIBA] = {
42171c17 13495 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13496 alc268_beep_mixer },
d273809e
TI
13497 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13498 alc268_toshiba_verbs },
d1a991a6
KY
13499 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13500 .dac_nids = alc268_dac_nids,
13501 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13502 .adc_nids = alc268_adc_nids_alt,
e1406348 13503 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13504 .hp_nid = 0x03,
13505 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13506 .channel_mode = alc268_modes,
13507 .input_mux = &alc268_capture_source,
d273809e 13508 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13509 .setup = alc268_toshiba_setup,
13510 .init_hook = alc268_toshiba_automute,
d273809e
TI
13511 },
13512 [ALC268_ACER] = {
432fd133 13513 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13514 alc268_beep_mixer },
d273809e
TI
13515 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13516 alc268_acer_verbs },
13517 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13518 .dac_nids = alc268_dac_nids,
13519 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13520 .adc_nids = alc268_adc_nids_alt,
e1406348 13521 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13522 .hp_nid = 0x02,
13523 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13524 .channel_mode = alc268_modes,
0ccb541c 13525 .input_mux = &alc268_acer_capture_source,
d273809e 13526 .unsol_event = alc268_acer_unsol_event,
889c4395 13527 .init_hook = alc268_acer_init_hook,
d1a991a6 13528 },
c238b4f4
TI
13529 [ALC268_ACER_DMIC] = {
13530 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13531 alc268_beep_mixer },
13532 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13533 alc268_acer_verbs },
13534 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13535 .dac_nids = alc268_dac_nids,
13536 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13537 .adc_nids = alc268_adc_nids_alt,
13538 .capsrc_nids = alc268_capsrc_nids,
13539 .hp_nid = 0x02,
13540 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13541 .channel_mode = alc268_modes,
13542 .input_mux = &alc268_acer_dmic_capture_source,
13543 .unsol_event = alc268_acer_unsol_event,
13544 .init_hook = alc268_acer_init_hook,
13545 },
8ef355da
KY
13546 [ALC268_ACER_ASPIRE_ONE] = {
13547 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13548 alc268_beep_mixer,
fdbc6626 13549 alc268_capture_nosrc_mixer },
8ef355da
KY
13550 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13551 alc268_acer_aspire_one_verbs },
13552 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13553 .dac_nids = alc268_dac_nids,
13554 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13555 .adc_nids = alc268_adc_nids_alt,
13556 .capsrc_nids = alc268_capsrc_nids,
13557 .hp_nid = 0x03,
13558 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13559 .channel_mode = alc268_modes,
8ef355da 13560 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13561 .setup = alc268_acer_lc_setup,
8ef355da
KY
13562 .init_hook = alc268_acer_lc_init_hook,
13563 },
3866f0b0 13564 [ALC268_DELL] = {
fdbc6626
TI
13565 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13566 alc268_capture_nosrc_mixer },
3866f0b0
TI
13567 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13568 alc268_dell_verbs },
13569 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13570 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13571 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13572 .adc_nids = alc268_adc_nids_alt,
13573 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13574 .hp_nid = 0x02,
13575 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13576 .channel_mode = alc268_modes,
a9fd4f3f 13577 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13578 .setup = alc268_dell_setup,
13579 .init_hook = alc_inithook,
3866f0b0 13580 },
f12462c5 13581 [ALC268_ZEPTO] = {
aef9d318
TI
13582 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13583 alc268_beep_mixer },
f12462c5
MT
13584 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13585 alc268_toshiba_verbs },
13586 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13587 .dac_nids = alc268_dac_nids,
13588 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13589 .adc_nids = alc268_adc_nids_alt,
e1406348 13590 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13591 .hp_nid = 0x03,
13592 .dig_out_nid = ALC268_DIGOUT_NID,
13593 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13594 .channel_mode = alc268_modes,
13595 .input_mux = &alc268_capture_source,
4f5d1706
TI
13596 .setup = alc268_toshiba_setup,
13597 .init_hook = alc268_toshiba_automute,
f12462c5 13598 },
86c53bd2
JW
13599#ifdef CONFIG_SND_DEBUG
13600 [ALC268_TEST] = {
13601 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13602 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13603 alc268_volume_init_verbs },
13604 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13605 .dac_nids = alc268_dac_nids,
13606 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13607 .adc_nids = alc268_adc_nids_alt,
e1406348 13608 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13609 .hp_nid = 0x03,
13610 .dig_out_nid = ALC268_DIGOUT_NID,
13611 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13612 .channel_mode = alc268_modes,
13613 .input_mux = &alc268_capture_source,
13614 },
13615#endif
a361d84b
KY
13616};
13617
13618static int patch_alc268(struct hda_codec *codec)
13619{
13620 struct alc_spec *spec;
13621 int board_config;
22971e3a 13622 int i, has_beep, err;
a361d84b 13623
ef86f581 13624 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13625 if (spec == NULL)
13626 return -ENOMEM;
13627
13628 codec->spec = spec;
13629
13630 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13631 alc268_models,
13632 alc268_cfg_tbl);
13633
3abf2f36
TI
13634 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13635 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13636 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13637
a361d84b 13638 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13639 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13640 codec->chip_name);
a361d84b
KY
13641 board_config = ALC268_AUTO;
13642 }
13643
13644 if (board_config == ALC268_AUTO) {
13645 /* automatic parse from the BIOS config */
13646 err = alc268_parse_auto_config(codec);
13647 if (err < 0) {
13648 alc_free(codec);
13649 return err;
13650 } else if (!err) {
13651 printk(KERN_INFO
13652 "hda_codec: Cannot set up configuration "
13653 "from BIOS. Using base mode...\n");
13654 board_config = ALC268_3ST;
13655 }
13656 }
13657
13658 if (board_config != ALC268_AUTO)
e9c364c0 13659 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 13660
a361d84b
KY
13661 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13662 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 13663 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 13664
a361d84b
KY
13665 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13666
22971e3a
TI
13667 has_beep = 0;
13668 for (i = 0; i < spec->num_mixers; i++) {
13669 if (spec->mixers[i] == alc268_beep_mixer) {
13670 has_beep = 1;
13671 break;
13672 }
13673 }
13674
13675 if (has_beep) {
13676 err = snd_hda_attach_beep_device(codec, 0x1);
13677 if (err < 0) {
13678 alc_free(codec);
13679 return err;
13680 }
13681 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13682 /* override the amp caps for beep generator */
13683 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
13684 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13685 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13686 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13687 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 13688 }
aef9d318 13689
7e0e44d4 13690 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
13691 /* check whether NID 0x07 is valid */
13692 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 13693 int i;
3866f0b0 13694
defb5ab2 13695 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 13696 /* get type */
a22d543a 13697 wcap = get_wcaps_type(wcap);
fdbc6626
TI
13698 if (spec->auto_mic ||
13699 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
13700 spec->adc_nids = alc268_adc_nids_alt;
13701 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
13702 if (spec->auto_mic)
13703 fixup_automic_adc(codec);
fdbc6626
TI
13704 if (spec->auto_mic || spec->input_mux->num_items == 1)
13705 add_mixer(spec, alc268_capture_nosrc_mixer);
13706 else
13707 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
13708 } else {
13709 spec->adc_nids = alc268_adc_nids;
13710 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 13711 add_mixer(spec, alc268_capture_mixer);
a361d84b 13712 }
85860c06
TI
13713 /* set default input source */
13714 for (i = 0; i < spec->num_adc_nids; i++)
13715 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
13716 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
13717 i < spec->num_mux_defs ?
13718 spec->input_mux[i].items[0].index :
85860c06 13719 spec->input_mux->items[0].index);
a361d84b 13720 }
2134ea4f
TI
13721
13722 spec->vmaster_nid = 0x02;
13723
a361d84b
KY
13724 codec->patch_ops = alc_patch_ops;
13725 if (board_config == ALC268_AUTO)
13726 spec->init_hook = alc268_auto_init;
ea1fb29a 13727
a361d84b
KY
13728 return 0;
13729}
13730
f6a92248
KY
13731/*
13732 * ALC269 channel source setting (2 channel)
13733 */
13734#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13735
13736#define alc269_dac_nids alc260_dac_nids
13737
13738static hda_nid_t alc269_adc_nids[1] = {
13739 /* ADC1 */
f53281e6
KY
13740 0x08,
13741};
13742
e01bf509
TI
13743static hda_nid_t alc269_capsrc_nids[1] = {
13744 0x23,
13745};
13746
84898e87
KY
13747static hda_nid_t alc269vb_adc_nids[1] = {
13748 /* ADC1 */
13749 0x09,
13750};
13751
13752static hda_nid_t alc269vb_capsrc_nids[1] = {
13753 0x22,
13754};
13755
6694635d
TI
13756static hda_nid_t alc269_adc_candidates[] = {
13757 0x08, 0x09, 0x07,
13758};
e01bf509 13759
f6a92248
KY
13760#define alc269_modes alc260_modes
13761#define alc269_capture_source alc880_lg_lw_capture_source
13762
13763static struct snd_kcontrol_new alc269_base_mixer[] = {
13764 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13765 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13766 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13767 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13768 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13769 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13770 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13771 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13772 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13773 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13774 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13775 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
13776 { } /* end */
13777};
13778
60db6b53
KY
13779static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13780 /* output mixer control */
13781 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13782 {
13783 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13784 .name = "Master Playback Switch",
5e26dfd0 13785 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
13786 .info = snd_hda_mixer_amp_switch_info,
13787 .get = snd_hda_mixer_amp_switch_get,
13788 .put = alc268_acer_master_sw_put,
13789 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13790 },
13791 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13792 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13793 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13794 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13795 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13796 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
60db6b53
KY
13797 { }
13798};
13799
64154835
TV
13800static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13801 /* output mixer control */
13802 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13803 {
13804 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13805 .name = "Master Playback Switch",
5e26dfd0 13806 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
13807 .info = snd_hda_mixer_amp_switch_info,
13808 .get = snd_hda_mixer_amp_switch_get,
13809 .put = alc268_acer_master_sw_put,
13810 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13811 },
13812 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13813 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13814 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13815 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13816 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13817 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13818 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13819 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
13820 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
64154835
TV
13821 { }
13822};
13823
84898e87 13824static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 13825 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 13826 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 13827 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 13828 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
13829 { } /* end */
13830};
13831
84898e87
KY
13832static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13833 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13834 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13835 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13836 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13837 { } /* end */
13838};
13839
f53281e6 13840/* capture mixer elements */
84898e87
KY
13841static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13842 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13843 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13844 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13845 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13846 { } /* end */
13847};
13848
13849static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
13850 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13851 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
26f5df26
TI
13852 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13853 { } /* end */
13854};
13855
84898e87
KY
13856static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13857 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13858 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13859 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13860 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13861 { } /* end */
13862};
13863
13864static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13865 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13866 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13867 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13868 { } /* end */
13869};
13870
26f5df26 13871/* FSC amilo */
84898e87 13872#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 13873
60db6b53
KY
13874static struct hda_verb alc269_quanta_fl1_verbs[] = {
13875 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13876 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13877 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13878 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13879 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13880 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13881 { }
13882};
f6a92248 13883
64154835
TV
13884static struct hda_verb alc269_lifebook_verbs[] = {
13885 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13886 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13887 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13888 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13889 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13890 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13891 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13892 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13893 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13894 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13895 { }
13896};
13897
60db6b53
KY
13898/* toggle speaker-output according to the hp-jack state */
13899static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13900{
13901 unsigned int present;
13902 unsigned char bits;
f6a92248 13903
864f92be 13904 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13905 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 13906 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 13907 HDA_AMP_MUTE, bits);
60db6b53 13908 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 13909 HDA_AMP_MUTE, bits);
f6a92248 13910
60db6b53
KY
13911 snd_hda_codec_write(codec, 0x20, 0,
13912 AC_VERB_SET_COEF_INDEX, 0x0c);
13913 snd_hda_codec_write(codec, 0x20, 0,
13914 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 13915
60db6b53
KY
13916 snd_hda_codec_write(codec, 0x20, 0,
13917 AC_VERB_SET_COEF_INDEX, 0x0c);
13918 snd_hda_codec_write(codec, 0x20, 0,
13919 AC_VERB_SET_PROC_COEF, 0x480);
13920}
f6a92248 13921
64154835
TV
13922/* toggle speaker-output according to the hp-jacks state */
13923static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
13924{
13925 unsigned int present;
13926 unsigned char bits;
13927
13928 /* Check laptop headphone socket */
864f92be 13929 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
13930
13931 /* Check port replicator headphone socket */
864f92be 13932 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 13933
5dbd5ec6 13934 bits = present ? HDA_AMP_MUTE : 0;
64154835 13935 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 13936 HDA_AMP_MUTE, bits);
64154835 13937 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 13938 HDA_AMP_MUTE, bits);
64154835
TV
13939
13940 snd_hda_codec_write(codec, 0x20, 0,
13941 AC_VERB_SET_COEF_INDEX, 0x0c);
13942 snd_hda_codec_write(codec, 0x20, 0,
13943 AC_VERB_SET_PROC_COEF, 0x680);
13944
13945 snd_hda_codec_write(codec, 0x20, 0,
13946 AC_VERB_SET_COEF_INDEX, 0x0c);
13947 snd_hda_codec_write(codec, 0x20, 0,
13948 AC_VERB_SET_PROC_COEF, 0x480);
13949}
13950
64154835
TV
13951static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13952{
13953 unsigned int present_laptop;
13954 unsigned int present_dock;
13955
864f92be
WF
13956 present_laptop = snd_hda_jack_detect(codec, 0x18);
13957 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
13958
13959 /* Laptop mic port overrides dock mic port, design decision */
13960 if (present_dock)
13961 snd_hda_codec_write(codec, 0x23, 0,
13962 AC_VERB_SET_CONNECT_SEL, 0x3);
13963 if (present_laptop)
13964 snd_hda_codec_write(codec, 0x23, 0,
13965 AC_VERB_SET_CONNECT_SEL, 0x0);
13966 if (!present_dock && !present_laptop)
13967 snd_hda_codec_write(codec, 0x23, 0,
13968 AC_VERB_SET_CONNECT_SEL, 0x1);
13969}
13970
60db6b53
KY
13971static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13972 unsigned int res)
13973{
4f5d1706
TI
13974 switch (res >> 26) {
13975 case ALC880_HP_EVENT:
60db6b53 13976 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
13977 break;
13978 case ALC880_MIC_EVENT:
13979 alc_mic_automute(codec);
13980 break;
13981 }
60db6b53 13982}
f6a92248 13983
64154835
TV
13984static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13985 unsigned int res)
13986{
13987 if ((res >> 26) == ALC880_HP_EVENT)
13988 alc269_lifebook_speaker_automute(codec);
13989 if ((res >> 26) == ALC880_MIC_EVENT)
13990 alc269_lifebook_mic_autoswitch(codec);
13991}
13992
4f5d1706
TI
13993static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13994{
13995 struct alc_spec *spec = codec->spec;
20645d70
TI
13996 spec->autocfg.hp_pins[0] = 0x15;
13997 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13998 spec->ext_mic.pin = 0x18;
13999 spec->ext_mic.mux_idx = 0;
14000 spec->int_mic.pin = 0x19;
14001 spec->int_mic.mux_idx = 1;
14002 spec->auto_mic = 1;
14003}
14004
60db6b53
KY
14005static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14006{
14007 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14008 alc_mic_automute(codec);
60db6b53 14009}
f6a92248 14010
64154835
TV
14011static void alc269_lifebook_init_hook(struct hda_codec *codec)
14012{
14013 alc269_lifebook_speaker_automute(codec);
14014 alc269_lifebook_mic_autoswitch(codec);
14015}
14016
84898e87 14017static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14018 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14019 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14020 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14021 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14022 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14023 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14024 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14025 {}
14026};
14027
84898e87 14028static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14029 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14030 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14031 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14032 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14033 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14034 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14035 {}
14036};
14037
84898e87
KY
14038static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14039 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14040 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14041 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14042 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14043 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14044 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14045 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14046 {}
14047};
14048
14049static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14050 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14051 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14052 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14053 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14054 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14055 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14056 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14057 {}
14058};
14059
f53281e6
KY
14060/* toggle speaker-output according to the hp-jack state */
14061static void alc269_speaker_automute(struct hda_codec *codec)
14062{
ebb83eeb
KY
14063 struct alc_spec *spec = codec->spec;
14064 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 14065 unsigned int present;
60db6b53 14066 unsigned char bits;
f53281e6 14067
ebb83eeb 14068 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 14069 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 14070 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14071 HDA_AMP_MUTE, bits);
f53281e6 14072 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14073 HDA_AMP_MUTE, bits);
f53281e6
KY
14074}
14075
f53281e6 14076/* unsolicited event for HP jack sensing */
84898e87 14077static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 14078 unsigned int res)
f53281e6 14079{
4f5d1706
TI
14080 switch (res >> 26) {
14081 case ALC880_HP_EVENT:
f53281e6 14082 alc269_speaker_automute(codec);
4f5d1706
TI
14083 break;
14084 case ALC880_MIC_EVENT:
14085 alc_mic_automute(codec);
14086 break;
14087 }
f53281e6
KY
14088}
14089
226b1ec8 14090static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14091{
4f5d1706 14092 struct alc_spec *spec = codec->spec;
20645d70
TI
14093 spec->autocfg.hp_pins[0] = 0x15;
14094 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14095 spec->ext_mic.pin = 0x18;
14096 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14097 spec->int_mic.pin = 0x19;
14098 spec->int_mic.mux_idx = 1;
4f5d1706 14099 spec->auto_mic = 1;
f53281e6
KY
14100}
14101
226b1ec8 14102static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14103{
14104 struct alc_spec *spec = codec->spec;
20645d70
TI
14105 spec->autocfg.hp_pins[0] = 0x15;
14106 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
14107 spec->ext_mic.pin = 0x18;
14108 spec->ext_mic.mux_idx = 0;
14109 spec->int_mic.pin = 0x12;
226b1ec8 14110 spec->int_mic.mux_idx = 5;
84898e87
KY
14111 spec->auto_mic = 1;
14112}
14113
226b1ec8 14114static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14115{
4f5d1706 14116 struct alc_spec *spec = codec->spec;
226b1ec8 14117 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14118 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14119 spec->ext_mic.pin = 0x18;
14120 spec->ext_mic.mux_idx = 0;
14121 spec->int_mic.pin = 0x19;
14122 spec->int_mic.mux_idx = 1;
14123 spec->auto_mic = 1;
f53281e6
KY
14124}
14125
226b1ec8
KY
14126static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14127{
14128 struct alc_spec *spec = codec->spec;
14129 spec->autocfg.hp_pins[0] = 0x21;
14130 spec->autocfg.speaker_pins[0] = 0x14;
14131 spec->ext_mic.pin = 0x18;
14132 spec->ext_mic.mux_idx = 0;
14133 spec->int_mic.pin = 0x12;
14134 spec->int_mic.mux_idx = 6;
14135 spec->auto_mic = 1;
14136}
14137
84898e87 14138static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
14139{
14140 alc269_speaker_automute(codec);
4f5d1706 14141 alc_mic_automute(codec);
f53281e6
KY
14142}
14143
60db6b53
KY
14144/*
14145 * generic initialization of ADC, input mixers and output mixers
14146 */
14147static struct hda_verb alc269_init_verbs[] = {
14148 /*
14149 * Unmute ADC0 and set the default input to mic-in
14150 */
84898e87 14151 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14152
14153 /*
84898e87 14154 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14155 */
14156 /* set vol=0 to output mixers */
14157 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14158 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14159
14160 /* set up input amps for analog loopback */
14161 /* Amp Indices: DAC = 0, mixer = 1 */
14162 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14163 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14164 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14165 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14166 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14167 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14168
14169 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14170 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14171 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14172 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14173 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14174 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14175 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14176
14177 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14178 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14179
84898e87
KY
14180 /* FIXME: use Mux-type input source selection */
14181 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14182 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14183 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14184
84898e87
KY
14185 /* set EAPD */
14186 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14187 { }
14188};
14189
14190static struct hda_verb alc269vb_init_verbs[] = {
14191 /*
14192 * Unmute ADC0 and set the default input to mic-in
14193 */
14194 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14195
14196 /*
14197 * Set up output mixers (0x02 - 0x03)
14198 */
14199 /* set vol=0 to output mixers */
14200 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14201 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14202
14203 /* set up input amps for analog loopback */
14204 /* Amp Indices: DAC = 0, mixer = 1 */
14205 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14206 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14207 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14208 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14209 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14210 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14211
14212 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14213 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14214 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14215 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14216 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14217 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14218 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14219
14220 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14221 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14222
14223 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14224 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14225 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14226 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14227
14228 /* set EAPD */
14229 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14230 { }
14231};
14232
9d0b71b1
TI
14233#define alc269_auto_create_multi_out_ctls \
14234 alc268_auto_create_multi_out_ctls
05f5f477
TI
14235#define alc269_auto_create_input_ctls \
14236 alc268_auto_create_input_ctls
f6a92248
KY
14237
14238#ifdef CONFIG_SND_HDA_POWER_SAVE
14239#define alc269_loopbacks alc880_loopbacks
14240#endif
14241
def319f9 14242/* pcm configuration: identical with ALC880 */
f6a92248
KY
14243#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14244#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14245#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14246#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14247
f03d3115
TI
14248static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14249 .substreams = 1,
14250 .channels_min = 2,
14251 .channels_max = 8,
14252 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14253 /* NID is set in alc_build_pcms */
14254 .ops = {
14255 .open = alc880_playback_pcm_open,
14256 .prepare = alc880_playback_pcm_prepare,
14257 .cleanup = alc880_playback_pcm_cleanup
14258 },
14259};
14260
14261static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14262 .substreams = 1,
14263 .channels_min = 2,
14264 .channels_max = 2,
14265 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14266 /* NID is set in alc_build_pcms */
14267};
14268
ad35879a
TI
14269#ifdef CONFIG_SND_HDA_POWER_SAVE
14270static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14271{
14272 switch (codec->subsystem_id) {
14273 case 0x103c1586:
14274 return 1;
14275 }
14276 return 0;
14277}
14278
14279static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14280{
14281 /* update mute-LED according to the speaker mute state */
14282 if (nid == 0x01 || nid == 0x14) {
14283 int pinval;
14284 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14285 HDA_AMP_MUTE)
14286 pinval = 0x24;
14287 else
14288 pinval = 0x20;
14289 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14290 snd_hda_codec_update_cache(codec, 0x19, 0,
14291 AC_VERB_SET_PIN_WIDGET_CONTROL,
14292 pinval);
ad35879a
TI
14293 }
14294 return alc_check_power_status(codec, nid);
14295}
14296#endif /* CONFIG_SND_HDA_POWER_SAVE */
14297
840b64c0
TI
14298static int alc275_setup_dual_adc(struct hda_codec *codec)
14299{
14300 struct alc_spec *spec = codec->spec;
14301
14302 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14303 return 0;
14304 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14305 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14306 if (spec->ext_mic.pin <= 0x12) {
14307 spec->private_adc_nids[0] = 0x08;
14308 spec->private_adc_nids[1] = 0x11;
14309 spec->private_capsrc_nids[0] = 0x23;
14310 spec->private_capsrc_nids[1] = 0x22;
14311 } else {
14312 spec->private_adc_nids[0] = 0x11;
14313 spec->private_adc_nids[1] = 0x08;
14314 spec->private_capsrc_nids[0] = 0x22;
14315 spec->private_capsrc_nids[1] = 0x23;
14316 }
14317 spec->adc_nids = spec->private_adc_nids;
14318 spec->capsrc_nids = spec->private_capsrc_nids;
14319 spec->num_adc_nids = 2;
14320 spec->dual_adc_switch = 1;
14321 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14322 spec->adc_nids[0], spec->adc_nids[1]);
14323 return 1;
14324 }
14325 return 0;
14326}
14327
f6a92248
KY
14328/*
14329 * BIOS auto configuration
14330 */
14331static int alc269_parse_auto_config(struct hda_codec *codec)
14332{
14333 struct alc_spec *spec = codec->spec;
cfb9fb55 14334 int err;
f6a92248
KY
14335 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14336
14337 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14338 alc269_ignore);
14339 if (err < 0)
14340 return err;
14341
14342 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14343 if (err < 0)
14344 return err;
05f5f477 14345 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
f6a92248
KY
14346 if (err < 0)
14347 return err;
14348
14349 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14350
757899ac 14351 alc_auto_parse_digital(codec);
f6a92248 14352
603c4019 14353 if (spec->kctls.list)
d88897ea 14354 add_mixer(spec, spec->kctls.list);
f6a92248 14355
84898e87
KY
14356 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
14357 add_verb(spec, alc269vb_init_verbs);
6227cdce 14358 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14359 } else {
14360 add_verb(spec, alc269_init_verbs);
6227cdce 14361 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14362 }
14363
f6a92248 14364 spec->num_mux_defs = 1;
61b9b9b1 14365 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14366
14367 if (!alc275_setup_dual_adc(codec))
14368 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14369 sizeof(alc269_adc_candidates));
6694635d 14370
e01bf509 14371 /* set default input source */
840b64c0 14372 if (!spec->dual_adc_switch)
748cce43
TI
14373 select_or_unmute_capsrc(codec, spec->capsrc_nids[0],
14374 spec->input_mux->items[0].index);
f6a92248
KY
14375
14376 err = alc_auto_add_mic_boost(codec);
14377 if (err < 0)
14378 return err;
14379
7e0e44d4 14380 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14381 set_capture_mixer(codec);
f53281e6 14382
f6a92248
KY
14383 return 1;
14384}
14385
e9af4f36
TI
14386#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14387#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14388#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14389
14390
14391/* init callback for auto-configuration model -- overriding the default init */
14392static void alc269_auto_init(struct hda_codec *codec)
14393{
f6c7e546 14394 struct alc_spec *spec = codec->spec;
f6a92248
KY
14395 alc269_auto_init_multi_out(codec);
14396 alc269_auto_init_hp_out(codec);
14397 alc269_auto_init_analog_input(codec);
757899ac 14398 alc_auto_init_digital(codec);
f6c7e546 14399 if (spec->unsol_event)
7fb0d78f 14400 alc_inithook(codec);
f6a92248
KY
14401}
14402
ff818c24
TI
14403enum {
14404 ALC269_FIXUP_SONY_VAIO,
14405};
14406
fbc25669 14407static const struct hda_verb alc269_sony_vaio_fixup_verbs[] = {
ff818c24
TI
14408 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14409 {}
14410};
14411
14412static const struct alc_fixup alc269_fixups[] = {
14413 [ALC269_FIXUP_SONY_VAIO] = {
14414 .verbs = alc269_sony_vaio_fixup_verbs
14415 },
14416};
14417
14418static struct snd_pci_quirk alc269_fixup_tbl[] = {
14419 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14420 {}
14421};
14422
14423
f6a92248
KY
14424/*
14425 * configuration and preset
14426 */
14427static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14428 [ALC269_BASIC] = "basic",
2922c9af 14429 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14430 [ALC269_AMIC] = "laptop-amic",
14431 [ALC269_DMIC] = "laptop-dmic",
64154835 14432 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14433 [ALC269_LIFEBOOK] = "lifebook",
14434 [ALC269_AUTO] = "auto",
f6a92248
KY
14435};
14436
14437static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14438 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
f53281e6 14439 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14440 ALC269_AMIC),
14441 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14442 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14443 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14444 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14445 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14446 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14447 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14448 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14449 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14450 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14451 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14452 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14453 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14454 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14455 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14456 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14457 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14458 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14459 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14460 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14461 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14462 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14463 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14464 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14465 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14466 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14467 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14468 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14469 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14470 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14471 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14472 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14473 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14474 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14475 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14476 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14477 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14478 ALC269_DMIC),
60db6b53 14479 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14480 ALC269_DMIC),
14481 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14482 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14483 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14484 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14485 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14486 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14487 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14488 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14489 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14490 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14491 {}
14492};
14493
14494static struct alc_config_preset alc269_presets[] = {
14495 [ALC269_BASIC] = {
f9e336f6 14496 .mixers = { alc269_base_mixer },
f6a92248
KY
14497 .init_verbs = { alc269_init_verbs },
14498 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14499 .dac_nids = alc269_dac_nids,
14500 .hp_nid = 0x03,
14501 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14502 .channel_mode = alc269_modes,
14503 .input_mux = &alc269_capture_source,
14504 },
60db6b53
KY
14505 [ALC269_QUANTA_FL1] = {
14506 .mixers = { alc269_quanta_fl1_mixer },
14507 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14508 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14509 .dac_nids = alc269_dac_nids,
14510 .hp_nid = 0x03,
14511 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14512 .channel_mode = alc269_modes,
14513 .input_mux = &alc269_capture_source,
14514 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 14515 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
14516 .init_hook = alc269_quanta_fl1_init_hook,
14517 },
84898e87
KY
14518 [ALC269_AMIC] = {
14519 .mixers = { alc269_laptop_mixer },
14520 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 14521 .init_verbs = { alc269_init_verbs,
84898e87 14522 alc269_laptop_amic_init_verbs },
f53281e6
KY
14523 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14524 .dac_nids = alc269_dac_nids,
14525 .hp_nid = 0x03,
14526 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14527 .channel_mode = alc269_modes,
84898e87
KY
14528 .unsol_event = alc269_laptop_unsol_event,
14529 .setup = alc269_laptop_amic_setup,
14530 .init_hook = alc269_laptop_inithook,
f53281e6 14531 },
84898e87
KY
14532 [ALC269_DMIC] = {
14533 .mixers = { alc269_laptop_mixer },
14534 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 14535 .init_verbs = { alc269_init_verbs,
84898e87
KY
14536 alc269_laptop_dmic_init_verbs },
14537 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14538 .dac_nids = alc269_dac_nids,
14539 .hp_nid = 0x03,
14540 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14541 .channel_mode = alc269_modes,
14542 .unsol_event = alc269_laptop_unsol_event,
14543 .setup = alc269_laptop_dmic_setup,
14544 .init_hook = alc269_laptop_inithook,
14545 },
14546 [ALC269VB_AMIC] = {
14547 .mixers = { alc269vb_laptop_mixer },
14548 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14549 .init_verbs = { alc269vb_init_verbs,
14550 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
14551 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14552 .dac_nids = alc269_dac_nids,
14553 .hp_nid = 0x03,
14554 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14555 .channel_mode = alc269_modes,
84898e87 14556 .unsol_event = alc269_laptop_unsol_event,
226b1ec8 14557 .setup = alc269vb_laptop_amic_setup,
84898e87
KY
14558 .init_hook = alc269_laptop_inithook,
14559 },
14560 [ALC269VB_DMIC] = {
14561 .mixers = { alc269vb_laptop_mixer },
14562 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14563 .init_verbs = { alc269vb_init_verbs,
14564 alc269vb_laptop_dmic_init_verbs },
14565 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14566 .dac_nids = alc269_dac_nids,
14567 .hp_nid = 0x03,
14568 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14569 .channel_mode = alc269_modes,
14570 .unsol_event = alc269_laptop_unsol_event,
14571 .setup = alc269vb_laptop_dmic_setup,
14572 .init_hook = alc269_laptop_inithook,
f53281e6 14573 },
26f5df26 14574 [ALC269_FUJITSU] = {
45bdd1c1 14575 .mixers = { alc269_fujitsu_mixer },
84898e87 14576 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 14577 .init_verbs = { alc269_init_verbs,
84898e87 14578 alc269_laptop_dmic_init_verbs },
26f5df26
TI
14579 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14580 .dac_nids = alc269_dac_nids,
14581 .hp_nid = 0x03,
14582 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14583 .channel_mode = alc269_modes,
84898e87
KY
14584 .unsol_event = alc269_laptop_unsol_event,
14585 .setup = alc269_laptop_dmic_setup,
14586 .init_hook = alc269_laptop_inithook,
26f5df26 14587 },
64154835
TV
14588 [ALC269_LIFEBOOK] = {
14589 .mixers = { alc269_lifebook_mixer },
14590 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14591 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14592 .dac_nids = alc269_dac_nids,
14593 .hp_nid = 0x03,
14594 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14595 .channel_mode = alc269_modes,
14596 .input_mux = &alc269_capture_source,
14597 .unsol_event = alc269_lifebook_unsol_event,
14598 .init_hook = alc269_lifebook_init_hook,
14599 },
f6a92248
KY
14600};
14601
14602static int patch_alc269(struct hda_codec *codec)
14603{
14604 struct alc_spec *spec;
14605 int board_config;
14606 int err;
84898e87 14607 int is_alc269vb = 0;
f6a92248
KY
14608
14609 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14610 if (spec == NULL)
14611 return -ENOMEM;
14612
14613 codec->spec = spec;
14614
da00c244
KY
14615 alc_auto_parse_customize_define(codec);
14616
274693f3 14617 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
c027ddcd
KY
14618 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
14619 spec->cdefine.platform_type == 1)
14620 alc_codec_rename(codec, "ALC271X");
14621 else
14622 alc_codec_rename(codec, "ALC259");
84898e87 14623 is_alc269vb = 1;
c027ddcd
KY
14624 } else
14625 alc_fix_pll_init(codec, 0x20, 0x04, 15);
274693f3 14626
f6a92248
KY
14627 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14628 alc269_models,
14629 alc269_cfg_tbl);
14630
14631 if (board_config < 0) {
9a11f1aa
TI
14632 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14633 codec->chip_name);
f6a92248
KY
14634 board_config = ALC269_AUTO;
14635 }
14636
ff818c24
TI
14637 if (board_config == ALC269_AUTO)
14638 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
14639
f6a92248
KY
14640 if (board_config == ALC269_AUTO) {
14641 /* automatic parse from the BIOS config */
14642 err = alc269_parse_auto_config(codec);
14643 if (err < 0) {
14644 alc_free(codec);
14645 return err;
14646 } else if (!err) {
14647 printk(KERN_INFO
14648 "hda_codec: Cannot set up configuration "
14649 "from BIOS. Using base mode...\n");
14650 board_config = ALC269_BASIC;
14651 }
14652 }
14653
dc1eae25 14654 if (has_cdefine_beep(codec)) {
8af2591d
TI
14655 err = snd_hda_attach_beep_device(codec, 0x1);
14656 if (err < 0) {
14657 alc_free(codec);
14658 return err;
14659 }
680cd536
KK
14660 }
14661
f6a92248 14662 if (board_config != ALC269_AUTO)
e9c364c0 14663 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 14664
84898e87 14665 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
14666 /* Due to a hardware problem on Lenovo Ideadpad, we need to
14667 * fix the sample rate of analog I/O to 44.1kHz
14668 */
14669 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
14670 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
14671 } else if (spec->dual_adc_switch) {
14672 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14673 /* switch ADC dynamically */
14674 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
14675 } else {
14676 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14677 spec->stream_analog_capture = &alc269_pcm_analog_capture;
14678 }
f6a92248
KY
14679 spec->stream_digital_playback = &alc269_pcm_digital_playback;
14680 spec->stream_digital_capture = &alc269_pcm_digital_capture;
14681
6694635d
TI
14682 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
14683 if (!is_alc269vb) {
14684 spec->adc_nids = alc269_adc_nids;
14685 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
14686 spec->capsrc_nids = alc269_capsrc_nids;
14687 } else {
14688 spec->adc_nids = alc269vb_adc_nids;
14689 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
14690 spec->capsrc_nids = alc269vb_capsrc_nids;
14691 }
84898e87
KY
14692 }
14693
f9e336f6 14694 if (!spec->cap_mixer)
b59bdf3b 14695 set_capture_mixer(codec);
dc1eae25 14696 if (has_cdefine_beep(codec))
da00c244 14697 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 14698
ff818c24
TI
14699 if (board_config == ALC269_AUTO)
14700 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
14701
100d5eb3
TI
14702 spec->vmaster_nid = 0x02;
14703
f6a92248
KY
14704 codec->patch_ops = alc_patch_ops;
14705 if (board_config == ALC269_AUTO)
14706 spec->init_hook = alc269_auto_init;
14707#ifdef CONFIG_SND_HDA_POWER_SAVE
14708 if (!spec->loopback.amplist)
14709 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
14710 if (alc269_mic2_for_mute_led(codec))
14711 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
14712#endif
14713
14714 return 0;
14715}
14716
df694daa
KY
14717/*
14718 * ALC861 channel source setting (2/6 channel selection for 3-stack)
14719 */
14720
14721/*
14722 * set the path ways for 2 channel output
14723 * need to set the codec line out and mic 1 pin widgets to inputs
14724 */
14725static struct hda_verb alc861_threestack_ch2_init[] = {
14726 /* set pin widget 1Ah (line in) for input */
14727 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14728 /* set pin widget 18h (mic1/2) for input, for mic also enable
14729 * the vref
14730 */
df694daa
KY
14731 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14732
9c7f852e
TI
14733 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14734#if 0
14735 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14736 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14737#endif
df694daa
KY
14738 { } /* end */
14739};
14740/*
14741 * 6ch mode
14742 * need to set the codec line out and mic 1 pin widgets to outputs
14743 */
14744static struct hda_verb alc861_threestack_ch6_init[] = {
14745 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14746 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14747 /* set pin widget 18h (mic1) for output (CLFE)*/
14748 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14749
14750 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 14751 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 14752
9c7f852e
TI
14753 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14754#if 0
14755 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14756 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14757#endif
df694daa
KY
14758 { } /* end */
14759};
14760
14761static struct hda_channel_mode alc861_threestack_modes[2] = {
14762 { 2, alc861_threestack_ch2_init },
14763 { 6, alc861_threestack_ch6_init },
14764};
22309c3e
TI
14765/* Set mic1 as input and unmute the mixer */
14766static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
14767 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14768 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14769 { } /* end */
14770};
14771/* Set mic1 as output and mute mixer */
14772static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
14773 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14774 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14775 { } /* end */
14776};
14777
14778static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
14779 { 2, alc861_uniwill_m31_ch2_init },
14780 { 4, alc861_uniwill_m31_ch4_init },
14781};
df694daa 14782
7cdbff94
MD
14783/* Set mic1 and line-in as input and unmute the mixer */
14784static struct hda_verb alc861_asus_ch2_init[] = {
14785 /* set pin widget 1Ah (line in) for input */
14786 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14787 /* set pin widget 18h (mic1/2) for input, for mic also enable
14788 * the vref
14789 */
7cdbff94
MD
14790 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14791
14792 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14793#if 0
14794 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14795 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14796#endif
14797 { } /* end */
14798};
14799/* Set mic1 nad line-in as output and mute mixer */
14800static struct hda_verb alc861_asus_ch6_init[] = {
14801 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14802 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14803 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14804 /* set pin widget 18h (mic1) for output (CLFE)*/
14805 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14806 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14807 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14808 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14809
14810 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14811#if 0
14812 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14813 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14814#endif
14815 { } /* end */
14816};
14817
14818static struct hda_channel_mode alc861_asus_modes[2] = {
14819 { 2, alc861_asus_ch2_init },
14820 { 6, alc861_asus_ch6_init },
14821};
14822
df694daa
KY
14823/* patch-ALC861 */
14824
14825static struct snd_kcontrol_new alc861_base_mixer[] = {
14826 /* output mixer control */
14827 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14828 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14829 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14830 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14831 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14832
14833 /*Input mixer control */
14834 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14835 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14836 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14837 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14838 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14839 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14840 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14841 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14842 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14843 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14844
df694daa
KY
14845 { } /* end */
14846};
14847
14848static struct snd_kcontrol_new alc861_3ST_mixer[] = {
14849 /* output mixer control */
14850 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14851 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14852 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14853 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14854 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14855
14856 /* Input mixer control */
14857 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14858 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14859 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14860 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14861 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14862 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14863 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14864 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14865 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14866 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14867
df694daa
KY
14868 {
14869 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14870 .name = "Channel Mode",
14871 .info = alc_ch_mode_info,
14872 .get = alc_ch_mode_get,
14873 .put = alc_ch_mode_put,
14874 .private_value = ARRAY_SIZE(alc861_threestack_modes),
14875 },
14876 { } /* end */
a53d1aec
TD
14877};
14878
d1d985f0 14879static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
14880 /* output mixer control */
14881 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14882 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14883 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 14884
a53d1aec 14885 { } /* end */
f12ab1e0 14886};
a53d1aec 14887
22309c3e
TI
14888static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
14889 /* output mixer control */
14890 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14891 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14892 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14893 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14894 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14895
14896 /* Input mixer control */
14897 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14898 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14899 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14900 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14901 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14902 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14903 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14904 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14905 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14906 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14907
22309c3e
TI
14908 {
14909 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14910 .name = "Channel Mode",
14911 .info = alc_ch_mode_info,
14912 .get = alc_ch_mode_get,
14913 .put = alc_ch_mode_put,
14914 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
14915 },
14916 { } /* end */
f12ab1e0 14917};
7cdbff94
MD
14918
14919static struct snd_kcontrol_new alc861_asus_mixer[] = {
14920 /* output mixer control */
14921 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14922 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14923 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14924 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14925 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14926
14927 /* Input mixer control */
14928 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14929 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14930 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14931 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14932 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14933 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14934 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14935 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14936 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
14937 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
14938
7cdbff94
MD
14939 {
14940 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14941 .name = "Channel Mode",
14942 .info = alc_ch_mode_info,
14943 .get = alc_ch_mode_get,
14944 .put = alc_ch_mode_put,
14945 .private_value = ARRAY_SIZE(alc861_asus_modes),
14946 },
14947 { }
56bb0cab
TI
14948};
14949
14950/* additional mixer */
d1d985f0 14951static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
14952 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14953 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
14954 { }
14955};
7cdbff94 14956
df694daa
KY
14957/*
14958 * generic initialization of ADC, input mixers and output mixers
14959 */
14960static struct hda_verb alc861_base_init_verbs[] = {
14961 /*
14962 * Unmute ADC0 and set the default input to mic-in
14963 */
14964 /* port-A for surround (rear panel) */
14965 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14966 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
14967 /* port-B for mic-in (rear panel) with vref */
14968 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14969 /* port-C for line-in (rear panel) */
14970 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14971 /* port-D for Front */
14972 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14973 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14974 /* port-E for HP out (front panel) */
14975 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
14976 /* route front PCM to HP */
9dece1d7 14977 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
14978 /* port-F for mic-in (front panel) with vref */
14979 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14980 /* port-G for CLFE (rear panel) */
14981 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14982 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14983 /* port-H for side (rear panel) */
14984 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14985 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
14986 /* CD-in */
14987 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14988 /* route front mic to ADC1*/
14989 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14990 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 14991
df694daa
KY
14992 /* Unmute DAC0~3 & spdif out*/
14993 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14994 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14995 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14996 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14997 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 14998
df694daa
KY
14999 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15000 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15001 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15002 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15003 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15004
df694daa
KY
15005 /* Unmute Stereo Mixer 15 */
15006 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15007 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15008 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15009 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15010
15011 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15012 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15013 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15014 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15015 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15016 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15017 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15018 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15019 /* hp used DAC 3 (Front) */
15020 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15021 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15022
15023 { }
15024};
15025
15026static struct hda_verb alc861_threestack_init_verbs[] = {
15027 /*
15028 * Unmute ADC0 and set the default input to mic-in
15029 */
15030 /* port-A for surround (rear panel) */
15031 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15032 /* port-B for mic-in (rear panel) with vref */
15033 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15034 /* port-C for line-in (rear panel) */
15035 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15036 /* port-D for Front */
15037 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15038 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15039 /* port-E for HP out (front panel) */
15040 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15041 /* route front PCM to HP */
9dece1d7 15042 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15043 /* port-F for mic-in (front panel) with vref */
15044 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15045 /* port-G for CLFE (rear panel) */
15046 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15047 /* port-H for side (rear panel) */
15048 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15049 /* CD-in */
15050 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15051 /* route front mic to ADC1*/
15052 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15053 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15054 /* Unmute DAC0~3 & spdif out*/
15055 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15056 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15057 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15058 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15059 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15060
df694daa
KY
15061 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15062 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15063 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15064 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15065 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15066
df694daa
KY
15067 /* Unmute Stereo Mixer 15 */
15068 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15069 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15070 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15071 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15072
15073 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15074 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15075 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15076 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15077 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15078 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15079 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15080 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15081 /* hp used DAC 3 (Front) */
15082 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15083 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15084 { }
15085};
22309c3e
TI
15086
15087static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15088 /*
15089 * Unmute ADC0 and set the default input to mic-in
15090 */
15091 /* port-A for surround (rear panel) */
15092 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15093 /* port-B for mic-in (rear panel) with vref */
15094 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15095 /* port-C for line-in (rear panel) */
15096 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15097 /* port-D for Front */
15098 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15099 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15100 /* port-E for HP out (front panel) */
f12ab1e0
TI
15101 /* this has to be set to VREF80 */
15102 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15103 /* route front PCM to HP */
9dece1d7 15104 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15105 /* port-F for mic-in (front panel) with vref */
15106 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15107 /* port-G for CLFE (rear panel) */
15108 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15109 /* port-H for side (rear panel) */
15110 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15111 /* CD-in */
15112 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15113 /* route front mic to ADC1*/
15114 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15115 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15116 /* Unmute DAC0~3 & spdif out*/
15117 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15118 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15119 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15120 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15121 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15122
22309c3e
TI
15123 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15124 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15125 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15126 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15127 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15128
22309c3e
TI
15129 /* Unmute Stereo Mixer 15 */
15130 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15131 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15132 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15133 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15134
15135 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15136 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15137 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15138 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15139 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15140 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15141 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15142 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15143 /* hp used DAC 3 (Front) */
15144 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15145 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15146 { }
15147};
15148
7cdbff94
MD
15149static struct hda_verb alc861_asus_init_verbs[] = {
15150 /*
15151 * Unmute ADC0 and set the default input to mic-in
15152 */
f12ab1e0
TI
15153 /* port-A for surround (rear panel)
15154 * according to codec#0 this is the HP jack
15155 */
7cdbff94
MD
15156 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15157 /* route front PCM to HP */
15158 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15159 /* port-B for mic-in (rear panel) with vref */
15160 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15161 /* port-C for line-in (rear panel) */
15162 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15163 /* port-D for Front */
15164 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15165 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15166 /* port-E for HP out (front panel) */
f12ab1e0
TI
15167 /* this has to be set to VREF80 */
15168 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15169 /* route front PCM to HP */
9dece1d7 15170 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15171 /* port-F for mic-in (front panel) with vref */
15172 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15173 /* port-G for CLFE (rear panel) */
15174 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15175 /* port-H for side (rear panel) */
15176 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15177 /* CD-in */
15178 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15179 /* route front mic to ADC1*/
15180 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15181 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15182 /* Unmute DAC0~3 & spdif out*/
15183 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15184 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15185 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15186 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15187 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15188 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15189 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15190 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15191 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15192 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15193
7cdbff94
MD
15194 /* Unmute Stereo Mixer 15 */
15195 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15196 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15197 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15198 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15199
15200 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15201 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15202 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15203 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15204 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15205 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15206 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15207 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15208 /* hp used DAC 3 (Front) */
15209 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15210 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15211 { }
15212};
15213
56bb0cab
TI
15214/* additional init verbs for ASUS laptops */
15215static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15216 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15217 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15218 { }
15219};
7cdbff94 15220
df694daa
KY
15221/*
15222 * generic initialization of ADC, input mixers and output mixers
15223 */
15224static struct hda_verb alc861_auto_init_verbs[] = {
15225 /*
15226 * Unmute ADC0 and set the default input to mic-in
15227 */
f12ab1e0 15228 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15229 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15230
df694daa
KY
15231 /* Unmute DAC0~3 & spdif out*/
15232 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15233 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15234 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15235 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15236 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15237
df694daa
KY
15238 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15239 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15240 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15241 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15242 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15243
df694daa
KY
15244 /* Unmute Stereo Mixer 15 */
15245 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15246 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15247 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15248 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15249
1c20930a
TI
15250 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15251 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15252 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15253 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15254 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15255 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15256 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15257 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15258
15259 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15260 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15261 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15262 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15263 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15264 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15265 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15266 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15267
f12ab1e0 15268 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15269
15270 { }
15271};
15272
a53d1aec
TD
15273static struct hda_verb alc861_toshiba_init_verbs[] = {
15274 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15275
a53d1aec
TD
15276 { }
15277};
15278
15279/* toggle speaker-output according to the hp-jack state */
15280static void alc861_toshiba_automute(struct hda_codec *codec)
15281{
864f92be 15282 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15283
47fd830a
TI
15284 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15285 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15286 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15287 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15288}
15289
15290static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15291 unsigned int res)
15292{
a53d1aec
TD
15293 if ((res >> 26) == ALC880_HP_EVENT)
15294 alc861_toshiba_automute(codec);
15295}
15296
def319f9 15297/* pcm configuration: identical with ALC880 */
df694daa
KY
15298#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15299#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15300#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15301#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15302
15303
15304#define ALC861_DIGOUT_NID 0x07
15305
15306static struct hda_channel_mode alc861_8ch_modes[1] = {
15307 { 8, NULL }
15308};
15309
15310static hda_nid_t alc861_dac_nids[4] = {
15311 /* front, surround, clfe, side */
15312 0x03, 0x06, 0x05, 0x04
15313};
15314
9c7f852e
TI
15315static hda_nid_t alc660_dac_nids[3] = {
15316 /* front, clfe, surround */
15317 0x03, 0x05, 0x06
15318};
15319
df694daa
KY
15320static hda_nid_t alc861_adc_nids[1] = {
15321 /* ADC0-2 */
15322 0x08,
15323};
15324
15325static struct hda_input_mux alc861_capture_source = {
15326 .num_items = 5,
15327 .items = {
15328 { "Mic", 0x0 },
15329 { "Front Mic", 0x3 },
15330 { "Line", 0x1 },
15331 { "CD", 0x4 },
15332 { "Mixer", 0x5 },
15333 },
15334};
15335
1c20930a
TI
15336static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15337{
15338 struct alc_spec *spec = codec->spec;
15339 hda_nid_t mix, srcs[5];
15340 int i, j, num;
15341
15342 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15343 return 0;
15344 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15345 if (num < 0)
15346 return 0;
15347 for (i = 0; i < num; i++) {
15348 unsigned int type;
a22d543a 15349 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15350 if (type != AC_WID_AUD_OUT)
15351 continue;
15352 for (j = 0; j < spec->multiout.num_dacs; j++)
15353 if (spec->multiout.dac_nids[j] == srcs[i])
15354 break;
15355 if (j >= spec->multiout.num_dacs)
15356 return srcs[i];
15357 }
15358 return 0;
15359}
15360
df694daa 15361/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15362static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15363 const struct auto_pin_cfg *cfg)
df694daa 15364{
1c20930a 15365 struct alc_spec *spec = codec->spec;
df694daa 15366 int i;
1c20930a 15367 hda_nid_t nid, dac;
df694daa
KY
15368
15369 spec->multiout.dac_nids = spec->private_dac_nids;
15370 for (i = 0; i < cfg->line_outs; i++) {
15371 nid = cfg->line_out_pins[i];
1c20930a
TI
15372 dac = alc861_look_for_dac(codec, nid);
15373 if (!dac)
15374 continue;
15375 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15376 }
df694daa
KY
15377 return 0;
15378}
15379
1c20930a
TI
15380static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15381 hda_nid_t nid, unsigned int chs)
15382{
0afe5f89 15383 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
1c20930a
TI
15384 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15385}
15386
df694daa 15387/* add playback controls from the parsed DAC table */
1c20930a 15388static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15389 const struct auto_pin_cfg *cfg)
15390{
1c20930a 15391 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
15392 static const char *chname[4] = {
15393 "Front", "Surround", NULL /*CLFE*/, "Side"
15394 };
df694daa 15395 hda_nid_t nid;
1c20930a
TI
15396 int i, err;
15397
15398 if (cfg->line_outs == 1) {
15399 const char *pfx = NULL;
15400 if (!cfg->hp_outs)
15401 pfx = "Master";
15402 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15403 pfx = "Speaker";
15404 if (pfx) {
15405 nid = spec->multiout.dac_nids[0];
15406 return alc861_create_out_sw(codec, pfx, nid, 3);
15407 }
15408 }
df694daa
KY
15409
15410 for (i = 0; i < cfg->line_outs; i++) {
15411 nid = spec->multiout.dac_nids[i];
f12ab1e0 15412 if (!nid)
df694daa 15413 continue;
1c20930a 15414 if (i == 2) {
df694daa 15415 /* Center/LFE */
1c20930a 15416 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15417 if (err < 0)
df694daa 15418 return err;
1c20930a 15419 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15420 if (err < 0)
df694daa
KY
15421 return err;
15422 } else {
1c20930a 15423 err = alc861_create_out_sw(codec, chname[i], nid, 3);
f12ab1e0 15424 if (err < 0)
df694daa
KY
15425 return err;
15426 }
15427 }
15428 return 0;
15429}
15430
1c20930a 15431static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 15432{
1c20930a 15433 struct alc_spec *spec = codec->spec;
df694daa
KY
15434 int err;
15435 hda_nid_t nid;
15436
f12ab1e0 15437 if (!pin)
df694daa
KY
15438 return 0;
15439
15440 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
15441 nid = alc861_look_for_dac(codec, pin);
15442 if (nid) {
15443 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15444 if (err < 0)
15445 return err;
15446 spec->multiout.hp_nid = nid;
15447 }
df694daa
KY
15448 }
15449 return 0;
15450}
15451
15452/* create playback/capture controls for input pins */
05f5f477 15453static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 15454 const struct auto_pin_cfg *cfg)
df694daa 15455{
05f5f477 15456 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
15457}
15458
f12ab1e0
TI
15459static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15460 hda_nid_t nid,
1c20930a 15461 int pin_type, hda_nid_t dac)
df694daa 15462{
1c20930a
TI
15463 hda_nid_t mix, srcs[5];
15464 int i, num;
15465
564c5bea
JL
15466 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15467 pin_type);
1c20930a 15468 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 15469 AMP_OUT_UNMUTE);
1c20930a
TI
15470 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15471 return;
15472 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15473 if (num < 0)
15474 return;
15475 for (i = 0; i < num; i++) {
15476 unsigned int mute;
15477 if (srcs[i] == dac || srcs[i] == 0x15)
15478 mute = AMP_IN_UNMUTE(i);
15479 else
15480 mute = AMP_IN_MUTE(i);
15481 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15482 mute);
15483 }
df694daa
KY
15484}
15485
15486static void alc861_auto_init_multi_out(struct hda_codec *codec)
15487{
15488 struct alc_spec *spec = codec->spec;
15489 int i;
15490
15491 for (i = 0; i < spec->autocfg.line_outs; i++) {
15492 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 15493 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 15494 if (nid)
baba8ee9 15495 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 15496 spec->multiout.dac_nids[i]);
df694daa
KY
15497 }
15498}
15499
15500static void alc861_auto_init_hp_out(struct hda_codec *codec)
15501{
15502 struct alc_spec *spec = codec->spec;
df694daa 15503
15870f05
TI
15504 if (spec->autocfg.hp_outs)
15505 alc861_auto_set_output_and_unmute(codec,
15506 spec->autocfg.hp_pins[0],
15507 PIN_HP,
1c20930a 15508 spec->multiout.hp_nid);
15870f05
TI
15509 if (spec->autocfg.speaker_outs)
15510 alc861_auto_set_output_and_unmute(codec,
15511 spec->autocfg.speaker_pins[0],
15512 PIN_OUT,
1c20930a 15513 spec->multiout.dac_nids[0]);
df694daa
KY
15514}
15515
15516static void alc861_auto_init_analog_input(struct hda_codec *codec)
15517{
15518 struct alc_spec *spec = codec->spec;
15519 int i;
15520
15521 for (i = 0; i < AUTO_PIN_LAST; i++) {
15522 hda_nid_t nid = spec->autocfg.input_pins[i];
23f0c048
TI
15523 if (nid >= 0x0c && nid <= 0x11)
15524 alc_set_input_pin(codec, nid, i);
df694daa
KY
15525 }
15526}
15527
15528/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
15529/* return 1 if successful, 0 if the proper config is not found,
15530 * or a negative error code
15531 */
df694daa
KY
15532static int alc861_parse_auto_config(struct hda_codec *codec)
15533{
15534 struct alc_spec *spec = codec->spec;
15535 int err;
15536 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
15537
f12ab1e0
TI
15538 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15539 alc861_ignore);
15540 if (err < 0)
df694daa 15541 return err;
f12ab1e0 15542 if (!spec->autocfg.line_outs)
df694daa
KY
15543 return 0; /* can't find valid BIOS pin config */
15544
1c20930a 15545 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
15546 if (err < 0)
15547 return err;
1c20930a 15548 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
15549 if (err < 0)
15550 return err;
1c20930a 15551 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
15552 if (err < 0)
15553 return err;
05f5f477 15554 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 15555 if (err < 0)
df694daa
KY
15556 return err;
15557
15558 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15559
757899ac 15560 alc_auto_parse_digital(codec);
df694daa 15561
603c4019 15562 if (spec->kctls.list)
d88897ea 15563 add_mixer(spec, spec->kctls.list);
df694daa 15564
d88897ea 15565 add_verb(spec, alc861_auto_init_verbs);
df694daa 15566
a1e8d2da 15567 spec->num_mux_defs = 1;
61b9b9b1 15568 spec->input_mux = &spec->private_imux[0];
df694daa
KY
15569
15570 spec->adc_nids = alc861_adc_nids;
15571 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 15572 set_capture_mixer(codec);
df694daa 15573
6227cdce 15574 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 15575
df694daa
KY
15576 return 1;
15577}
15578
ae6b813a
TI
15579/* additional initialization for auto-configuration model */
15580static void alc861_auto_init(struct hda_codec *codec)
df694daa 15581{
f6c7e546 15582 struct alc_spec *spec = codec->spec;
df694daa
KY
15583 alc861_auto_init_multi_out(codec);
15584 alc861_auto_init_hp_out(codec);
15585 alc861_auto_init_analog_input(codec);
757899ac 15586 alc_auto_init_digital(codec);
f6c7e546 15587 if (spec->unsol_event)
7fb0d78f 15588 alc_inithook(codec);
df694daa
KY
15589}
15590
cb53c626
TI
15591#ifdef CONFIG_SND_HDA_POWER_SAVE
15592static struct hda_amp_list alc861_loopbacks[] = {
15593 { 0x15, HDA_INPUT, 0 },
15594 { 0x15, HDA_INPUT, 1 },
15595 { 0x15, HDA_INPUT, 2 },
15596 { 0x15, HDA_INPUT, 3 },
15597 { } /* end */
15598};
15599#endif
15600
df694daa
KY
15601
15602/*
15603 * configuration and preset
15604 */
f5fcc13c
TI
15605static const char *alc861_models[ALC861_MODEL_LAST] = {
15606 [ALC861_3ST] = "3stack",
15607 [ALC660_3ST] = "3stack-660",
15608 [ALC861_3ST_DIG] = "3stack-dig",
15609 [ALC861_6ST_DIG] = "6stack-dig",
15610 [ALC861_UNIWILL_M31] = "uniwill-m31",
15611 [ALC861_TOSHIBA] = "toshiba",
15612 [ALC861_ASUS] = "asus",
15613 [ALC861_ASUS_LAPTOP] = "asus-laptop",
15614 [ALC861_AUTO] = "auto",
15615};
15616
15617static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 15618 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
15619 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15620 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15621 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 15622 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 15623 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 15624 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
15625 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
15626 * Any other models that need this preset?
15627 */
15628 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
15629 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
15630 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 15631 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
15632 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
15633 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
15634 /* FIXME: the below seems conflict */
15635 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 15636 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 15637 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
15638 {}
15639};
15640
15641static struct alc_config_preset alc861_presets[] = {
15642 [ALC861_3ST] = {
15643 .mixers = { alc861_3ST_mixer },
15644 .init_verbs = { alc861_threestack_init_verbs },
15645 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15646 .dac_nids = alc861_dac_nids,
15647 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15648 .channel_mode = alc861_threestack_modes,
4e195a7b 15649 .need_dac_fix = 1,
df694daa
KY
15650 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15651 .adc_nids = alc861_adc_nids,
15652 .input_mux = &alc861_capture_source,
15653 },
15654 [ALC861_3ST_DIG] = {
15655 .mixers = { alc861_base_mixer },
15656 .init_verbs = { alc861_threestack_init_verbs },
15657 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15658 .dac_nids = alc861_dac_nids,
15659 .dig_out_nid = ALC861_DIGOUT_NID,
15660 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15661 .channel_mode = alc861_threestack_modes,
4e195a7b 15662 .need_dac_fix = 1,
df694daa
KY
15663 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15664 .adc_nids = alc861_adc_nids,
15665 .input_mux = &alc861_capture_source,
15666 },
15667 [ALC861_6ST_DIG] = {
15668 .mixers = { alc861_base_mixer },
15669 .init_verbs = { alc861_base_init_verbs },
15670 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15671 .dac_nids = alc861_dac_nids,
15672 .dig_out_nid = ALC861_DIGOUT_NID,
15673 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
15674 .channel_mode = alc861_8ch_modes,
15675 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15676 .adc_nids = alc861_adc_nids,
15677 .input_mux = &alc861_capture_source,
15678 },
9c7f852e
TI
15679 [ALC660_3ST] = {
15680 .mixers = { alc861_3ST_mixer },
15681 .init_verbs = { alc861_threestack_init_verbs },
15682 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
15683 .dac_nids = alc660_dac_nids,
15684 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15685 .channel_mode = alc861_threestack_modes,
4e195a7b 15686 .need_dac_fix = 1,
9c7f852e
TI
15687 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15688 .adc_nids = alc861_adc_nids,
15689 .input_mux = &alc861_capture_source,
15690 },
22309c3e
TI
15691 [ALC861_UNIWILL_M31] = {
15692 .mixers = { alc861_uniwill_m31_mixer },
15693 .init_verbs = { alc861_uniwill_m31_init_verbs },
15694 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15695 .dac_nids = alc861_dac_nids,
15696 .dig_out_nid = ALC861_DIGOUT_NID,
15697 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
15698 .channel_mode = alc861_uniwill_m31_modes,
15699 .need_dac_fix = 1,
15700 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15701 .adc_nids = alc861_adc_nids,
15702 .input_mux = &alc861_capture_source,
15703 },
a53d1aec
TD
15704 [ALC861_TOSHIBA] = {
15705 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
15706 .init_verbs = { alc861_base_init_verbs,
15707 alc861_toshiba_init_verbs },
a53d1aec
TD
15708 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15709 .dac_nids = alc861_dac_nids,
15710 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15711 .channel_mode = alc883_3ST_2ch_modes,
15712 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15713 .adc_nids = alc861_adc_nids,
15714 .input_mux = &alc861_capture_source,
15715 .unsol_event = alc861_toshiba_unsol_event,
15716 .init_hook = alc861_toshiba_automute,
15717 },
7cdbff94
MD
15718 [ALC861_ASUS] = {
15719 .mixers = { alc861_asus_mixer },
15720 .init_verbs = { alc861_asus_init_verbs },
15721 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15722 .dac_nids = alc861_dac_nids,
15723 .dig_out_nid = ALC861_DIGOUT_NID,
15724 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
15725 .channel_mode = alc861_asus_modes,
15726 .need_dac_fix = 1,
15727 .hp_nid = 0x06,
15728 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15729 .adc_nids = alc861_adc_nids,
15730 .input_mux = &alc861_capture_source,
15731 },
56bb0cab
TI
15732 [ALC861_ASUS_LAPTOP] = {
15733 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
15734 .init_verbs = { alc861_asus_init_verbs,
15735 alc861_asus_laptop_init_verbs },
15736 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15737 .dac_nids = alc861_dac_nids,
15738 .dig_out_nid = ALC861_DIGOUT_NID,
15739 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15740 .channel_mode = alc883_3ST_2ch_modes,
15741 .need_dac_fix = 1,
15742 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15743 .adc_nids = alc861_adc_nids,
15744 .input_mux = &alc861_capture_source,
15745 },
15746};
df694daa 15747
cfc9b06f
TI
15748/* Pin config fixes */
15749enum {
15750 PINFIX_FSC_AMILO_PI1505,
15751};
15752
15753static struct alc_pincfg alc861_fsc_amilo_pi1505_pinfix[] = {
15754 { 0x0b, 0x0221101f }, /* HP */
15755 { 0x0f, 0x90170310 }, /* speaker */
15756 { }
15757};
15758
15759static const struct alc_fixup alc861_fixups[] = {
15760 [PINFIX_FSC_AMILO_PI1505] = {
15761 .pins = alc861_fsc_amilo_pi1505_pinfix
15762 },
15763};
15764
15765static struct snd_pci_quirk alc861_fixup_tbl[] = {
15766 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
15767 {}
15768};
df694daa
KY
15769
15770static int patch_alc861(struct hda_codec *codec)
15771{
15772 struct alc_spec *spec;
15773 int board_config;
15774 int err;
15775
dc041e0b 15776 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
15777 if (spec == NULL)
15778 return -ENOMEM;
15779
f12ab1e0 15780 codec->spec = spec;
df694daa 15781
f5fcc13c
TI
15782 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
15783 alc861_models,
15784 alc861_cfg_tbl);
9c7f852e 15785
f5fcc13c 15786 if (board_config < 0) {
9a11f1aa
TI
15787 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15788 codec->chip_name);
df694daa
KY
15789 board_config = ALC861_AUTO;
15790 }
15791
7fa90e87
TI
15792 if (board_config == ALC861_AUTO)
15793 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
cfc9b06f 15794
df694daa
KY
15795 if (board_config == ALC861_AUTO) {
15796 /* automatic parse from the BIOS config */
15797 err = alc861_parse_auto_config(codec);
15798 if (err < 0) {
15799 alc_free(codec);
15800 return err;
f12ab1e0 15801 } else if (!err) {
9c7f852e
TI
15802 printk(KERN_INFO
15803 "hda_codec: Cannot set up configuration "
15804 "from BIOS. Using base mode...\n");
df694daa
KY
15805 board_config = ALC861_3ST_DIG;
15806 }
15807 }
15808
680cd536
KK
15809 err = snd_hda_attach_beep_device(codec, 0x23);
15810 if (err < 0) {
15811 alc_free(codec);
15812 return err;
15813 }
15814
df694daa 15815 if (board_config != ALC861_AUTO)
e9c364c0 15816 setup_preset(codec, &alc861_presets[board_config]);
df694daa 15817
df694daa
KY
15818 spec->stream_analog_playback = &alc861_pcm_analog_playback;
15819 spec->stream_analog_capture = &alc861_pcm_analog_capture;
15820
df694daa
KY
15821 spec->stream_digital_playback = &alc861_pcm_digital_playback;
15822 spec->stream_digital_capture = &alc861_pcm_digital_capture;
15823
c7a8eb10
TI
15824 if (!spec->cap_mixer)
15825 set_capture_mixer(codec);
45bdd1c1
TI
15826 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
15827
2134ea4f
TI
15828 spec->vmaster_nid = 0x03;
15829
7fa90e87
TI
15830 if (board_config == ALC861_AUTO)
15831 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
15832
df694daa 15833 codec->patch_ops = alc_patch_ops;
c97259df 15834 if (board_config == ALC861_AUTO) {
ae6b813a 15835 spec->init_hook = alc861_auto_init;
c97259df
DC
15836#ifdef CONFIG_SND_HDA_POWER_SAVE
15837 spec->power_hook = alc_power_eapd;
15838#endif
15839 }
cb53c626
TI
15840#ifdef CONFIG_SND_HDA_POWER_SAVE
15841 if (!spec->loopback.amplist)
15842 spec->loopback.amplist = alc861_loopbacks;
15843#endif
ea1fb29a 15844
1da177e4
LT
15845 return 0;
15846}
15847
f32610ed
JS
15848/*
15849 * ALC861-VD support
15850 *
15851 * Based on ALC882
15852 *
15853 * In addition, an independent DAC
15854 */
15855#define ALC861VD_DIGOUT_NID 0x06
15856
15857static hda_nid_t alc861vd_dac_nids[4] = {
15858 /* front, surr, clfe, side surr */
15859 0x02, 0x03, 0x04, 0x05
15860};
15861
15862/* dac_nids for ALC660vd are in a different order - according to
15863 * Realtek's driver.
def319f9 15864 * This should probably result in a different mixer for 6stack models
f32610ed
JS
15865 * of ALC660vd codecs, but for now there is only 3stack mixer
15866 * - and it is the same as in 861vd.
15867 * adc_nids in ALC660vd are (is) the same as in 861vd
15868 */
15869static hda_nid_t alc660vd_dac_nids[3] = {
15870 /* front, rear, clfe, rear_surr */
15871 0x02, 0x04, 0x03
15872};
15873
15874static hda_nid_t alc861vd_adc_nids[1] = {
15875 /* ADC0 */
15876 0x09,
15877};
15878
e1406348
TI
15879static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
15880
f32610ed
JS
15881/* input MUX */
15882/* FIXME: should be a matrix-type input source selection */
15883static struct hda_input_mux alc861vd_capture_source = {
15884 .num_items = 4,
15885 .items = {
15886 { "Mic", 0x0 },
15887 { "Front Mic", 0x1 },
15888 { "Line", 0x2 },
15889 { "CD", 0x4 },
15890 },
15891};
15892
272a527c 15893static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 15894 .num_items = 2,
272a527c 15895 .items = {
b419f346
TD
15896 { "Ext Mic", 0x0 },
15897 { "Int Mic", 0x1 },
272a527c
KY
15898 },
15899};
15900
d1a991a6
KY
15901static struct hda_input_mux alc861vd_hp_capture_source = {
15902 .num_items = 2,
15903 .items = {
15904 { "Front Mic", 0x0 },
15905 { "ATAPI Mic", 0x1 },
15906 },
15907};
15908
f32610ed
JS
15909/*
15910 * 2ch mode
15911 */
15912static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
15913 { 2, NULL }
15914};
15915
15916/*
15917 * 6ch mode
15918 */
15919static struct hda_verb alc861vd_6stack_ch6_init[] = {
15920 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15921 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15922 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15923 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15924 { } /* end */
15925};
15926
15927/*
15928 * 8ch mode
15929 */
15930static struct hda_verb alc861vd_6stack_ch8_init[] = {
15931 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15932 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15933 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15934 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15935 { } /* end */
15936};
15937
15938static struct hda_channel_mode alc861vd_6stack_modes[2] = {
15939 { 6, alc861vd_6stack_ch6_init },
15940 { 8, alc861vd_6stack_ch8_init },
15941};
15942
15943static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
15944 {
15945 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15946 .name = "Channel Mode",
15947 .info = alc_ch_mode_info,
15948 .get = alc_ch_mode_get,
15949 .put = alc_ch_mode_put,
15950 },
15951 { } /* end */
15952};
15953
f32610ed
JS
15954/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15955 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15956 */
15957static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
15958 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15959 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15960
15961 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15962 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
15963
15964 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
15965 HDA_OUTPUT),
15966 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
15967 HDA_OUTPUT),
15968 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
15969 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
15970
15971 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
15972 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
15973
15974 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15975
15976 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15977 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15978 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15979
15980 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15981 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15982 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15983
15984 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15985 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15986
15987 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15988 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15989
f32610ed
JS
15990 { } /* end */
15991};
15992
15993static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
15994 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15995 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15996
15997 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15998
15999 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
16000 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16001 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16002
16003 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
16004 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16005 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16006
16007 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16008 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16009
16010 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16011 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16012
f32610ed
JS
16013 { } /* end */
16014};
16015
bdd148a3
KY
16016static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16017 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16018 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16019 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16020
16021 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16022
16023 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
16024 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16025 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16026
16027 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
16028 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16029 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16030
16031 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16032 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16033
16034 { } /* end */
16035};
16036
b419f346
TD
16037/* Pin assignment: Speaker=0x14, HP = 0x15,
16038 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
16039 */
16040static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16041 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16042 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16043 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16044 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
16045 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16046 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16047 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16048 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16049 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16050 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16051 { } /* end */
16052};
16053
d1a991a6
KY
16054/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16055 * Front Mic=0x18, ATAPI Mic = 0x19,
16056 */
16057static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16058 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16059 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16060 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16061 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16062 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16063 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16064 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16065 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16066
d1a991a6
KY
16067 { } /* end */
16068};
16069
f32610ed
JS
16070/*
16071 * generic initialization of ADC, input mixers and output mixers
16072 */
16073static struct hda_verb alc861vd_volume_init_verbs[] = {
16074 /*
16075 * Unmute ADC0 and set the default input to mic-in
16076 */
16077 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16078 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16079
16080 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16081 * the analog-loopback mixer widget
16082 */
16083 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16084 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16085 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16086 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16087 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16088 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16089
16090 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16091 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16092 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16093 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16094 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16095
16096 /*
16097 * Set up output mixers (0x02 - 0x05)
16098 */
16099 /* set vol=0 to output mixers */
16100 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16101 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16102 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16103 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16104
16105 /* set up input amps for analog loopback */
16106 /* Amp Indices: DAC = 0, mixer = 1 */
16107 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16108 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16109 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16110 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16111 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16112 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16113 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16114 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16115
16116 { }
16117};
16118
16119/*
16120 * 3-stack pin configuration:
16121 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16122 */
16123static struct hda_verb alc861vd_3stack_init_verbs[] = {
16124 /*
16125 * Set pin mode and muting
16126 */
16127 /* set front pin widgets 0x14 for output */
16128 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16129 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16130 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16131
16132 /* Mic (rear) pin: input vref at 80% */
16133 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16134 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16135 /* Front Mic pin: input vref at 80% */
16136 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16137 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16138 /* Line In pin: input */
16139 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16140 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16141 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16142 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16143 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16144 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16145 /* CD pin widget for input */
16146 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16147
16148 { }
16149};
16150
16151/*
16152 * 6-stack pin configuration:
16153 */
16154static struct hda_verb alc861vd_6stack_init_verbs[] = {
16155 /*
16156 * Set pin mode and muting
16157 */
16158 /* set front pin widgets 0x14 for output */
16159 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16160 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16161 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16162
16163 /* Rear Pin: output 1 (0x0d) */
16164 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16165 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16166 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16167 /* CLFE Pin: output 2 (0x0e) */
16168 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16169 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16170 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16171 /* Side Pin: output 3 (0x0f) */
16172 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16173 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16174 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16175
16176 /* Mic (rear) pin: input vref at 80% */
16177 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16178 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16179 /* Front Mic pin: input vref at 80% */
16180 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16181 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16182 /* Line In pin: input */
16183 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16184 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16185 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16186 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16187 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16188 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16189 /* CD pin widget for input */
16190 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16191
16192 { }
16193};
16194
bdd148a3
KY
16195static struct hda_verb alc861vd_eapd_verbs[] = {
16196 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16197 { }
16198};
16199
f9423e7a
KY
16200static struct hda_verb alc660vd_eapd_verbs[] = {
16201 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16202 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16203 { }
16204};
16205
bdd148a3
KY
16206static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16207 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16208 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16209 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16210 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16211 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16212 {}
16213};
16214
bdd148a3
KY
16215static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
16216{
16217 unsigned int present;
16218 unsigned char bits;
16219
864f92be 16220 present = snd_hda_jack_detect(codec, 0x18);
47fd830a 16221 bits = present ? HDA_AMP_MUTE : 0;
864f92be 16222
47fd830a
TI
16223 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
16224 HDA_AMP_MUTE, bits);
bdd148a3
KY
16225}
16226
4f5d1706 16227static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16228{
a9fd4f3f 16229 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16230 spec->autocfg.hp_pins[0] = 0x1b;
16231 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
16232}
16233
16234static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16235{
a9fd4f3f 16236 alc_automute_amp(codec);
bdd148a3
KY
16237 alc861vd_lenovo_mic_automute(codec);
16238}
16239
16240static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16241 unsigned int res)
16242{
16243 switch (res >> 26) {
bdd148a3
KY
16244 case ALC880_MIC_EVENT:
16245 alc861vd_lenovo_mic_automute(codec);
16246 break;
a9fd4f3f
TI
16247 default:
16248 alc_automute_amp_unsol_event(codec, res);
16249 break;
bdd148a3
KY
16250 }
16251}
16252
272a527c
KY
16253static struct hda_verb alc861vd_dallas_verbs[] = {
16254 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16255 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16256 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16257 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16258
16259 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16260 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16261 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16262 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16263 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16264 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16265 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16266 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16267
272a527c
KY
16268 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16269 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16270 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16271 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16272 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16273 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16274 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16275 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16276
16277 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16278 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16279 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16280 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16281 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16282 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16283 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16284 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16285
16286 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16287 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16288 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16289 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16290
16291 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16292 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16293 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16294
16295 { } /* end */
16296};
16297
16298/* toggle speaker-output according to the hp-jack state */
4f5d1706 16299static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16300{
a9fd4f3f 16301 struct alc_spec *spec = codec->spec;
272a527c 16302
a9fd4f3f
TI
16303 spec->autocfg.hp_pins[0] = 0x15;
16304 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
16305}
16306
cb53c626
TI
16307#ifdef CONFIG_SND_HDA_POWER_SAVE
16308#define alc861vd_loopbacks alc880_loopbacks
16309#endif
16310
def319f9 16311/* pcm configuration: identical with ALC880 */
f32610ed
JS
16312#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16313#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16314#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16315#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16316
16317/*
16318 * configuration and preset
16319 */
16320static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
16321 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16322 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16323 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16324 [ALC861VD_3ST] = "3stack",
16325 [ALC861VD_3ST_DIG] = "3stack-digout",
16326 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16327 [ALC861VD_LENOVO] = "lenovo",
272a527c 16328 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16329 [ALC861VD_HP] = "hp",
f32610ed
JS
16330 [ALC861VD_AUTO] = "auto",
16331};
16332
16333static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16334 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16335 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16336 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16337 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16338 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16339 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16340 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16341 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16342 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16343 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16344 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16345 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16346 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16347 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16348 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16349 {}
16350};
16351
16352static struct alc_config_preset alc861vd_presets[] = {
16353 [ALC660VD_3ST] = {
16354 .mixers = { alc861vd_3st_mixer },
16355 .init_verbs = { alc861vd_volume_init_verbs,
16356 alc861vd_3stack_init_verbs },
16357 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16358 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16359 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16360 .channel_mode = alc861vd_3stack_2ch_modes,
16361 .input_mux = &alc861vd_capture_source,
16362 },
6963f84c
MC
16363 [ALC660VD_3ST_DIG] = {
16364 .mixers = { alc861vd_3st_mixer },
16365 .init_verbs = { alc861vd_volume_init_verbs,
16366 alc861vd_3stack_init_verbs },
16367 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16368 .dac_nids = alc660vd_dac_nids,
16369 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16370 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16371 .channel_mode = alc861vd_3stack_2ch_modes,
16372 .input_mux = &alc861vd_capture_source,
16373 },
f32610ed
JS
16374 [ALC861VD_3ST] = {
16375 .mixers = { alc861vd_3st_mixer },
16376 .init_verbs = { alc861vd_volume_init_verbs,
16377 alc861vd_3stack_init_verbs },
16378 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16379 .dac_nids = alc861vd_dac_nids,
16380 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16381 .channel_mode = alc861vd_3stack_2ch_modes,
16382 .input_mux = &alc861vd_capture_source,
16383 },
16384 [ALC861VD_3ST_DIG] = {
16385 .mixers = { alc861vd_3st_mixer },
16386 .init_verbs = { alc861vd_volume_init_verbs,
16387 alc861vd_3stack_init_verbs },
16388 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16389 .dac_nids = alc861vd_dac_nids,
16390 .dig_out_nid = ALC861VD_DIGOUT_NID,
16391 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16392 .channel_mode = alc861vd_3stack_2ch_modes,
16393 .input_mux = &alc861vd_capture_source,
16394 },
16395 [ALC861VD_6ST_DIG] = {
16396 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16397 .init_verbs = { alc861vd_volume_init_verbs,
16398 alc861vd_6stack_init_verbs },
16399 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16400 .dac_nids = alc861vd_dac_nids,
16401 .dig_out_nid = ALC861VD_DIGOUT_NID,
16402 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16403 .channel_mode = alc861vd_6stack_modes,
16404 .input_mux = &alc861vd_capture_source,
16405 },
bdd148a3
KY
16406 [ALC861VD_LENOVO] = {
16407 .mixers = { alc861vd_lenovo_mixer },
16408 .init_verbs = { alc861vd_volume_init_verbs,
16409 alc861vd_3stack_init_verbs,
16410 alc861vd_eapd_verbs,
16411 alc861vd_lenovo_unsol_verbs },
16412 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16413 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16414 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16415 .channel_mode = alc861vd_3stack_2ch_modes,
16416 .input_mux = &alc861vd_capture_source,
16417 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16418 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16419 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16420 },
272a527c
KY
16421 [ALC861VD_DALLAS] = {
16422 .mixers = { alc861vd_dallas_mixer },
16423 .init_verbs = { alc861vd_dallas_verbs },
16424 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16425 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16426 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16427 .channel_mode = alc861vd_3stack_2ch_modes,
16428 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 16429 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16430 .setup = alc861vd_dallas_setup,
16431 .init_hook = alc_automute_amp,
d1a991a6
KY
16432 },
16433 [ALC861VD_HP] = {
16434 .mixers = { alc861vd_hp_mixer },
16435 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16436 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16437 .dac_nids = alc861vd_dac_nids,
d1a991a6 16438 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
16439 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16440 .channel_mode = alc861vd_3stack_2ch_modes,
16441 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 16442 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16443 .setup = alc861vd_dallas_setup,
16444 .init_hook = alc_automute_amp,
ea1fb29a 16445 },
13c94744
TI
16446 [ALC660VD_ASUS_V1S] = {
16447 .mixers = { alc861vd_lenovo_mixer },
16448 .init_verbs = { alc861vd_volume_init_verbs,
16449 alc861vd_3stack_init_verbs,
16450 alc861vd_eapd_verbs,
16451 alc861vd_lenovo_unsol_verbs },
16452 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16453 .dac_nids = alc660vd_dac_nids,
16454 .dig_out_nid = ALC861VD_DIGOUT_NID,
16455 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16456 .channel_mode = alc861vd_3stack_2ch_modes,
16457 .input_mux = &alc861vd_capture_source,
16458 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16459 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16460 .init_hook = alc861vd_lenovo_init_hook,
13c94744 16461 },
f32610ed
JS
16462};
16463
16464/*
16465 * BIOS auto configuration
16466 */
05f5f477
TI
16467static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16468 const struct auto_pin_cfg *cfg)
16469{
6227cdce 16470 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
05f5f477
TI
16471}
16472
16473
f32610ed
JS
16474static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
16475 hda_nid_t nid, int pin_type, int dac_idx)
16476{
f6c7e546 16477 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
16478}
16479
16480static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
16481{
16482 struct alc_spec *spec = codec->spec;
16483 int i;
16484
16485 for (i = 0; i <= HDA_SIDE; i++) {
16486 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16487 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
16488 if (nid)
16489 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 16490 pin_type, i);
f32610ed
JS
16491 }
16492}
16493
16494
16495static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
16496{
16497 struct alc_spec *spec = codec->spec;
16498 hda_nid_t pin;
16499
16500 pin = spec->autocfg.hp_pins[0];
def319f9 16501 if (pin) /* connect to front and use dac 0 */
f32610ed 16502 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
16503 pin = spec->autocfg.speaker_pins[0];
16504 if (pin)
16505 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
16506}
16507
f32610ed
JS
16508#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
16509
16510static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
16511{
16512 struct alc_spec *spec = codec->spec;
16513 int i;
16514
16515 for (i = 0; i < AUTO_PIN_LAST; i++) {
16516 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 16517 if (alc_is_input_pin(codec, nid)) {
23f0c048 16518 alc_set_input_pin(codec, nid, i);
e82c025b
TI
16519 if (nid != ALC861VD_PIN_CD_NID &&
16520 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
16521 snd_hda_codec_write(codec, nid, 0,
16522 AC_VERB_SET_AMP_GAIN_MUTE,
16523 AMP_OUT_MUTE);
16524 }
16525 }
16526}
16527
f511b01c
TI
16528#define alc861vd_auto_init_input_src alc882_auto_init_input_src
16529
f32610ed
JS
16530#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16531#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16532
16533/* add playback controls from the parsed DAC table */
16534/* Based on ALC880 version. But ALC861VD has separate,
16535 * different NIDs for mute/unmute switch and volume control */
16536static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16537 const struct auto_pin_cfg *cfg)
16538{
f32610ed
JS
16539 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
16540 hda_nid_t nid_v, nid_s;
16541 int i, err;
16542
16543 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 16544 if (!spec->multiout.dac_nids[i])
f32610ed
JS
16545 continue;
16546 nid_v = alc861vd_idx_to_mixer_vol(
16547 alc880_dac_to_idx(
16548 spec->multiout.dac_nids[i]));
16549 nid_s = alc861vd_idx_to_mixer_switch(
16550 alc880_dac_to_idx(
16551 spec->multiout.dac_nids[i]));
16552
16553 if (i == 2) {
16554 /* Center/LFE */
0afe5f89
TI
16555 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16556 "Center",
f12ab1e0
TI
16557 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16558 HDA_OUTPUT));
16559 if (err < 0)
f32610ed 16560 return err;
0afe5f89
TI
16561 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16562 "LFE",
f12ab1e0
TI
16563 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16564 HDA_OUTPUT));
16565 if (err < 0)
f32610ed 16566 return err;
0afe5f89
TI
16567 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16568 "Center",
f12ab1e0
TI
16569 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
16570 HDA_INPUT));
16571 if (err < 0)
f32610ed 16572 return err;
0afe5f89
TI
16573 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16574 "LFE",
f12ab1e0
TI
16575 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
16576 HDA_INPUT));
16577 if (err < 0)
f32610ed
JS
16578 return err;
16579 } else {
a4fcd491
TI
16580 const char *pfx;
16581 if (cfg->line_outs == 1 &&
16582 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
16583 if (!cfg->hp_pins)
16584 pfx = "Speaker";
16585 else
16586 pfx = "PCM";
16587 } else
16588 pfx = chname[i];
0afe5f89 16589 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16590 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16591 HDA_OUTPUT));
16592 if (err < 0)
f32610ed 16593 return err;
a4fcd491
TI
16594 if (cfg->line_outs == 1 &&
16595 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
16596 pfx = "Speaker";
0afe5f89 16597 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
bdd148a3 16598 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
16599 HDA_INPUT));
16600 if (err < 0)
f32610ed
JS
16601 return err;
16602 }
16603 }
16604 return 0;
16605}
16606
16607/* add playback controls for speaker and HP outputs */
16608/* Based on ALC880 version. But ALC861VD has separate,
16609 * different NIDs for mute/unmute switch and volume control */
16610static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16611 hda_nid_t pin, const char *pfx)
16612{
16613 hda_nid_t nid_v, nid_s;
16614 int err;
f32610ed 16615
f12ab1e0 16616 if (!pin)
f32610ed
JS
16617 return 0;
16618
16619 if (alc880_is_fixed_pin(pin)) {
16620 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16621 /* specify the DAC as the extra output */
f12ab1e0 16622 if (!spec->multiout.hp_nid)
f32610ed
JS
16623 spec->multiout.hp_nid = nid_v;
16624 else
16625 spec->multiout.extra_out_nid[0] = nid_v;
16626 /* control HP volume/switch on the output mixer amp */
16627 nid_v = alc861vd_idx_to_mixer_vol(
16628 alc880_fixed_pin_idx(pin));
16629 nid_s = alc861vd_idx_to_mixer_switch(
16630 alc880_fixed_pin_idx(pin));
16631
0afe5f89 16632 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16633 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
16634 if (err < 0)
f32610ed 16635 return err;
0afe5f89 16636 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
16637 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
16638 if (err < 0)
f32610ed
JS
16639 return err;
16640 } else if (alc880_is_multi_pin(pin)) {
16641 /* set manual connection */
16642 /* we have only a switch on HP-out PIN */
0afe5f89 16643 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
16644 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16645 if (err < 0)
f32610ed
JS
16646 return err;
16647 }
16648 return 0;
16649}
16650
16651/* parse the BIOS configuration and set up the alc_spec
16652 * return 1 if successful, 0 if the proper config is not found,
16653 * or a negative error code
16654 * Based on ALC880 version - had to change it to override
16655 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
16656static int alc861vd_parse_auto_config(struct hda_codec *codec)
16657{
16658 struct alc_spec *spec = codec->spec;
16659 int err;
16660 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
16661
f12ab1e0
TI
16662 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16663 alc861vd_ignore);
16664 if (err < 0)
f32610ed 16665 return err;
f12ab1e0 16666 if (!spec->autocfg.line_outs)
f32610ed
JS
16667 return 0; /* can't find valid BIOS pin config */
16668
f12ab1e0
TI
16669 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16670 if (err < 0)
16671 return err;
16672 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
16673 if (err < 0)
16674 return err;
16675 err = alc861vd_auto_create_extra_out(spec,
16676 spec->autocfg.speaker_pins[0],
16677 "Speaker");
16678 if (err < 0)
16679 return err;
16680 err = alc861vd_auto_create_extra_out(spec,
16681 spec->autocfg.hp_pins[0],
16682 "Headphone");
16683 if (err < 0)
16684 return err;
05f5f477 16685 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16686 if (err < 0)
f32610ed
JS
16687 return err;
16688
16689 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16690
757899ac 16691 alc_auto_parse_digital(codec);
f32610ed 16692
603c4019 16693 if (spec->kctls.list)
d88897ea 16694 add_mixer(spec, spec->kctls.list);
f32610ed 16695
d88897ea 16696 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
16697
16698 spec->num_mux_defs = 1;
61b9b9b1 16699 spec->input_mux = &spec->private_imux[0];
f32610ed 16700
776e184e
TI
16701 err = alc_auto_add_mic_boost(codec);
16702 if (err < 0)
16703 return err;
16704
6227cdce 16705 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 16706
f32610ed
JS
16707 return 1;
16708}
16709
16710/* additional initialization for auto-configuration model */
16711static void alc861vd_auto_init(struct hda_codec *codec)
16712{
f6c7e546 16713 struct alc_spec *spec = codec->spec;
f32610ed
JS
16714 alc861vd_auto_init_multi_out(codec);
16715 alc861vd_auto_init_hp_out(codec);
16716 alc861vd_auto_init_analog_input(codec);
f511b01c 16717 alc861vd_auto_init_input_src(codec);
757899ac 16718 alc_auto_init_digital(codec);
f6c7e546 16719 if (spec->unsol_event)
7fb0d78f 16720 alc_inithook(codec);
f32610ed
JS
16721}
16722
f8f25ba3
TI
16723enum {
16724 ALC660VD_FIX_ASUS_GPIO1
16725};
16726
16727/* reset GPIO1 */
16728static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
16729 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
16730 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
16731 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
16732 { }
16733};
16734
16735static const struct alc_fixup alc861vd_fixups[] = {
16736 [ALC660VD_FIX_ASUS_GPIO1] = {
16737 .verbs = alc660vd_fix_asus_gpio1_verbs,
16738 },
16739};
16740
16741static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
16742 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
16743 {}
16744};
16745
f32610ed
JS
16746static int patch_alc861vd(struct hda_codec *codec)
16747{
16748 struct alc_spec *spec;
16749 int err, board_config;
16750
16751 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16752 if (spec == NULL)
16753 return -ENOMEM;
16754
16755 codec->spec = spec;
16756
16757 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
16758 alc861vd_models,
16759 alc861vd_cfg_tbl);
16760
16761 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
16762 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16763 codec->chip_name);
f32610ed
JS
16764 board_config = ALC861VD_AUTO;
16765 }
16766
7fa90e87
TI
16767 if (board_config == ALC861VD_AUTO)
16768 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
f8f25ba3 16769
f32610ed
JS
16770 if (board_config == ALC861VD_AUTO) {
16771 /* automatic parse from the BIOS config */
16772 err = alc861vd_parse_auto_config(codec);
16773 if (err < 0) {
16774 alc_free(codec);
16775 return err;
f12ab1e0 16776 } else if (!err) {
f32610ed
JS
16777 printk(KERN_INFO
16778 "hda_codec: Cannot set up configuration "
16779 "from BIOS. Using base mode...\n");
16780 board_config = ALC861VD_3ST;
16781 }
16782 }
16783
680cd536
KK
16784 err = snd_hda_attach_beep_device(codec, 0x23);
16785 if (err < 0) {
16786 alc_free(codec);
16787 return err;
16788 }
16789
f32610ed 16790 if (board_config != ALC861VD_AUTO)
e9c364c0 16791 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 16792
2f893286 16793 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 16794 /* always turn on EAPD */
d88897ea 16795 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
16796 }
16797
f32610ed
JS
16798 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
16799 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
16800
f32610ed
JS
16801 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
16802 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
16803
dd704698
TI
16804 if (!spec->adc_nids) {
16805 spec->adc_nids = alc861vd_adc_nids;
16806 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
16807 }
16808 if (!spec->capsrc_nids)
16809 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 16810
b59bdf3b 16811 set_capture_mixer(codec);
45bdd1c1 16812 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 16813
2134ea4f
TI
16814 spec->vmaster_nid = 0x02;
16815
7fa90e87
TI
16816 if (board_config == ALC861VD_AUTO)
16817 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
16818
f32610ed
JS
16819 codec->patch_ops = alc_patch_ops;
16820
16821 if (board_config == ALC861VD_AUTO)
16822 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
16823#ifdef CONFIG_SND_HDA_POWER_SAVE
16824 if (!spec->loopback.amplist)
16825 spec->loopback.amplist = alc861vd_loopbacks;
16826#endif
f32610ed
JS
16827
16828 return 0;
16829}
16830
bc9f98a9
KY
16831/*
16832 * ALC662 support
16833 *
16834 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
16835 * configuration. Each pin widget can choose any input DACs and a mixer.
16836 * Each ADC is connected from a mixer of all inputs. This makes possible
16837 * 6-channel independent captures.
16838 *
16839 * In addition, an independent DAC for the multi-playback (not used in this
16840 * driver yet).
16841 */
16842#define ALC662_DIGOUT_NID 0x06
16843#define ALC662_DIGIN_NID 0x0a
16844
16845static hda_nid_t alc662_dac_nids[4] = {
16846 /* front, rear, clfe, rear_surr */
16847 0x02, 0x03, 0x04
16848};
16849
622e84cd
KY
16850static hda_nid_t alc272_dac_nids[2] = {
16851 0x02, 0x03
16852};
16853
b59bdf3b 16854static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 16855 /* ADC1-2 */
b59bdf3b 16856 0x09, 0x08
bc9f98a9 16857};
e1406348 16858
622e84cd
KY
16859static hda_nid_t alc272_adc_nids[1] = {
16860 /* ADC1-2 */
16861 0x08,
16862};
16863
b59bdf3b 16864static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
16865static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
16866
e1406348 16867
bc9f98a9
KY
16868/* input MUX */
16869/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
16870static struct hda_input_mux alc662_capture_source = {
16871 .num_items = 4,
16872 .items = {
16873 { "Mic", 0x0 },
16874 { "Front Mic", 0x1 },
16875 { "Line", 0x2 },
16876 { "CD", 0x4 },
16877 },
16878};
16879
16880static struct hda_input_mux alc662_lenovo_101e_capture_source = {
16881 .num_items = 2,
16882 .items = {
16883 { "Mic", 0x1 },
16884 { "Line", 0x2 },
16885 },
16886};
291702f0 16887
6dda9f4a
KY
16888static struct hda_input_mux alc663_capture_source = {
16889 .num_items = 3,
16890 .items = {
16891 { "Mic", 0x0 },
16892 { "Front Mic", 0x1 },
16893 { "Line", 0x2 },
16894 },
16895};
16896
4f5d1706 16897#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
16898static struct hda_input_mux alc272_nc10_capture_source = {
16899 .num_items = 16,
16900 .items = {
16901 { "Autoselect Mic", 0x0 },
16902 { "Internal Mic", 0x1 },
16903 { "In-0x02", 0x2 },
16904 { "In-0x03", 0x3 },
16905 { "In-0x04", 0x4 },
16906 { "In-0x05", 0x5 },
16907 { "In-0x06", 0x6 },
16908 { "In-0x07", 0x7 },
16909 { "In-0x08", 0x8 },
16910 { "In-0x09", 0x9 },
16911 { "In-0x0a", 0x0a },
16912 { "In-0x0b", 0x0b },
16913 { "In-0x0c", 0x0c },
16914 { "In-0x0d", 0x0d },
16915 { "In-0x0e", 0x0e },
16916 { "In-0x0f", 0x0f },
16917 },
16918};
16919#endif
16920
bc9f98a9
KY
16921/*
16922 * 2ch mode
16923 */
16924static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
16925 { 2, NULL }
16926};
16927
16928/*
16929 * 2ch mode
16930 */
16931static struct hda_verb alc662_3ST_ch2_init[] = {
16932 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
16933 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16934 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
16935 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16936 { } /* end */
16937};
16938
16939/*
16940 * 6ch mode
16941 */
16942static struct hda_verb alc662_3ST_ch6_init[] = {
16943 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16944 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16945 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
16946 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16947 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16948 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
16949 { } /* end */
16950};
16951
16952static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
16953 { 2, alc662_3ST_ch2_init },
16954 { 6, alc662_3ST_ch6_init },
16955};
16956
16957/*
16958 * 2ch mode
16959 */
16960static struct hda_verb alc662_sixstack_ch6_init[] = {
16961 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16962 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16963 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16964 { } /* end */
16965};
16966
16967/*
16968 * 6ch mode
16969 */
16970static struct hda_verb alc662_sixstack_ch8_init[] = {
16971 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16972 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16973 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16974 { } /* end */
16975};
16976
16977static struct hda_channel_mode alc662_5stack_modes[2] = {
16978 { 2, alc662_sixstack_ch6_init },
16979 { 6, alc662_sixstack_ch8_init },
16980};
16981
16982/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16983 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16984 */
16985
16986static struct snd_kcontrol_new alc662_base_mixer[] = {
16987 /* output mixer control */
16988 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 16989 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 16990 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 16991 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
16992 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16993 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
16994 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16995 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
16996 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16997
16998 /*Input mixer control */
16999 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17000 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17001 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17002 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17003 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17004 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17005 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17006 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17007 { } /* end */
17008};
17009
17010static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17011 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17012 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17013 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17014 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17015 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17016 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17017 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17018 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17019 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17020 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17021 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17022 { } /* end */
17023};
17024
17025static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17026 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17027 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17028 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17029 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17030 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17031 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17032 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17033 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17034 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17035 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17036 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17037 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17038 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17039 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17040 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17041 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17042 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17043 { } /* end */
17044};
17045
17046static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17047 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17048 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17049 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17050 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17051 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17052 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17053 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17054 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17055 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17056 { } /* end */
17057};
17058
291702f0 17059static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17060 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17061 ALC262_HIPPO_MASTER_SWITCH,
291702f0
KY
17062
17063 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
17064 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17065 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17066
17067 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
17068 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17069 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17070 { } /* end */
17071};
17072
8c427226 17073static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17074 ALC262_HIPPO_MASTER_SWITCH,
17075 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17076 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17077 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17078 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17079 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17080 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17081 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17082 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17083 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17084 { } /* end */
17085};
17086
f1d4e28b
KY
17087static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17088 .ops = &snd_hda_bind_vol,
17089 .values = {
17090 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17091 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17092 0
17093 },
17094};
17095
17096static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17097 .ops = &snd_hda_bind_sw,
17098 .values = {
17099 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17100 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17101 0
17102 },
17103};
17104
6dda9f4a 17105static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17106 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17107 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17108 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17109 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17110 { } /* end */
17111};
17112
17113static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17114 .ops = &snd_hda_bind_sw,
17115 .values = {
17116 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17117 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17118 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17119 0
17120 },
17121};
17122
17123static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17124 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17125 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17126 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17127 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17128 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17129 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17130
17131 { } /* end */
17132};
17133
17134static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17135 .ops = &snd_hda_bind_sw,
17136 .values = {
17137 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17138 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17139 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17140 0
17141 },
17142};
17143
17144static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17145 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17146 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17147 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17148 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17149 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17150 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17151 { } /* end */
17152};
17153
17154static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17155 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17156 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17157 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17158 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17159 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17160 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17161 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17162 { } /* end */
17163};
17164
17165static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17166 .ops = &snd_hda_bind_vol,
17167 .values = {
17168 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17169 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17170 0
17171 },
17172};
17173
17174static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17175 .ops = &snd_hda_bind_sw,
17176 .values = {
17177 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17178 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17179 0
17180 },
17181};
17182
17183static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17184 HDA_BIND_VOL("Master Playback Volume",
17185 &alc663_asus_two_bind_master_vol),
17186 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17187 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17188 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17189 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17190 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17191 { } /* end */
17192};
17193
17194static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17195 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17196 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17197 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17198 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17199 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17200 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17201 { } /* end */
17202};
17203
17204static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17205 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17206 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17207 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17208 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17209 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17210
17211 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17212 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17213 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17214 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17215 { } /* end */
17216};
17217
17218static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17219 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17220 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17221 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17222
17223 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17224 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17225 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17226 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17227 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17228 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17229 { } /* end */
17230};
17231
ebb83eeb
KY
17232static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17233 .ops = &snd_hda_bind_sw,
17234 .values = {
17235 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17236 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17237 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17238 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17239 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17240 0
17241 },
17242};
17243
17244static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17245 .ops = &snd_hda_bind_sw,
17246 .values = {
17247 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17248 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17249 0
17250 },
17251};
17252
17253static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17254 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17255 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17256 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17257 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17258 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17259 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17260 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17261 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17262 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17263 { } /* end */
17264};
17265
17266static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17267 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17268 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17269 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17270 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17271 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17272 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17273 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17274 { } /* end */
17275};
17276
17277
bc9f98a9
KY
17278static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17279 {
17280 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17281 .name = "Channel Mode",
17282 .info = alc_ch_mode_info,
17283 .get = alc_ch_mode_get,
17284 .put = alc_ch_mode_put,
17285 },
17286 { } /* end */
17287};
17288
17289static struct hda_verb alc662_init_verbs[] = {
17290 /* ADC: mute amp left and right */
17291 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17292 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17293
b60dd394
KY
17294 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17295 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17296 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17297 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17298 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17299 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17300
17301 /* Front Pin: output 0 (0x0c) */
17302 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17303 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17304
17305 /* Rear Pin: output 1 (0x0d) */
17306 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17307 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17308
17309 /* CLFE Pin: output 2 (0x0e) */
17310 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17311 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17312
17313 /* Mic (rear) pin: input vref at 80% */
17314 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17315 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17316 /* Front Mic pin: input vref at 80% */
17317 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17318 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17319 /* Line In pin: input */
17320 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17321 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17322 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17323 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17324 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17325 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17326 /* CD pin widget for input */
17327 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17328
17329 /* FIXME: use matrix-type input source selection */
17330 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17331 /* Input mixer */
17332 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17333 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
17334
17335 /* always trun on EAPD */
17336 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17337 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17338
bc9f98a9
KY
17339 { }
17340};
17341
cec27c89
KY
17342static struct hda_verb alc663_init_verbs[] = {
17343 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17344 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17345 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17346 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17347 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17348 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17349 { }
17350};
17351
17352static struct hda_verb alc272_init_verbs[] = {
17353 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17354 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17355 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17356 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17357 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17358 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17359 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17360 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17361 { }
17362};
17363
bc9f98a9
KY
17364static struct hda_verb alc662_sue_init_verbs[] = {
17365 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17366 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17367 {}
17368};
17369
17370static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17371 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17372 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17373 {}
bc9f98a9
KY
17374};
17375
8c427226
KY
17376/* Set Unsolicited Event*/
17377static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17378 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17379 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17380 {}
17381};
17382
6dda9f4a 17383static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17384 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17385 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17386 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17387 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17388 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17389 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17390 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17391 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17392 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17393 {}
17394};
17395
17396static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17397 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17398 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17399 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17400 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17401 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17402 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17403 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17404 {}
17405};
17406
17407static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17408 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17409 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17410 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17411 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17412 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17413 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17414 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17415 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17416 {}
17417};
6dda9f4a 17418
f1d4e28b
KY
17419static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17420 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17421 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17422 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17423 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17424 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17425 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17426 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17427 {}
17428};
6dda9f4a 17429
f1d4e28b
KY
17430static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17431 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17432 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17433 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17434 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17435 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17436 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17437 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17438 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17439 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
17440 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17441 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
17442 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17443 {}
17444};
17445
17446static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17447 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17448 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17449 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17450 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17451 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17452 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17453 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17454 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17455 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17456 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17457 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17458 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
17459 {}
17460};
17461
17462static struct hda_verb alc663_g71v_init_verbs[] = {
17463 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17464 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17465 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17466
17467 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17468 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17469 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17470
17471 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17472 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17473 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17474 {}
17475};
17476
17477static struct hda_verb alc663_g50v_init_verbs[] = {
17478 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17479 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17480 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17481
17482 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17483 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17484 {}
17485};
17486
f1d4e28b
KY
17487static struct hda_verb alc662_ecs_init_verbs[] = {
17488 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17489 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17490 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17491 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17492 {}
17493};
17494
622e84cd
KY
17495static struct hda_verb alc272_dell_zm1_init_verbs[] = {
17496 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17497 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17498 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17499 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17500 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17501 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17502 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17503 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17504 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17505 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17506 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17507 {}
17508};
17509
17510static struct hda_verb alc272_dell_init_verbs[] = {
17511 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17512 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17513 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17514 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17515 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17516 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17517 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17518 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17519 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17520 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17521 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17522 {}
17523};
17524
ebb83eeb
KY
17525static struct hda_verb alc663_mode7_init_verbs[] = {
17526 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17527 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17528 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17529 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17530 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17531 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17532 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17533 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17534 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17535 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17536 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17537 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17538 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17539 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17540 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17541 {}
17542};
17543
17544static struct hda_verb alc663_mode8_init_verbs[] = {
17545 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17546 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17547 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17548 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17549 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17550 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17551 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17552 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17553 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17554 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17555 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17556 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17557 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17558 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17559 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17560 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17561 {}
17562};
17563
f1d4e28b
KY
17564static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17565 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17566 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17567 { } /* end */
17568};
17569
622e84cd
KY
17570static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17571 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17572 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17573 { } /* end */
17574};
17575
bc9f98a9
KY
17576static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
17577{
17578 unsigned int present;
f12ab1e0 17579 unsigned char bits;
bc9f98a9 17580
864f92be 17581 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 17582 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17583
47fd830a
TI
17584 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17585 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17586}
17587
17588static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
17589{
17590 unsigned int present;
f12ab1e0 17591 unsigned char bits;
bc9f98a9 17592
864f92be 17593 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 17594 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17595
47fd830a
TI
17596 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17597 HDA_AMP_MUTE, bits);
17598 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17599 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17600}
17601
17602static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
17603 unsigned int res)
17604{
17605 if ((res >> 26) == ALC880_HP_EVENT)
17606 alc662_lenovo_101e_all_automute(codec);
17607 if ((res >> 26) == ALC880_FRONT_EVENT)
17608 alc662_lenovo_101e_ispeaker_automute(codec);
17609}
17610
291702f0
KY
17611/* unsolicited event for HP jack sensing */
17612static void alc662_eeepc_unsol_event(struct hda_codec *codec,
17613 unsigned int res)
17614{
291702f0 17615 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 17616 alc_mic_automute(codec);
42171c17
TI
17617 else
17618 alc262_hippo_unsol_event(codec, res);
291702f0
KY
17619}
17620
4f5d1706
TI
17621static void alc662_eeepc_setup(struct hda_codec *codec)
17622{
17623 struct alc_spec *spec = codec->spec;
17624
17625 alc262_hippo1_setup(codec);
17626 spec->ext_mic.pin = 0x18;
17627 spec->ext_mic.mux_idx = 0;
17628 spec->int_mic.pin = 0x19;
17629 spec->int_mic.mux_idx = 1;
17630 spec->auto_mic = 1;
17631}
17632
291702f0
KY
17633static void alc662_eeepc_inithook(struct hda_codec *codec)
17634{
4f5d1706
TI
17635 alc262_hippo_automute(codec);
17636 alc_mic_automute(codec);
291702f0
KY
17637}
17638
4f5d1706 17639static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 17640{
42171c17
TI
17641 struct alc_spec *spec = codec->spec;
17642
17643 spec->autocfg.hp_pins[0] = 0x14;
17644 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
17645}
17646
4f5d1706
TI
17647#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
17648
6dda9f4a
KY
17649static void alc663_m51va_speaker_automute(struct hda_codec *codec)
17650{
17651 unsigned int present;
17652 unsigned char bits;
17653
864f92be 17654 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 17655 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 17656 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17657 HDA_AMP_MUTE, bits);
f1d4e28b 17658 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17659 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17660}
17661
17662static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
17663{
17664 unsigned int present;
17665 unsigned char bits;
17666
864f92be 17667 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
17668 bits = present ? HDA_AMP_MUTE : 0;
17669 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17670 HDA_AMP_MUTE, bits);
f1d4e28b 17671 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17672 HDA_AMP_MUTE, bits);
f1d4e28b 17673 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 17674 HDA_AMP_MUTE, bits);
f1d4e28b 17675 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 17676 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17677}
17678
17679static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
17680{
17681 unsigned int present;
17682 unsigned char bits;
17683
864f92be 17684 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17685 bits = present ? HDA_AMP_MUTE : 0;
17686 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17687 HDA_AMP_MUTE, bits);
f1d4e28b 17688 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17689 HDA_AMP_MUTE, bits);
f1d4e28b 17690 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 17691 HDA_AMP_MUTE, bits);
f1d4e28b 17692 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 17693 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17694}
17695
17696static void alc662_f5z_speaker_automute(struct hda_codec *codec)
17697{
17698 unsigned int present;
17699 unsigned char bits;
17700
864f92be 17701 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
17702 bits = present ? 0 : PIN_OUT;
17703 snd_hda_codec_write(codec, 0x14, 0,
17704 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
17705}
17706
17707static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
17708{
17709 unsigned int present1, present2;
17710
864f92be
WF
17711 present1 = snd_hda_jack_detect(codec, 0x21);
17712 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17713
17714 if (present1 || present2) {
17715 snd_hda_codec_write_cache(codec, 0x14, 0,
17716 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17717 } else {
17718 snd_hda_codec_write_cache(codec, 0x14, 0,
17719 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17720 }
17721}
17722
17723static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
17724{
17725 unsigned int present1, present2;
17726
864f92be
WF
17727 present1 = snd_hda_jack_detect(codec, 0x1b);
17728 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17729
17730 if (present1 || present2) {
17731 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17732 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 17733 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17734 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
17735 } else {
17736 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17737 HDA_AMP_MUTE, 0);
f1d4e28b 17738 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17739 HDA_AMP_MUTE, 0);
f1d4e28b 17740 }
6dda9f4a
KY
17741}
17742
ebb83eeb
KY
17743static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
17744{
17745 unsigned int present1, present2;
17746
17747 present1 = snd_hda_codec_read(codec, 0x1b, 0,
17748 AC_VERB_GET_PIN_SENSE, 0)
17749 & AC_PINSENSE_PRESENCE;
17750 present2 = snd_hda_codec_read(codec, 0x21, 0,
17751 AC_VERB_GET_PIN_SENSE, 0)
17752 & AC_PINSENSE_PRESENCE;
17753
17754 if (present1 || present2) {
17755 snd_hda_codec_write_cache(codec, 0x14, 0,
17756 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17757 snd_hda_codec_write_cache(codec, 0x17, 0,
17758 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17759 } else {
17760 snd_hda_codec_write_cache(codec, 0x14, 0,
17761 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17762 snd_hda_codec_write_cache(codec, 0x17, 0,
17763 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17764 }
17765}
17766
17767static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
17768{
17769 unsigned int present1, present2;
17770
17771 present1 = snd_hda_codec_read(codec, 0x21, 0,
17772 AC_VERB_GET_PIN_SENSE, 0)
17773 & AC_PINSENSE_PRESENCE;
17774 present2 = snd_hda_codec_read(codec, 0x15, 0,
17775 AC_VERB_GET_PIN_SENSE, 0)
17776 & AC_PINSENSE_PRESENCE;
17777
17778 if (present1 || present2) {
17779 snd_hda_codec_write_cache(codec, 0x14, 0,
17780 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17781 snd_hda_codec_write_cache(codec, 0x17, 0,
17782 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17783 } else {
17784 snd_hda_codec_write_cache(codec, 0x14, 0,
17785 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17786 snd_hda_codec_write_cache(codec, 0x17, 0,
17787 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17788 }
17789}
17790
6dda9f4a
KY
17791static void alc663_m51va_unsol_event(struct hda_codec *codec,
17792 unsigned int res)
17793{
17794 switch (res >> 26) {
17795 case ALC880_HP_EVENT:
17796 alc663_m51va_speaker_automute(codec);
17797 break;
17798 case ALC880_MIC_EVENT:
4f5d1706 17799 alc_mic_automute(codec);
6dda9f4a
KY
17800 break;
17801 }
17802}
17803
4f5d1706
TI
17804static void alc663_m51va_setup(struct hda_codec *codec)
17805{
17806 struct alc_spec *spec = codec->spec;
17807 spec->ext_mic.pin = 0x18;
17808 spec->ext_mic.mux_idx = 0;
17809 spec->int_mic.pin = 0x12;
ebb83eeb 17810 spec->int_mic.mux_idx = 9;
4f5d1706
TI
17811 spec->auto_mic = 1;
17812}
17813
6dda9f4a
KY
17814static void alc663_m51va_inithook(struct hda_codec *codec)
17815{
17816 alc663_m51va_speaker_automute(codec);
4f5d1706 17817 alc_mic_automute(codec);
6dda9f4a
KY
17818}
17819
f1d4e28b 17820/* ***************** Mode1 ******************************/
4f5d1706 17821#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
17822
17823static void alc663_mode1_setup(struct hda_codec *codec)
17824{
17825 struct alc_spec *spec = codec->spec;
17826 spec->ext_mic.pin = 0x18;
17827 spec->ext_mic.mux_idx = 0;
17828 spec->int_mic.pin = 0x19;
17829 spec->int_mic.mux_idx = 1;
17830 spec->auto_mic = 1;
17831}
17832
4f5d1706 17833#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 17834
f1d4e28b
KY
17835/* ***************** Mode2 ******************************/
17836static void alc662_mode2_unsol_event(struct hda_codec *codec,
17837 unsigned int res)
17838{
17839 switch (res >> 26) {
17840 case ALC880_HP_EVENT:
17841 alc662_f5z_speaker_automute(codec);
17842 break;
17843 case ALC880_MIC_EVENT:
4f5d1706 17844 alc_mic_automute(codec);
f1d4e28b
KY
17845 break;
17846 }
17847}
17848
ebb83eeb 17849#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 17850
f1d4e28b
KY
17851static void alc662_mode2_inithook(struct hda_codec *codec)
17852{
17853 alc662_f5z_speaker_automute(codec);
4f5d1706 17854 alc_mic_automute(codec);
f1d4e28b
KY
17855}
17856/* ***************** Mode3 ******************************/
17857static void alc663_mode3_unsol_event(struct hda_codec *codec,
17858 unsigned int res)
17859{
17860 switch (res >> 26) {
17861 case ALC880_HP_EVENT:
17862 alc663_two_hp_m1_speaker_automute(codec);
17863 break;
17864 case ALC880_MIC_EVENT:
4f5d1706 17865 alc_mic_automute(codec);
f1d4e28b
KY
17866 break;
17867 }
17868}
17869
ebb83eeb 17870#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 17871
f1d4e28b
KY
17872static void alc663_mode3_inithook(struct hda_codec *codec)
17873{
17874 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 17875 alc_mic_automute(codec);
f1d4e28b
KY
17876}
17877/* ***************** Mode4 ******************************/
17878static void alc663_mode4_unsol_event(struct hda_codec *codec,
17879 unsigned int res)
17880{
17881 switch (res >> 26) {
17882 case ALC880_HP_EVENT:
17883 alc663_21jd_two_speaker_automute(codec);
17884 break;
17885 case ALC880_MIC_EVENT:
4f5d1706 17886 alc_mic_automute(codec);
f1d4e28b
KY
17887 break;
17888 }
17889}
17890
ebb83eeb 17891#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 17892
f1d4e28b
KY
17893static void alc663_mode4_inithook(struct hda_codec *codec)
17894{
17895 alc663_21jd_two_speaker_automute(codec);
4f5d1706 17896 alc_mic_automute(codec);
f1d4e28b
KY
17897}
17898/* ***************** Mode5 ******************************/
17899static void alc663_mode5_unsol_event(struct hda_codec *codec,
17900 unsigned int res)
17901{
17902 switch (res >> 26) {
17903 case ALC880_HP_EVENT:
17904 alc663_15jd_two_speaker_automute(codec);
17905 break;
17906 case ALC880_MIC_EVENT:
4f5d1706 17907 alc_mic_automute(codec);
f1d4e28b
KY
17908 break;
17909 }
17910}
17911
ebb83eeb 17912#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 17913
f1d4e28b
KY
17914static void alc663_mode5_inithook(struct hda_codec *codec)
17915{
17916 alc663_15jd_two_speaker_automute(codec);
4f5d1706 17917 alc_mic_automute(codec);
f1d4e28b
KY
17918}
17919/* ***************** Mode6 ******************************/
17920static void alc663_mode6_unsol_event(struct hda_codec *codec,
17921 unsigned int res)
17922{
17923 switch (res >> 26) {
17924 case ALC880_HP_EVENT:
17925 alc663_two_hp_m2_speaker_automute(codec);
17926 break;
17927 case ALC880_MIC_EVENT:
4f5d1706 17928 alc_mic_automute(codec);
f1d4e28b
KY
17929 break;
17930 }
17931}
17932
ebb83eeb 17933#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 17934
f1d4e28b
KY
17935static void alc663_mode6_inithook(struct hda_codec *codec)
17936{
17937 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 17938 alc_mic_automute(codec);
f1d4e28b
KY
17939}
17940
ebb83eeb
KY
17941/* ***************** Mode7 ******************************/
17942static void alc663_mode7_unsol_event(struct hda_codec *codec,
17943 unsigned int res)
17944{
17945 switch (res >> 26) {
17946 case ALC880_HP_EVENT:
17947 alc663_two_hp_m7_speaker_automute(codec);
17948 break;
17949 case ALC880_MIC_EVENT:
17950 alc_mic_automute(codec);
17951 break;
17952 }
17953}
17954
17955#define alc663_mode7_setup alc663_mode1_setup
17956
17957static void alc663_mode7_inithook(struct hda_codec *codec)
17958{
17959 alc663_two_hp_m7_speaker_automute(codec);
17960 alc_mic_automute(codec);
17961}
17962
17963/* ***************** Mode8 ******************************/
17964static void alc663_mode8_unsol_event(struct hda_codec *codec,
17965 unsigned int res)
17966{
17967 switch (res >> 26) {
17968 case ALC880_HP_EVENT:
17969 alc663_two_hp_m8_speaker_automute(codec);
17970 break;
17971 case ALC880_MIC_EVENT:
17972 alc_mic_automute(codec);
17973 break;
17974 }
17975}
17976
17977#define alc663_mode8_setup alc663_m51va_setup
17978
17979static void alc663_mode8_inithook(struct hda_codec *codec)
17980{
17981 alc663_two_hp_m8_speaker_automute(codec);
17982 alc_mic_automute(codec);
17983}
17984
6dda9f4a
KY
17985static void alc663_g71v_hp_automute(struct hda_codec *codec)
17986{
17987 unsigned int present;
17988 unsigned char bits;
17989
864f92be 17990 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
17991 bits = present ? HDA_AMP_MUTE : 0;
17992 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17993 HDA_AMP_MUTE, bits);
17994 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17995 HDA_AMP_MUTE, bits);
17996}
17997
17998static void alc663_g71v_front_automute(struct hda_codec *codec)
17999{
18000 unsigned int present;
18001 unsigned char bits;
18002
864f92be 18003 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
18004 bits = present ? HDA_AMP_MUTE : 0;
18005 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18006 HDA_AMP_MUTE, bits);
18007}
18008
18009static void alc663_g71v_unsol_event(struct hda_codec *codec,
18010 unsigned int res)
18011{
18012 switch (res >> 26) {
18013 case ALC880_HP_EVENT:
18014 alc663_g71v_hp_automute(codec);
18015 break;
18016 case ALC880_FRONT_EVENT:
18017 alc663_g71v_front_automute(codec);
18018 break;
18019 case ALC880_MIC_EVENT:
4f5d1706 18020 alc_mic_automute(codec);
6dda9f4a
KY
18021 break;
18022 }
18023}
18024
4f5d1706
TI
18025#define alc663_g71v_setup alc663_m51va_setup
18026
6dda9f4a
KY
18027static void alc663_g71v_inithook(struct hda_codec *codec)
18028{
18029 alc663_g71v_front_automute(codec);
18030 alc663_g71v_hp_automute(codec);
4f5d1706 18031 alc_mic_automute(codec);
6dda9f4a
KY
18032}
18033
18034static void alc663_g50v_unsol_event(struct hda_codec *codec,
18035 unsigned int res)
18036{
18037 switch (res >> 26) {
18038 case ALC880_HP_EVENT:
18039 alc663_m51va_speaker_automute(codec);
18040 break;
18041 case ALC880_MIC_EVENT:
4f5d1706 18042 alc_mic_automute(codec);
6dda9f4a
KY
18043 break;
18044 }
18045}
18046
4f5d1706
TI
18047#define alc663_g50v_setup alc663_m51va_setup
18048
6dda9f4a
KY
18049static void alc663_g50v_inithook(struct hda_codec *codec)
18050{
18051 alc663_m51va_speaker_automute(codec);
4f5d1706 18052 alc_mic_automute(codec);
6dda9f4a
KY
18053}
18054
f1d4e28b
KY
18055static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18056 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18057 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b
KY
18058
18059 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
18060 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18061 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18062
18063 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
18064 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18065 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18066 { } /* end */
18067};
18068
9541ba1d
CP
18069static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18070 /* Master Playback automatically created from Speaker and Headphone */
18071 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18072 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18073 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18074 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18075
18076 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18077 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18078 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
18079
18080 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18081 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18082 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
18083 { } /* end */
18084};
18085
cb53c626
TI
18086#ifdef CONFIG_SND_HDA_POWER_SAVE
18087#define alc662_loopbacks alc880_loopbacks
18088#endif
18089
bc9f98a9 18090
def319f9 18091/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18092#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18093#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18094#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18095#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18096
18097/*
18098 * configuration and preset
18099 */
18100static const char *alc662_models[ALC662_MODEL_LAST] = {
18101 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18102 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18103 [ALC662_3ST_6ch] = "3stack-6ch",
18104 [ALC662_5ST_DIG] = "6stack-dig",
18105 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18106 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18107 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18108 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18109 [ALC663_ASUS_M51VA] = "m51va",
18110 [ALC663_ASUS_G71V] = "g71v",
18111 [ALC663_ASUS_H13] = "h13",
18112 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18113 [ALC663_ASUS_MODE1] = "asus-mode1",
18114 [ALC662_ASUS_MODE2] = "asus-mode2",
18115 [ALC663_ASUS_MODE3] = "asus-mode3",
18116 [ALC663_ASUS_MODE4] = "asus-mode4",
18117 [ALC663_ASUS_MODE5] = "asus-mode5",
18118 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18119 [ALC663_ASUS_MODE7] = "asus-mode7",
18120 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18121 [ALC272_DELL] = "dell",
18122 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18123 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18124 [ALC662_AUTO] = "auto",
18125};
18126
18127static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18128 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18129 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18130 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18131 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18132 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18133 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18134 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18135 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18136 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18137 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18138 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18139 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18140 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18141 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18142 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18143 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18144 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18145 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18146 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18147 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18148 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18149 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18150 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18151 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18152 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18153 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18154 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18155 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18156 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18157 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18158 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18159 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18160 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18161 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18162 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18163 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18164 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18165 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18166 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18167 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18168 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18169 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18170 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18171 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18172 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18173 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18174 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18175 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18176 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18177 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18178 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18179 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18180 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18181 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18182 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18183 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18184 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18185 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18186 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18187 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18188 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18189 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18190 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18191 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18192 ALC662_3ST_6ch_DIG),
4dee8baa 18193 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18194 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
18195 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18196 ALC662_3ST_6ch_DIG),
6227cdce 18197 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18198 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18199 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18200 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18201 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18202 ALC662_3ST_6ch_DIG),
dea0a509
TI
18203 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18204 ALC663_ASUS_H13),
bc9f98a9
KY
18205 {}
18206};
18207
18208static struct alc_config_preset alc662_presets[] = {
18209 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18210 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
18211 .init_verbs = { alc662_init_verbs },
18212 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18213 .dac_nids = alc662_dac_nids,
18214 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18215 .dig_in_nid = ALC662_DIGIN_NID,
18216 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18217 .channel_mode = alc662_3ST_2ch_modes,
18218 .input_mux = &alc662_capture_source,
18219 },
18220 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18221 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18222 .init_verbs = { alc662_init_verbs },
18223 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18224 .dac_nids = alc662_dac_nids,
18225 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18226 .dig_in_nid = ALC662_DIGIN_NID,
18227 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18228 .channel_mode = alc662_3ST_6ch_modes,
18229 .need_dac_fix = 1,
18230 .input_mux = &alc662_capture_source,
f12ab1e0 18231 },
bc9f98a9 18232 [ALC662_3ST_6ch] = {
f9e336f6 18233 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18234 .init_verbs = { alc662_init_verbs },
18235 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18236 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18237 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18238 .channel_mode = alc662_3ST_6ch_modes,
18239 .need_dac_fix = 1,
18240 .input_mux = &alc662_capture_source,
f12ab1e0 18241 },
bc9f98a9 18242 [ALC662_5ST_DIG] = {
f9e336f6 18243 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18244 .init_verbs = { alc662_init_verbs },
18245 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18246 .dac_nids = alc662_dac_nids,
18247 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18248 .dig_in_nid = ALC662_DIGIN_NID,
18249 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18250 .channel_mode = alc662_5stack_modes,
18251 .input_mux = &alc662_capture_source,
18252 },
18253 [ALC662_LENOVO_101E] = {
f9e336f6 18254 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
18255 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18256 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18257 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18258 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18259 .channel_mode = alc662_3ST_2ch_modes,
18260 .input_mux = &alc662_lenovo_101e_capture_source,
18261 .unsol_event = alc662_lenovo_101e_unsol_event,
18262 .init_hook = alc662_lenovo_101e_all_automute,
18263 },
291702f0 18264 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18265 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
18266 .init_verbs = { alc662_init_verbs,
18267 alc662_eeepc_sue_init_verbs },
18268 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18269 .dac_nids = alc662_dac_nids,
291702f0
KY
18270 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18271 .channel_mode = alc662_3ST_2ch_modes,
291702f0 18272 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18273 .setup = alc662_eeepc_setup,
291702f0
KY
18274 .init_hook = alc662_eeepc_inithook,
18275 },
8c427226 18276 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18277 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18278 alc662_chmode_mixer },
18279 .init_verbs = { alc662_init_verbs,
18280 alc662_eeepc_ep20_sue_init_verbs },
18281 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18282 .dac_nids = alc662_dac_nids,
8c427226
KY
18283 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18284 .channel_mode = alc662_3ST_6ch_modes,
18285 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 18286 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18287 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
18288 .init_hook = alc662_eeepc_ep20_inithook,
18289 },
f1d4e28b 18290 [ALC662_ECS] = {
f9e336f6 18291 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
18292 .init_verbs = { alc662_init_verbs,
18293 alc662_ecs_init_verbs },
18294 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18295 .dac_nids = alc662_dac_nids,
18296 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18297 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18298 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18299 .setup = alc662_eeepc_setup,
f1d4e28b
KY
18300 .init_hook = alc662_eeepc_inithook,
18301 },
6dda9f4a 18302 [ALC663_ASUS_M51VA] = {
f9e336f6 18303 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18304 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18305 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18306 .dac_nids = alc662_dac_nids,
18307 .dig_out_nid = ALC662_DIGOUT_NID,
18308 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18309 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18310 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18311 .setup = alc663_m51va_setup,
6dda9f4a
KY
18312 .init_hook = alc663_m51va_inithook,
18313 },
18314 [ALC663_ASUS_G71V] = {
f9e336f6 18315 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
18316 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18317 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18318 .dac_nids = alc662_dac_nids,
18319 .dig_out_nid = ALC662_DIGOUT_NID,
18320 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18321 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18322 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 18323 .setup = alc663_g71v_setup,
6dda9f4a
KY
18324 .init_hook = alc663_g71v_inithook,
18325 },
18326 [ALC663_ASUS_H13] = {
f9e336f6 18327 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18328 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18329 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18330 .dac_nids = alc662_dac_nids,
18331 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18332 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
18333 .unsol_event = alc663_m51va_unsol_event,
18334 .init_hook = alc663_m51va_inithook,
18335 },
18336 [ALC663_ASUS_G50V] = {
f9e336f6 18337 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
18338 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18339 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18340 .dac_nids = alc662_dac_nids,
18341 .dig_out_nid = ALC662_DIGOUT_NID,
18342 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18343 .channel_mode = alc662_3ST_6ch_modes,
18344 .input_mux = &alc663_capture_source,
18345 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 18346 .setup = alc663_g50v_setup,
6dda9f4a
KY
18347 .init_hook = alc663_g50v_inithook,
18348 },
f1d4e28b 18349 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18350 .mixers = { alc663_m51va_mixer },
18351 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18352 .init_verbs = { alc662_init_verbs,
18353 alc663_21jd_amic_init_verbs },
18354 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18355 .hp_nid = 0x03,
18356 .dac_nids = alc662_dac_nids,
18357 .dig_out_nid = ALC662_DIGOUT_NID,
18358 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18359 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18360 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18361 .setup = alc663_mode1_setup,
f1d4e28b
KY
18362 .init_hook = alc663_mode1_inithook,
18363 },
18364 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18365 .mixers = { alc662_1bjd_mixer },
18366 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18367 .init_verbs = { alc662_init_verbs,
18368 alc662_1bjd_amic_init_verbs },
18369 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18370 .dac_nids = alc662_dac_nids,
18371 .dig_out_nid = ALC662_DIGOUT_NID,
18372 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18373 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18374 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18375 .setup = alc662_mode2_setup,
f1d4e28b
KY
18376 .init_hook = alc662_mode2_inithook,
18377 },
18378 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18379 .mixers = { alc663_two_hp_m1_mixer },
18380 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18381 .init_verbs = { alc662_init_verbs,
18382 alc663_two_hp_amic_m1_init_verbs },
18383 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18384 .hp_nid = 0x03,
18385 .dac_nids = alc662_dac_nids,
18386 .dig_out_nid = ALC662_DIGOUT_NID,
18387 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18388 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18389 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 18390 .setup = alc663_mode3_setup,
f1d4e28b
KY
18391 .init_hook = alc663_mode3_inithook,
18392 },
18393 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18394 .mixers = { alc663_asus_21jd_clfe_mixer },
18395 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18396 .init_verbs = { alc662_init_verbs,
18397 alc663_21jd_amic_init_verbs},
18398 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18399 .hp_nid = 0x03,
18400 .dac_nids = alc662_dac_nids,
18401 .dig_out_nid = ALC662_DIGOUT_NID,
18402 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18403 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18404 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18405 .setup = alc663_mode4_setup,
f1d4e28b
KY
18406 .init_hook = alc663_mode4_inithook,
18407 },
18408 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18409 .mixers = { alc663_asus_15jd_clfe_mixer },
18410 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18411 .init_verbs = { alc662_init_verbs,
18412 alc663_15jd_amic_init_verbs },
18413 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18414 .hp_nid = 0x03,
18415 .dac_nids = alc662_dac_nids,
18416 .dig_out_nid = ALC662_DIGOUT_NID,
18417 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18418 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18419 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 18420 .setup = alc663_mode5_setup,
f1d4e28b
KY
18421 .init_hook = alc663_mode5_inithook,
18422 },
18423 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18424 .mixers = { alc663_two_hp_m2_mixer },
18425 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18426 .init_verbs = { alc662_init_verbs,
18427 alc663_two_hp_amic_m2_init_verbs },
18428 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18429 .hp_nid = 0x03,
18430 .dac_nids = alc662_dac_nids,
18431 .dig_out_nid = ALC662_DIGOUT_NID,
18432 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18433 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18434 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 18435 .setup = alc663_mode6_setup,
f1d4e28b
KY
18436 .init_hook = alc663_mode6_inithook,
18437 },
ebb83eeb
KY
18438 [ALC663_ASUS_MODE7] = {
18439 .mixers = { alc663_mode7_mixer },
18440 .cap_mixer = alc662_auto_capture_mixer,
18441 .init_verbs = { alc662_init_verbs,
18442 alc663_mode7_init_verbs },
18443 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18444 .hp_nid = 0x03,
18445 .dac_nids = alc662_dac_nids,
18446 .dig_out_nid = ALC662_DIGOUT_NID,
18447 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18448 .channel_mode = alc662_3ST_2ch_modes,
18449 .unsol_event = alc663_mode7_unsol_event,
18450 .setup = alc663_mode7_setup,
18451 .init_hook = alc663_mode7_inithook,
18452 },
18453 [ALC663_ASUS_MODE8] = {
18454 .mixers = { alc663_mode8_mixer },
18455 .cap_mixer = alc662_auto_capture_mixer,
18456 .init_verbs = { alc662_init_verbs,
18457 alc663_mode8_init_verbs },
18458 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18459 .hp_nid = 0x03,
18460 .dac_nids = alc662_dac_nids,
18461 .dig_out_nid = ALC662_DIGOUT_NID,
18462 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18463 .channel_mode = alc662_3ST_2ch_modes,
18464 .unsol_event = alc663_mode8_unsol_event,
18465 .setup = alc663_mode8_setup,
18466 .init_hook = alc663_mode8_inithook,
18467 },
622e84cd
KY
18468 [ALC272_DELL] = {
18469 .mixers = { alc663_m51va_mixer },
18470 .cap_mixer = alc272_auto_capture_mixer,
18471 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
18472 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18473 .dac_nids = alc662_dac_nids,
18474 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18475 .adc_nids = alc272_adc_nids,
18476 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18477 .capsrc_nids = alc272_capsrc_nids,
18478 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18479 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18480 .setup = alc663_m51va_setup,
622e84cd
KY
18481 .init_hook = alc663_m51va_inithook,
18482 },
18483 [ALC272_DELL_ZM1] = {
18484 .mixers = { alc663_m51va_mixer },
18485 .cap_mixer = alc662_auto_capture_mixer,
18486 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
18487 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18488 .dac_nids = alc662_dac_nids,
18489 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18490 .adc_nids = alc662_adc_nids,
b59bdf3b 18491 .num_adc_nids = 1,
622e84cd
KY
18492 .capsrc_nids = alc662_capsrc_nids,
18493 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18494 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18495 .setup = alc663_m51va_setup,
622e84cd
KY
18496 .init_hook = alc663_m51va_inithook,
18497 },
9541ba1d
CP
18498 [ALC272_SAMSUNG_NC10] = {
18499 .mixers = { alc272_nc10_mixer },
18500 .init_verbs = { alc662_init_verbs,
18501 alc663_21jd_amic_init_verbs },
18502 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18503 .dac_nids = alc272_dac_nids,
18504 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18505 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18506 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 18507 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18508 .setup = alc663_mode4_setup,
9541ba1d
CP
18509 .init_hook = alc663_mode4_inithook,
18510 },
bc9f98a9
KY
18511};
18512
18513
18514/*
18515 * BIOS auto configuration
18516 */
18517
7085ec12
TI
18518/* convert from MIX nid to DAC */
18519static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
18520{
18521 if (nid == 0x0f)
18522 return 0x02;
18523 else if (nid >= 0x0c && nid <= 0x0e)
18524 return nid - 0x0c + 0x02;
18525 else
18526 return 0;
18527}
18528
18529/* get MIX nid connected to the given pin targeted to DAC */
18530static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18531 hda_nid_t dac)
18532{
18533 hda_nid_t mix[4];
18534 int i, num;
18535
18536 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18537 for (i = 0; i < num; i++) {
18538 if (alc662_mix_to_dac(mix[i]) == dac)
18539 return mix[i];
18540 }
18541 return 0;
18542}
18543
18544/* look for an empty DAC slot */
18545static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18546{
18547 struct alc_spec *spec = codec->spec;
18548 hda_nid_t srcs[5];
18549 int i, j, num;
18550
18551 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18552 if (num < 0)
18553 return 0;
18554 for (i = 0; i < num; i++) {
18555 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
18556 if (!nid)
18557 continue;
18558 for (j = 0; j < spec->multiout.num_dacs; j++)
18559 if (spec->multiout.dac_nids[j] == nid)
18560 break;
18561 if (j >= spec->multiout.num_dacs)
18562 return nid;
18563 }
18564 return 0;
18565}
18566
18567/* fill in the dac_nids table from the parsed pin configuration */
18568static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18569 const struct auto_pin_cfg *cfg)
18570{
18571 struct alc_spec *spec = codec->spec;
18572 int i;
18573 hda_nid_t dac;
18574
18575 spec->multiout.dac_nids = spec->private_dac_nids;
18576 for (i = 0; i < cfg->line_outs; i++) {
18577 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
18578 if (!dac)
18579 continue;
18580 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
18581 }
18582 return 0;
18583}
18584
0afe5f89 18585static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18586 hda_nid_t nid, unsigned int chs)
18587{
0afe5f89 18588 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
7085ec12
TI
18589 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18590}
18591
0afe5f89 18592static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18593 hda_nid_t nid, unsigned int chs)
18594{
0afe5f89 18595 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12
TI
18596 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18597}
18598
18599#define alc662_add_stereo_vol(spec, pfx, nid) \
18600 alc662_add_vol_ctl(spec, pfx, nid, 3)
18601#define alc662_add_stereo_sw(spec, pfx, nid) \
18602 alc662_add_sw_ctl(spec, pfx, nid, 3)
18603
bc9f98a9 18604/* add playback controls from the parsed DAC table */
7085ec12 18605static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
18606 const struct auto_pin_cfg *cfg)
18607{
7085ec12 18608 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18609 static const char *chname[4] = {
18610 "Front", "Surround", NULL /*CLFE*/, "Side"
18611 };
7085ec12 18612 hda_nid_t nid, mix;
bc9f98a9
KY
18613 int i, err;
18614
18615 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
18616 nid = spec->multiout.dac_nids[i];
18617 if (!nid)
18618 continue;
18619 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
18620 if (!mix)
bc9f98a9 18621 continue;
bc9f98a9
KY
18622 if (i == 2) {
18623 /* Center/LFE */
7085ec12 18624 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
18625 if (err < 0)
18626 return err;
7085ec12 18627 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
18628 if (err < 0)
18629 return err;
7085ec12 18630 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
18631 if (err < 0)
18632 return err;
7085ec12 18633 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
18634 if (err < 0)
18635 return err;
18636 } else {
0d884cb9
TI
18637 const char *pfx;
18638 if (cfg->line_outs == 1 &&
18639 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
7085ec12 18640 if (cfg->hp_outs)
0d884cb9
TI
18641 pfx = "Speaker";
18642 else
18643 pfx = "PCM";
18644 } else
18645 pfx = chname[i];
7085ec12 18646 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
bc9f98a9
KY
18647 if (err < 0)
18648 return err;
0d884cb9
TI
18649 if (cfg->line_outs == 1 &&
18650 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
18651 pfx = "Speaker";
7085ec12 18652 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
bc9f98a9
KY
18653 if (err < 0)
18654 return err;
18655 }
18656 }
18657 return 0;
18658}
18659
18660/* add playback controls for speaker and HP outputs */
7085ec12
TI
18661/* return DAC nid if any new DAC is assigned */
18662static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
18663 const char *pfx)
18664{
7085ec12
TI
18665 struct alc_spec *spec = codec->spec;
18666 hda_nid_t nid, mix;
bc9f98a9 18667 int err;
bc9f98a9
KY
18668
18669 if (!pin)
18670 return 0;
7085ec12
TI
18671 nid = alc662_look_for_dac(codec, pin);
18672 if (!nid) {
7085ec12
TI
18673 /* the corresponding DAC is already occupied */
18674 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18675 return 0; /* no way */
18676 /* create a switch only */
0afe5f89 18677 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 18678 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
18679 }
18680
7085ec12
TI
18681 mix = alc662_dac_to_mix(codec, pin, nid);
18682 if (!mix)
18683 return 0;
18684 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
18685 if (err < 0)
18686 return err;
18687 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
18688 if (err < 0)
18689 return err;
18690 return nid;
bc9f98a9
KY
18691}
18692
18693/* create playback/capture controls for input pins */
05f5f477 18694#define alc662_auto_create_input_ctls \
4b7348a1 18695 alc882_auto_create_input_ctls
bc9f98a9
KY
18696
18697static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
18698 hda_nid_t nid, int pin_type,
7085ec12 18699 hda_nid_t dac)
bc9f98a9 18700{
7085ec12 18701 int i, num;
ce503f38 18702 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 18703
f6c7e546 18704 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 18705 /* need the manual connection? */
7085ec12
TI
18706 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
18707 if (num <= 1)
18708 return;
18709 for (i = 0; i < num; i++) {
18710 if (alc662_mix_to_dac(srcs[i]) != dac)
18711 continue;
18712 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
18713 return;
bc9f98a9
KY
18714 }
18715}
18716
18717static void alc662_auto_init_multi_out(struct hda_codec *codec)
18718{
18719 struct alc_spec *spec = codec->spec;
7085ec12 18720 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
18721 int i;
18722
18723 for (i = 0; i <= HDA_SIDE; i++) {
18724 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18725 if (nid)
baba8ee9 18726 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 18727 spec->multiout.dac_nids[i]);
bc9f98a9
KY
18728 }
18729}
18730
18731static void alc662_auto_init_hp_out(struct hda_codec *codec)
18732{
18733 struct alc_spec *spec = codec->spec;
18734 hda_nid_t pin;
18735
18736 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
18737 if (pin)
18738 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
18739 spec->multiout.hp_nid);
f6c7e546
TI
18740 pin = spec->autocfg.speaker_pins[0];
18741 if (pin)
7085ec12
TI
18742 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
18743 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
18744}
18745
bc9f98a9
KY
18746#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
18747
18748static void alc662_auto_init_analog_input(struct hda_codec *codec)
18749{
18750 struct alc_spec *spec = codec->spec;
18751 int i;
18752
18753 for (i = 0; i < AUTO_PIN_LAST; i++) {
18754 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 18755 if (alc_is_input_pin(codec, nid)) {
23f0c048 18756 alc_set_input_pin(codec, nid, i);
52ca15b7 18757 if (nid != ALC662_PIN_CD_NID &&
e82c025b 18758 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
18759 snd_hda_codec_write(codec, nid, 0,
18760 AC_VERB_SET_AMP_GAIN_MUTE,
18761 AMP_OUT_MUTE);
18762 }
18763 }
18764}
18765
f511b01c
TI
18766#define alc662_auto_init_input_src alc882_auto_init_input_src
18767
bc9f98a9
KY
18768static int alc662_parse_auto_config(struct hda_codec *codec)
18769{
18770 struct alc_spec *spec = codec->spec;
18771 int err;
18772 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
18773
18774 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
18775 alc662_ignore);
18776 if (err < 0)
18777 return err;
18778 if (!spec->autocfg.line_outs)
18779 return 0; /* can't find valid BIOS pin config */
18780
7085ec12 18781 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
18782 if (err < 0)
18783 return err;
7085ec12 18784 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
18785 if (err < 0)
18786 return err;
7085ec12 18787 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
18788 spec->autocfg.speaker_pins[0],
18789 "Speaker");
18790 if (err < 0)
18791 return err;
7085ec12
TI
18792 if (err)
18793 spec->multiout.extra_out_nid[0] = err;
18794 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
18795 "Headphone");
18796 if (err < 0)
18797 return err;
7085ec12
TI
18798 if (err)
18799 spec->multiout.hp_nid = err;
05f5f477 18800 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 18801 if (err < 0)
bc9f98a9
KY
18802 return err;
18803
18804 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
18805
757899ac 18806 alc_auto_parse_digital(codec);
bc9f98a9 18807
603c4019 18808 if (spec->kctls.list)
d88897ea 18809 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
18810
18811 spec->num_mux_defs = 1;
61b9b9b1 18812 spec->input_mux = &spec->private_imux[0];
ea1fb29a 18813
cec27c89
KY
18814 add_verb(spec, alc662_init_verbs);
18815 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
d1eb57f4 18816 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
cec27c89
KY
18817 add_verb(spec, alc663_init_verbs);
18818
18819 if (codec->vendor_id == 0x10ec0272)
18820 add_verb(spec, alc272_init_verbs);
ee979a14
TI
18821
18822 err = alc_auto_add_mic_boost(codec);
18823 if (err < 0)
18824 return err;
18825
6227cdce
KY
18826 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18827 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18828 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18829 else
18830 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 18831
8c87286f 18832 return 1;
bc9f98a9
KY
18833}
18834
18835/* additional initialization for auto-configuration model */
18836static void alc662_auto_init(struct hda_codec *codec)
18837{
f6c7e546 18838 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18839 alc662_auto_init_multi_out(codec);
18840 alc662_auto_init_hp_out(codec);
18841 alc662_auto_init_analog_input(codec);
f511b01c 18842 alc662_auto_init_input_src(codec);
757899ac 18843 alc_auto_init_digital(codec);
f6c7e546 18844 if (spec->unsol_event)
7fb0d78f 18845 alc_inithook(codec);
bc9f98a9
KY
18846}
18847
18848static int patch_alc662(struct hda_codec *codec)
18849{
18850 struct alc_spec *spec;
18851 int err, board_config;
18852
18853 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
18854 if (!spec)
18855 return -ENOMEM;
18856
18857 codec->spec = spec;
18858
da00c244
KY
18859 alc_auto_parse_customize_define(codec);
18860
2c3bf9ab
TI
18861 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18862
c027ddcd
KY
18863 if (alc_read_coef_idx(codec, 0) == 0x8020)
18864 alc_codec_rename(codec, "ALC661");
18865 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) &&
18866 codec->bus->pci->subsystem_vendor == 0x1025 &&
18867 spec->cdefine.platform_type == 1)
18868 alc_codec_rename(codec, "ALC272X");
274693f3 18869
bc9f98a9
KY
18870 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
18871 alc662_models,
18872 alc662_cfg_tbl);
18873 if (board_config < 0) {
9a11f1aa
TI
18874 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
18875 codec->chip_name);
bc9f98a9
KY
18876 board_config = ALC662_AUTO;
18877 }
18878
18879 if (board_config == ALC662_AUTO) {
18880 /* automatic parse from the BIOS config */
18881 err = alc662_parse_auto_config(codec);
18882 if (err < 0) {
18883 alc_free(codec);
18884 return err;
8c87286f 18885 } else if (!err) {
bc9f98a9
KY
18886 printk(KERN_INFO
18887 "hda_codec: Cannot set up configuration "
18888 "from BIOS. Using base mode...\n");
18889 board_config = ALC662_3ST_2ch_DIG;
18890 }
18891 }
18892
dc1eae25 18893 if (has_cdefine_beep(codec)) {
8af2591d
TI
18894 err = snd_hda_attach_beep_device(codec, 0x1);
18895 if (err < 0) {
18896 alc_free(codec);
18897 return err;
18898 }
680cd536
KK
18899 }
18900
bc9f98a9 18901 if (board_config != ALC662_AUTO)
e9c364c0 18902 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 18903
bc9f98a9
KY
18904 spec->stream_analog_playback = &alc662_pcm_analog_playback;
18905 spec->stream_analog_capture = &alc662_pcm_analog_capture;
18906
bc9f98a9
KY
18907 spec->stream_digital_playback = &alc662_pcm_digital_playback;
18908 spec->stream_digital_capture = &alc662_pcm_digital_capture;
18909
dd704698
TI
18910 if (!spec->adc_nids) {
18911 spec->adc_nids = alc662_adc_nids;
18912 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
18913 }
18914 if (!spec->capsrc_nids)
18915 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 18916
f9e336f6 18917 if (!spec->cap_mixer)
b59bdf3b 18918 set_capture_mixer(codec);
cec27c89 18919
dc1eae25 18920 if (has_cdefine_beep(codec)) {
da00c244
KY
18921 switch (codec->vendor_id) {
18922 case 0x10ec0662:
18923 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18924 break;
18925 case 0x10ec0272:
18926 case 0x10ec0663:
18927 case 0x10ec0665:
18928 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18929 break;
18930 case 0x10ec0273:
18931 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18932 break;
18933 }
cec27c89 18934 }
2134ea4f
TI
18935 spec->vmaster_nid = 0x02;
18936
bc9f98a9
KY
18937 codec->patch_ops = alc_patch_ops;
18938 if (board_config == ALC662_AUTO)
18939 spec->init_hook = alc662_auto_init;
cb53c626
TI
18940#ifdef CONFIG_SND_HDA_POWER_SAVE
18941 if (!spec->loopback.amplist)
18942 spec->loopback.amplist = alc662_loopbacks;
18943#endif
bc9f98a9
KY
18944
18945 return 0;
18946}
18947
274693f3
KY
18948static int patch_alc888(struct hda_codec *codec)
18949{
18950 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
18951 kfree(codec->chip_name);
18952 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
18953 if (!codec->chip_name) {
18954 alc_free(codec);
274693f3 18955 return -ENOMEM;
ac2c92e0
TI
18956 }
18957 return patch_alc662(codec);
274693f3 18958 }
ac2c92e0 18959 return patch_alc882(codec);
274693f3
KY
18960}
18961
d1eb57f4
KY
18962/*
18963 * ALC680 support
18964 */
18965#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
18966#define alc680_modes alc260_modes
18967
18968static hda_nid_t alc680_dac_nids[3] = {
18969 /* Lout1, Lout2, hp */
18970 0x02, 0x03, 0x04
18971};
18972
18973static hda_nid_t alc680_adc_nids[3] = {
18974 /* ADC0-2 */
18975 /* DMIC, MIC, Line-in*/
18976 0x07, 0x08, 0x09
18977};
18978
18979static struct snd_kcontrol_new alc680_base_mixer[] = {
18980 /* output mixer control */
18981 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
18982 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18983 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
18984 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
18985 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
18986 { }
18987};
18988
18989static struct snd_kcontrol_new alc680_capture_mixer[] = {
18990 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
18991 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
18992 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
18993 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
18994 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
18995 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
18996 { } /* end */
18997};
18998
18999/*
19000 * generic initialization of ADC, input mixers and output mixers
19001 */
19002static struct hda_verb alc680_init_verbs[] = {
19003 /* Unmute DAC0-1 and set vol = 0 */
19004 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
19005 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
19006 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
19007
19008 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
19009 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
19010 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
19011 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
19012 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
19013
19014 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19015 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19016 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19017 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19018 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19019 { }
19020};
19021
19022/* create input playback/capture controls for the given pin */
19023static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19024 const char *ctlname, int idx)
19025{
19026 hda_nid_t dac;
19027 int err;
19028
19029 switch (nid) {
19030 case 0x14:
19031 dac = 0x02;
19032 break;
19033 case 0x15:
19034 dac = 0x03;
19035 break;
19036 case 0x16:
19037 dac = 0x04;
19038 break;
19039 default:
19040 return 0;
19041 }
19042 if (spec->multiout.dac_nids[0] != dac &&
19043 spec->multiout.dac_nids[1] != dac) {
19044 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19045 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19046 HDA_OUTPUT));
19047 if (err < 0)
19048 return err;
19049
19050 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19051 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19052
19053 if (err < 0)
19054 return err;
19055 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19056 }
19057
19058 return 0;
19059}
19060
19061/* add playback controls from the parsed DAC table */
19062static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19063 const struct auto_pin_cfg *cfg)
19064{
19065 hda_nid_t nid;
19066 int err;
19067
19068 spec->multiout.dac_nids = spec->private_dac_nids;
19069
19070 nid = cfg->line_out_pins[0];
19071 if (nid) {
19072 const char *name;
19073 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19074 name = "Speaker";
19075 else
19076 name = "Front";
19077 err = alc680_new_analog_output(spec, nid, name, 0);
19078 if (err < 0)
19079 return err;
19080 }
19081
19082 nid = cfg->speaker_pins[0];
19083 if (nid) {
19084 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19085 if (err < 0)
19086 return err;
19087 }
19088 nid = cfg->hp_pins[0];
19089 if (nid) {
19090 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19091 if (err < 0)
19092 return err;
19093 }
19094
19095 return 0;
19096}
19097
19098static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19099 hda_nid_t nid, int pin_type)
19100{
19101 alc_set_pin_output(codec, nid, pin_type);
19102}
19103
19104static void alc680_auto_init_multi_out(struct hda_codec *codec)
19105{
19106 struct alc_spec *spec = codec->spec;
19107 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19108 if (nid) {
19109 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19110 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19111 }
19112}
19113
19114static void alc680_auto_init_hp_out(struct hda_codec *codec)
19115{
19116 struct alc_spec *spec = codec->spec;
19117 hda_nid_t pin;
19118
19119 pin = spec->autocfg.hp_pins[0];
19120 if (pin)
19121 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19122 pin = spec->autocfg.speaker_pins[0];
19123 if (pin)
19124 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19125}
19126
19127/* pcm configuration: identical with ALC880 */
19128#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19129#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19130#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19131#define alc680_pcm_digital_playback alc880_pcm_digital_playback
19132
19133static struct hda_input_mux alc680_capture_source = {
19134 .num_items = 1,
19135 .items = {
19136 { "Mic", 0x0 },
19137 },
19138};
19139
19140/*
19141 * BIOS auto configuration
19142 */
19143static int alc680_parse_auto_config(struct hda_codec *codec)
19144{
19145 struct alc_spec *spec = codec->spec;
19146 int err;
19147 static hda_nid_t alc680_ignore[] = { 0 };
19148
19149 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19150 alc680_ignore);
19151 if (err < 0)
19152 return err;
19153 if (!spec->autocfg.line_outs) {
19154 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19155 spec->multiout.max_channels = 2;
19156 spec->no_analog = 1;
19157 goto dig_only;
19158 }
19159 return 0; /* can't find valid BIOS pin config */
19160 }
19161 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19162 if (err < 0)
19163 return err;
19164
19165 spec->multiout.max_channels = 2;
19166
19167 dig_only:
19168 /* digital only support output */
757899ac 19169 alc_auto_parse_digital(codec);
d1eb57f4
KY
19170 if (spec->kctls.list)
19171 add_mixer(spec, spec->kctls.list);
19172
19173 add_verb(spec, alc680_init_verbs);
19174 spec->num_mux_defs = 1;
19175 spec->input_mux = &alc680_capture_source;
19176
19177 err = alc_auto_add_mic_boost(codec);
19178 if (err < 0)
19179 return err;
19180
19181 return 1;
19182}
19183
19184#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19185
19186/* init callback for auto-configuration model -- overriding the default init */
19187static void alc680_auto_init(struct hda_codec *codec)
19188{
19189 struct alc_spec *spec = codec->spec;
19190 alc680_auto_init_multi_out(codec);
19191 alc680_auto_init_hp_out(codec);
19192 alc680_auto_init_analog_input(codec);
757899ac 19193 alc_auto_init_digital(codec);
d1eb57f4
KY
19194 if (spec->unsol_event)
19195 alc_inithook(codec);
19196}
19197
19198/*
19199 * configuration and preset
19200 */
19201static const char *alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19202 [ALC680_BASE] = "base",
19203 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19204};
19205
19206static struct snd_pci_quirk alc680_cfg_tbl[] = {
19207 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19208 {}
19209};
19210
19211static struct alc_config_preset alc680_presets[] = {
19212 [ALC680_BASE] = {
19213 .mixers = { alc680_base_mixer },
19214 .cap_mixer = alc680_capture_mixer,
19215 .init_verbs = { alc680_init_verbs },
19216 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19217 .dac_nids = alc680_dac_nids,
19218 .num_adc_nids = ARRAY_SIZE(alc680_adc_nids),
19219 .adc_nids = alc680_adc_nids,
19220 .hp_nid = 0x04,
19221 .dig_out_nid = ALC680_DIGOUT_NID,
19222 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19223 .channel_mode = alc680_modes,
19224 .input_mux = &alc680_capture_source,
19225 },
19226};
19227
19228static int patch_alc680(struct hda_codec *codec)
19229{
19230 struct alc_spec *spec;
19231 int board_config;
19232 int err;
19233
19234 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19235 if (spec == NULL)
19236 return -ENOMEM;
19237
19238 codec->spec = spec;
19239
19240 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19241 alc680_models,
19242 alc680_cfg_tbl);
19243
19244 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19245 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19246 codec->chip_name);
19247 board_config = ALC680_AUTO;
19248 }
19249
19250 if (board_config == ALC680_AUTO) {
19251 /* automatic parse from the BIOS config */
19252 err = alc680_parse_auto_config(codec);
19253 if (err < 0) {
19254 alc_free(codec);
19255 return err;
19256 } else if (!err) {
19257 printk(KERN_INFO
19258 "hda_codec: Cannot set up configuration "
19259 "from BIOS. Using base mode...\n");
19260 board_config = ALC680_BASE;
19261 }
19262 }
19263
19264 if (board_config != ALC680_AUTO)
19265 setup_preset(codec, &alc680_presets[board_config]);
19266
19267 spec->stream_analog_playback = &alc680_pcm_analog_playback;
19268 spec->stream_analog_capture = &alc680_pcm_analog_capture;
19269 spec->stream_analog_alt_capture = &alc680_pcm_analog_alt_capture;
19270 spec->stream_digital_playback = &alc680_pcm_digital_playback;
19271
19272 if (!spec->adc_nids) {
19273 spec->adc_nids = alc680_adc_nids;
19274 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19275 }
19276
19277 if (!spec->cap_mixer)
19278 set_capture_mixer(codec);
19279
19280 spec->vmaster_nid = 0x02;
19281
19282 codec->patch_ops = alc_patch_ops;
19283 if (board_config == ALC680_AUTO)
19284 spec->init_hook = alc680_auto_init;
19285
19286 return 0;
19287}
19288
1da177e4
LT
19289/*
19290 * patch entries
19291 */
1289e9e8 19292static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 19293 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 19294 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 19295 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 19296 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 19297 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 19298 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 19299 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 19300 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 19301 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 19302 .patch = patch_alc861 },
f32610ed
JS
19303 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19304 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19305 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 19306 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 19307 .patch = patch_alc882 },
bc9f98a9
KY
19308 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19309 .patch = patch_alc662 },
6dda9f4a 19310 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 19311 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 19312 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 19313 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 19314 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 19315 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 19316 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 19317 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 19318 .patch = patch_alc882 },
cb308f97 19319 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 19320 .patch = patch_alc882 },
df694daa 19321 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
4953550a 19322 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
4442608d 19323 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 19324 .patch = patch_alc882 },
274693f3 19325 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 19326 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 19327 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
19328 {} /* terminator */
19329};
1289e9e8
TI
19330
19331MODULE_ALIAS("snd-hda-codec-id:10ec*");
19332
19333MODULE_LICENSE("GPL");
19334MODULE_DESCRIPTION("Realtek HD-audio codec");
19335
19336static struct hda_codec_preset_list realtek_list = {
19337 .preset = snd_hda_preset_realtek,
19338 .owner = THIS_MODULE,
19339};
19340
19341static int __init patch_realtek_init(void)
19342{
19343 return snd_hda_add_codec_preset(&realtek_list);
19344}
19345
19346static void __exit patch_realtek_exit(void)
19347{
19348 snd_hda_delete_codec_preset(&realtek_list);
19349}
19350
19351module_init(patch_realtek_init)
19352module_exit(patch_realtek_exit)