]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Add PC-beep whitelist for an Intel board
[mirror_ubuntu-bionic-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
840b64c0
TI
5169/* set the default connection to that pin */
5170static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5171{
5172 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5173 int i;
5174
eaa9b3a7
TI
5175 for (i = 0; i < spec->num_adc_nids; i++) {
5176 hda_nid_t cap = spec->capsrc_nids ?
5177 spec->capsrc_nids[i] : spec->adc_nids[i];
5178 int idx;
5179
5180 idx = get_connection_index(codec, cap, pin);
5181 if (idx < 0)
5182 continue;
eaa9b3a7
TI
5183 /* select or unmute this route */
5184 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5185 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5186 HDA_AMP_MUTE, 0);
5187 } else {
5188 snd_hda_codec_write_cache(codec, cap, 0,
5189 AC_VERB_SET_CONNECT_SEL, idx);
5190 }
840b64c0
TI
5191 return i; /* return the found index */
5192 }
5193 return -1; /* not found */
5194}
5195
5196/* choose the ADC/MUX containing the input pin and initialize the setup */
5197static void fixup_single_adc(struct hda_codec *codec)
5198{
5199 struct alc_spec *spec = codec->spec;
5200 hda_nid_t pin = 0;
5201 int i;
5202
5203 /* search for the input pin; there must be only one */
5204 for (i = 0; i < AUTO_PIN_LAST; i++) {
5205 if (spec->autocfg.input_pins[i]) {
5206 pin = spec->autocfg.input_pins[i];
5207 break;
5208 }
5209 }
5210 if (!pin)
eaa9b3a7 5211 return;
840b64c0
TI
5212 i = init_capsrc_for_pin(codec, pin);
5213 if (i >= 0) {
5214 /* use only this ADC */
5215 if (spec->capsrc_nids)
5216 spec->capsrc_nids += i;
5217 spec->adc_nids += i;
5218 spec->num_adc_nids = 1;
eaa9b3a7
TI
5219 }
5220}
5221
840b64c0
TI
5222/* initialize dual adcs */
5223static void fixup_dual_adc_switch(struct hda_codec *codec)
5224{
5225 struct alc_spec *spec = codec->spec;
5226 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5227 init_capsrc_for_pin(codec, spec->int_mic.pin);
5228}
5229
b59bdf3b 5230static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5231{
b59bdf3b 5232 struct alc_spec *spec = codec->spec;
a23b688f
TI
5233 static struct snd_kcontrol_new *caps[2][3] = {
5234 { alc_capture_mixer_nosrc1,
5235 alc_capture_mixer_nosrc2,
5236 alc_capture_mixer_nosrc3 },
5237 { alc_capture_mixer1,
5238 alc_capture_mixer2,
5239 alc_capture_mixer3 },
f9e336f6 5240 };
a23b688f 5241 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5242 int mux = 0;
840b64c0
TI
5243 int num_adcs = spec->num_adc_nids;
5244 if (spec->dual_adc_switch)
5245 fixup_dual_adc_switch(codec);
5246 else if (spec->auto_mic)
b59bdf3b 5247 fixup_automic_adc(codec);
eaa9b3a7
TI
5248 else if (spec->input_mux) {
5249 if (spec->input_mux->num_items > 1)
5250 mux = 1;
5251 else if (spec->input_mux->num_items == 1)
5252 fixup_single_adc(codec);
5253 }
840b64c0
TI
5254 if (spec->dual_adc_switch)
5255 num_adcs = 1;
5256 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5257 }
f9e336f6
TI
5258}
5259
6694635d
TI
5260/* fill adc_nids (and capsrc_nids) containing all active input pins */
5261static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5262 int num_nids)
5263{
5264 struct alc_spec *spec = codec->spec;
5265 int n;
5266 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5267
5268 for (n = 0; n < num_nids; n++) {
5269 hda_nid_t adc, cap;
5270 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5271 int nconns, i, j;
5272
5273 adc = nids[n];
5274 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5275 continue;
5276 cap = adc;
5277 nconns = snd_hda_get_connections(codec, cap, conn,
5278 ARRAY_SIZE(conn));
5279 if (nconns == 1) {
5280 cap = conn[0];
5281 nconns = snd_hda_get_connections(codec, cap, conn,
5282 ARRAY_SIZE(conn));
5283 }
5284 if (nconns <= 0)
5285 continue;
5286 if (!fallback_adc) {
5287 fallback_adc = adc;
5288 fallback_cap = cap;
5289 }
5290 for (i = 0; i < AUTO_PIN_LAST; i++) {
5291 hda_nid_t nid = spec->autocfg.input_pins[i];
5292 if (!nid)
5293 continue;
5294 for (j = 0; j < nconns; j++) {
5295 if (conn[j] == nid)
5296 break;
5297 }
5298 if (j >= nconns)
5299 break;
5300 }
5301 if (i >= AUTO_PIN_LAST) {
5302 int num_adcs = spec->num_adc_nids;
5303 spec->private_adc_nids[num_adcs] = adc;
5304 spec->private_capsrc_nids[num_adcs] = cap;
5305 spec->num_adc_nids++;
5306 spec->adc_nids = spec->private_adc_nids;
5307 if (adc != cap)
5308 spec->capsrc_nids = spec->private_capsrc_nids;
5309 }
5310 }
5311 if (!spec->num_adc_nids) {
5312 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5313 " using fallback 0x%x\n",
5314 codec->chip_name, fallback_adc);
6694635d
TI
5315 spec->private_adc_nids[0] = fallback_adc;
5316 spec->adc_nids = spec->private_adc_nids;
5317 if (fallback_adc != fallback_cap) {
5318 spec->private_capsrc_nids[0] = fallback_cap;
5319 spec->capsrc_nids = spec->private_adc_nids;
5320 }
5321 }
5322}
5323
67d634c0 5324#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5325#define set_beep_amp(spec, nid, idx, dir) \
5326 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25
TI
5327
5328static struct snd_pci_quirk beep_white_list[] = {
5329 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
e096c8e6 5330 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5331 {}
5332};
5333
5334static inline int has_cdefine_beep(struct hda_codec *codec)
5335{
5336 struct alc_spec *spec = codec->spec;
5337 const struct snd_pci_quirk *q;
5338 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5339 if (q)
5340 return q->value;
5341 return spec->cdefine.enable_pcbeep;
5342}
67d634c0
TI
5343#else
5344#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5345#define has_cdefine_beep(codec) 0
67d634c0 5346#endif
45bdd1c1
TI
5347
5348/*
5349 * OK, here we have finally the patch for ALC880
5350 */
5351
1da177e4
LT
5352static int patch_alc880(struct hda_codec *codec)
5353{
5354 struct alc_spec *spec;
5355 int board_config;
df694daa 5356 int err;
1da177e4 5357
e560d8d8 5358 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5359 if (spec == NULL)
5360 return -ENOMEM;
5361
5362 codec->spec = spec;
5363
f5fcc13c
TI
5364 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5365 alc880_models,
5366 alc880_cfg_tbl);
5367 if (board_config < 0) {
9a11f1aa
TI
5368 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5369 codec->chip_name);
e9edcee0 5370 board_config = ALC880_AUTO;
1da177e4 5371 }
1da177e4 5372
e9edcee0
TI
5373 if (board_config == ALC880_AUTO) {
5374 /* automatic parse from the BIOS config */
5375 err = alc880_parse_auto_config(codec);
5376 if (err < 0) {
5377 alc_free(codec);
5378 return err;
f12ab1e0 5379 } else if (!err) {
9c7f852e
TI
5380 printk(KERN_INFO
5381 "hda_codec: Cannot set up configuration "
5382 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5383 board_config = ALC880_3ST;
5384 }
1da177e4
LT
5385 }
5386
680cd536
KK
5387 err = snd_hda_attach_beep_device(codec, 0x1);
5388 if (err < 0) {
5389 alc_free(codec);
5390 return err;
5391 }
5392
df694daa 5393 if (board_config != ALC880_AUTO)
e9c364c0 5394 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5395
1da177e4
LT
5396 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5397 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5398 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5399
1da177e4
LT
5400 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5401 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5402
f12ab1e0 5403 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5404 /* check whether NID 0x07 is valid */
54d17403 5405 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5406 /* get type */
a22d543a 5407 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5408 if (wcap != AC_WID_AUD_IN) {
5409 spec->adc_nids = alc880_adc_nids_alt;
5410 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5411 } else {
5412 spec->adc_nids = alc880_adc_nids;
5413 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5414 }
5415 }
b59bdf3b 5416 set_capture_mixer(codec);
45bdd1c1 5417 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5418
2134ea4f
TI
5419 spec->vmaster_nid = 0x0c;
5420
1da177e4 5421 codec->patch_ops = alc_patch_ops;
e9edcee0 5422 if (board_config == ALC880_AUTO)
ae6b813a 5423 spec->init_hook = alc880_auto_init;
cb53c626
TI
5424#ifdef CONFIG_SND_HDA_POWER_SAVE
5425 if (!spec->loopback.amplist)
5426 spec->loopback.amplist = alc880_loopbacks;
5427#endif
1da177e4
LT
5428
5429 return 0;
5430}
5431
e9edcee0 5432
1da177e4
LT
5433/*
5434 * ALC260 support
5435 */
5436
e9edcee0
TI
5437static hda_nid_t alc260_dac_nids[1] = {
5438 /* front */
5439 0x02,
5440};
5441
5442static hda_nid_t alc260_adc_nids[1] = {
5443 /* ADC0 */
5444 0x04,
5445};
5446
df694daa 5447static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5448 /* ADC1 */
5449 0x05,
5450};
5451
d57fdac0
JW
5452/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5453 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5454 */
5455static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5456 /* ADC0, ADC1 */
5457 0x04, 0x05
5458};
5459
e9edcee0
TI
5460#define ALC260_DIGOUT_NID 0x03
5461#define ALC260_DIGIN_NID 0x06
5462
5463static struct hda_input_mux alc260_capture_source = {
5464 .num_items = 4,
5465 .items = {
5466 { "Mic", 0x0 },
5467 { "Front Mic", 0x1 },
5468 { "Line", 0x2 },
5469 { "CD", 0x4 },
5470 },
5471};
5472
17e7aec6 5473/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5474 * headphone jack and the internal CD lines since these are the only pins at
5475 * which audio can appear. For flexibility, also allow the option of
5476 * recording the mixer output on the second ADC (ADC0 doesn't have a
5477 * connection to the mixer output).
a9430dd8 5478 */
a1e8d2da
JW
5479static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5480 {
5481 .num_items = 3,
5482 .items = {
5483 { "Mic/Line", 0x0 },
5484 { "CD", 0x4 },
5485 { "Headphone", 0x2 },
5486 },
a9430dd8 5487 },
a1e8d2da
JW
5488 {
5489 .num_items = 4,
5490 .items = {
5491 { "Mic/Line", 0x0 },
5492 { "CD", 0x4 },
5493 { "Headphone", 0x2 },
5494 { "Mixer", 0x5 },
5495 },
5496 },
5497
a9430dd8
JW
5498};
5499
a1e8d2da
JW
5500/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5501 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5502 */
a1e8d2da
JW
5503static struct hda_input_mux alc260_acer_capture_sources[2] = {
5504 {
5505 .num_items = 4,
5506 .items = {
5507 { "Mic", 0x0 },
5508 { "Line", 0x2 },
5509 { "CD", 0x4 },
5510 { "Headphone", 0x5 },
5511 },
5512 },
5513 {
5514 .num_items = 5,
5515 .items = {
5516 { "Mic", 0x0 },
5517 { "Line", 0x2 },
5518 { "CD", 0x4 },
5519 { "Headphone", 0x6 },
5520 { "Mixer", 0x5 },
5521 },
0bfc90e9
JW
5522 },
5523};
cc959489
MS
5524
5525/* Maxdata Favorit 100XS */
5526static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5527 {
5528 .num_items = 2,
5529 .items = {
5530 { "Line/Mic", 0x0 },
5531 { "CD", 0x4 },
5532 },
5533 },
5534 {
5535 .num_items = 3,
5536 .items = {
5537 { "Line/Mic", 0x0 },
5538 { "CD", 0x4 },
5539 { "Mixer", 0x5 },
5540 },
5541 },
5542};
5543
1da177e4
LT
5544/*
5545 * This is just place-holder, so there's something for alc_build_pcms to look
5546 * at when it calculates the maximum number of channels. ALC260 has no mixer
5547 * element which allows changing the channel mode, so the verb list is
5548 * never used.
5549 */
d2a6d7dc 5550static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5551 { 2, NULL },
5552};
5553
df694daa
KY
5554
5555/* Mixer combinations
5556 *
5557 * basic: base_output + input + pc_beep + capture
5558 * HP: base_output + input + capture_alt
5559 * HP_3013: hp_3013 + input + capture
5560 * fujitsu: fujitsu + capture
0bfc90e9 5561 * acer: acer + capture
df694daa
KY
5562 */
5563
5564static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5565 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5566 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5567 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5568 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5569 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5570 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5571 { } /* end */
f12ab1e0 5572};
1da177e4 5573
df694daa 5574static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5575 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5576 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5577 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5578 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5579 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5580 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5581 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5582 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5583 { } /* end */
5584};
5585
bec15c3a
TI
5586/* update HP, line and mono out pins according to the master switch */
5587static void alc260_hp_master_update(struct hda_codec *codec,
5588 hda_nid_t hp, hda_nid_t line,
5589 hda_nid_t mono)
5590{
5591 struct alc_spec *spec = codec->spec;
5592 unsigned int val = spec->master_sw ? PIN_HP : 0;
5593 /* change HP and line-out pins */
30cde0aa 5594 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5595 val);
30cde0aa 5596 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5597 val);
5598 /* mono (speaker) depending on the HP jack sense */
5599 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5600 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5601 val);
5602}
5603
5604static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5605 struct snd_ctl_elem_value *ucontrol)
5606{
5607 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5608 struct alc_spec *spec = codec->spec;
5609 *ucontrol->value.integer.value = spec->master_sw;
5610 return 0;
5611}
5612
5613static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5614 struct snd_ctl_elem_value *ucontrol)
5615{
5616 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5617 struct alc_spec *spec = codec->spec;
5618 int val = !!*ucontrol->value.integer.value;
5619 hda_nid_t hp, line, mono;
5620
5621 if (val == spec->master_sw)
5622 return 0;
5623 spec->master_sw = val;
5624 hp = (kcontrol->private_value >> 16) & 0xff;
5625 line = (kcontrol->private_value >> 8) & 0xff;
5626 mono = kcontrol->private_value & 0xff;
5627 alc260_hp_master_update(codec, hp, line, mono);
5628 return 1;
5629}
5630
5631static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5632 {
5633 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5634 .name = "Master Playback Switch",
5b0cb1d8 5635 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5636 .info = snd_ctl_boolean_mono_info,
5637 .get = alc260_hp_master_sw_get,
5638 .put = alc260_hp_master_sw_put,
5639 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5640 },
5641 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5642 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5643 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5644 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5645 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5646 HDA_OUTPUT),
5647 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5648 { } /* end */
5649};
5650
5651static struct hda_verb alc260_hp_unsol_verbs[] = {
5652 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5653 {},
5654};
5655
5656static void alc260_hp_automute(struct hda_codec *codec)
5657{
5658 struct alc_spec *spec = codec->spec;
bec15c3a 5659
864f92be 5660 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5661 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5662}
5663
5664static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5665{
5666 if ((res >> 26) == ALC880_HP_EVENT)
5667 alc260_hp_automute(codec);
5668}
5669
df694daa 5670static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5671 {
5672 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5673 .name = "Master Playback Switch",
5b0cb1d8 5674 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5675 .info = snd_ctl_boolean_mono_info,
5676 .get = alc260_hp_master_sw_get,
5677 .put = alc260_hp_master_sw_put,
30cde0aa 5678 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5679 },
df694daa
KY
5680 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5681 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5682 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5683 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5684 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5685 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
5686 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5687 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
5688 { } /* end */
5689};
5690
3f878308
KY
5691static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5692 .ops = &snd_hda_bind_vol,
5693 .values = {
5694 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5695 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5696 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5697 0
5698 },
5699};
5700
5701static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5702 .ops = &snd_hda_bind_sw,
5703 .values = {
5704 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5705 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5706 0
5707 },
5708};
5709
5710static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5711 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5712 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5713 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5714 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5715 { } /* end */
5716};
5717
bec15c3a
TI
5718static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5719 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5720 {},
5721};
5722
5723static void alc260_hp_3013_automute(struct hda_codec *codec)
5724{
5725 struct alc_spec *spec = codec->spec;
bec15c3a 5726
864f92be 5727 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 5728 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
5729}
5730
5731static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5732 unsigned int res)
5733{
5734 if ((res >> 26) == ALC880_HP_EVENT)
5735 alc260_hp_3013_automute(codec);
5736}
5737
3f878308
KY
5738static void alc260_hp_3012_automute(struct hda_codec *codec)
5739{
864f92be 5740 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 5741
3f878308
KY
5742 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5743 bits);
5744 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5745 bits);
5746 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5747 bits);
5748}
5749
5750static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5751 unsigned int res)
5752{
5753 if ((res >> 26) == ALC880_HP_EVENT)
5754 alc260_hp_3012_automute(codec);
5755}
5756
5757/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
5758 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5759 */
c8b6bf9b 5760static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 5761 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5762 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 5763 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
5764 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5765 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5766 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5767 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 5768 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
5769 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5770 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
5771 { } /* end */
5772};
5773
a1e8d2da
JW
5774/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5775 * versions of the ALC260 don't act on requests to enable mic bias from NID
5776 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5777 * datasheet doesn't mention this restriction. At this stage it's not clear
5778 * whether this behaviour is intentional or is a hardware bug in chip
5779 * revisions available in early 2006. Therefore for now allow the
5780 * "Headphone Jack Mode" control to span all choices, but if it turns out
5781 * that the lack of mic bias for this NID is intentional we could change the
5782 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5783 *
5784 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5785 * don't appear to make the mic bias available from the "line" jack, even
5786 * though the NID used for this jack (0x14) can supply it. The theory is
5787 * that perhaps Acer have included blocking capacitors between the ALC260
5788 * and the output jack. If this turns out to be the case for all such
5789 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5790 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
5791 *
5792 * The C20x Tablet series have a mono internal speaker which is controlled
5793 * via the chip's Mono sum widget and pin complex, so include the necessary
5794 * controls for such models. On models without a "mono speaker" the control
5795 * won't do anything.
a1e8d2da 5796 */
0bfc90e9
JW
5797static struct snd_kcontrol_new alc260_acer_mixer[] = {
5798 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5799 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 5800 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 5801 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 5802 HDA_OUTPUT),
31bffaa9 5803 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 5804 HDA_INPUT),
0bfc90e9
JW
5805 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5806 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5807 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5808 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5809 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5810 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5811 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5812 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
5813 { } /* end */
5814};
5815
cc959489
MS
5816/* Maxdata Favorit 100XS: one output and one input (0x12) jack
5817 */
5818static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5819 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5820 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5821 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5822 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5823 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5824 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5825 { } /* end */
5826};
5827
bc9f98a9
KY
5828/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5829 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5830 */
5831static struct snd_kcontrol_new alc260_will_mixer[] = {
5832 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5833 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5834 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5835 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5836 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5837 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5838 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5839 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5840 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5841 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
5842 { } /* end */
5843};
5844
5845/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5846 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5847 */
5848static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5849 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5850 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5851 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5852 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5853 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5854 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5855 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5856 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5857 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5858 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5859 { } /* end */
5860};
5861
df694daa
KY
5862/*
5863 * initialization verbs
5864 */
1da177e4
LT
5865static struct hda_verb alc260_init_verbs[] = {
5866 /* Line In pin widget for input */
05acb863 5867 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5868 /* CD pin widget for input */
05acb863 5869 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5870 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 5871 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5872 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 5873 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5874 /* LINE-2 is used for line-out in rear */
05acb863 5875 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5876 /* select line-out */
fd56f2db 5877 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5878 /* LINE-OUT pin */
05acb863 5879 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5880 /* enable HP */
05acb863 5881 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 5882 /* enable Mono */
05acb863
TI
5883 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5884 /* mute capture amp left and right */
16ded525 5885 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
5886 /* set connection select to line in (default select for this ADC) */
5887 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
5888 /* mute capture amp left and right */
5889 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5890 /* set connection select to line in (default select for this ADC) */
5891 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
5892 /* set vol=0 Line-Out mixer amp left and right */
5893 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5894 /* unmute pin widget amp left and right (no gain on this amp) */
5895 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5896 /* set vol=0 HP mixer amp left and right */
5897 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5898 /* unmute pin widget amp left and right (no gain on this amp) */
5899 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5900 /* set vol=0 Mono mixer amp left and right */
5901 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5902 /* unmute pin widget amp left and right (no gain on this amp) */
5903 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5904 /* unmute LINE-2 out pin */
5905 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
5906 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5907 * Line In 2 = 0x03
5908 */
cb53c626
TI
5909 /* mute analog inputs */
5910 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5911 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5912 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5913 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5914 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5915 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
5916 /* mute Front out path */
5917 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5918 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5919 /* mute Headphone out path */
5920 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5921 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5922 /* mute Mono out path */
5923 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5924 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
5925 { }
5926};
5927
474167d6 5928#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
5929static struct hda_verb alc260_hp_init_verbs[] = {
5930 /* Headphone and output */
5931 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5932 /* mono output */
5933 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5934 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5935 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5936 /* Mic2 (front panel) pin widget for input and vref at 80% */
5937 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5938 /* Line In pin widget for input */
5939 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5940 /* Line-2 pin widget for output */
5941 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5942 /* CD pin widget for input */
5943 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5944 /* unmute amp left and right */
5945 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5946 /* set connection select to line in (default select for this ADC) */
5947 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5948 /* unmute Line-Out mixer amp left and right (volume = 0) */
5949 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5950 /* mute pin widget amp left and right (no gain on this amp) */
5951 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5952 /* unmute HP mixer amp left and right (volume = 0) */
5953 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5954 /* mute pin widget amp left and right (no gain on this amp) */
5955 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5956 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5957 * Line In 2 = 0x03
5958 */
cb53c626
TI
5959 /* mute analog inputs */
5960 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5961 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5962 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5963 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5964 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5965 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5966 /* Unmute Front out path */
5967 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5968 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5969 /* Unmute Headphone out path */
5970 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5971 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5972 /* Unmute Mono out path */
5973 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5974 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5975 { }
5976};
474167d6 5977#endif
df694daa
KY
5978
5979static struct hda_verb alc260_hp_3013_init_verbs[] = {
5980 /* Line out and output */
5981 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5982 /* mono output */
5983 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5984 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5985 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5986 /* Mic2 (front panel) pin widget for input and vref at 80% */
5987 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5988 /* Line In pin widget for input */
5989 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5990 /* Headphone pin widget for output */
5991 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5992 /* CD pin widget for input */
5993 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5994 /* unmute amp left and right */
5995 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5996 /* set connection select to line in (default select for this ADC) */
5997 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5998 /* unmute Line-Out mixer amp left and right (volume = 0) */
5999 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6000 /* mute pin widget amp left and right (no gain on this amp) */
6001 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6002 /* unmute HP mixer amp left and right (volume = 0) */
6003 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6004 /* mute pin widget amp left and right (no gain on this amp) */
6005 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6006 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6007 * Line In 2 = 0x03
6008 */
cb53c626
TI
6009 /* mute analog inputs */
6010 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6011 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6012 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6013 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6014 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6015 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6016 /* Unmute Front out path */
6017 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6018 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6019 /* Unmute Headphone out path */
6020 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6021 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6022 /* Unmute Mono out path */
6023 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6024 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6025 { }
6026};
6027
a9430dd8 6028/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6029 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6030 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
6031 */
6032static struct hda_verb alc260_fujitsu_init_verbs[] = {
6033 /* Disable all GPIOs */
6034 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6035 /* Internal speaker is connected to headphone pin */
6036 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6037 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6038 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6039 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6040 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6041 /* Ensure all other unused pins are disabled and muted. */
6042 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6043 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6044 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6045 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6046 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6047 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6048 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6049 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6050
6051 /* Disable digital (SPDIF) pins */
6052 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6053 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6054
ea1fb29a 6055 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6056 * when acting as an output.
6057 */
6058 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6059
f7ace40d 6060 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6061 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6062 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6063 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6064 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6065 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6066 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6067 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6068 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6069 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6070
f7ace40d
JW
6071 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6072 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6073 /* Unmute Line1 pin widget output buffer since it starts as an output.
6074 * If the pin mode is changed by the user the pin mode control will
6075 * take care of enabling the pin's input/output buffers as needed.
6076 * Therefore there's no need to enable the input buffer at this
6077 * stage.
cdcd9268 6078 */
f7ace40d 6079 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6080 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6081 * mixer ctrl)
6082 */
f7ace40d
JW
6083 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6084
6085 /* Mute capture amp left and right */
6086 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6087 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6088 * in (on mic1 pin)
6089 */
6090 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6091
6092 /* Do the same for the second ADC: mute capture input amp and
6093 * set ADC connection to line in (on mic1 pin)
6094 */
6095 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6096 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6097
6098 /* Mute all inputs to mixer widget (even unconnected ones) */
6099 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6100 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6101 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6102 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6103 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6104 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6105 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6106 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6107
6108 { }
a9430dd8
JW
6109};
6110
0bfc90e9
JW
6111/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6112 * similar laptops (adapted from Fujitsu init verbs).
6113 */
6114static struct hda_verb alc260_acer_init_verbs[] = {
6115 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6116 * the headphone jack. Turn this on and rely on the standard mute
6117 * methods whenever the user wants to turn these outputs off.
6118 */
6119 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6120 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6121 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6122 /* Internal speaker/Headphone jack is connected to Line-out pin */
6123 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6124 /* Internal microphone/Mic jack is connected to Mic1 pin */
6125 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6126 /* Line In jack is connected to Line1 pin */
6127 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6128 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6129 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6130 /* Ensure all other unused pins are disabled and muted. */
6131 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6132 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6133 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6134 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6135 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6136 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6137 /* Disable digital (SPDIF) pins */
6138 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6139 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6140
ea1fb29a 6141 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6142 * bus when acting as outputs.
6143 */
6144 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6145 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6146
6147 /* Start with output sum widgets muted and their output gains at min */
6148 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6149 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6150 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6151 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6152 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6153 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6154 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6155 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6156 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6157
f12ab1e0
TI
6158 /* Unmute Line-out pin widget amp left and right
6159 * (no equiv mixer ctrl)
6160 */
0bfc90e9 6161 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6162 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6163 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6164 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6165 * inputs. If the pin mode is changed by the user the pin mode control
6166 * will take care of enabling the pin's input/output buffers as needed.
6167 * Therefore there's no need to enable the input buffer at this
6168 * stage.
6169 */
6170 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6171 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6172
6173 /* Mute capture amp left and right */
6174 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6175 /* Set ADC connection select to match default mixer setting - mic
6176 * (on mic1 pin)
6177 */
6178 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6179
6180 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6181 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6182 */
6183 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6184 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6185
6186 /* Mute all inputs to mixer widget (even unconnected ones) */
6187 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6188 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6189 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6190 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6191 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6192 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6193 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6194 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6195
6196 { }
6197};
6198
cc959489
MS
6199/* Initialisation sequence for Maxdata Favorit 100XS
6200 * (adapted from Acer init verbs).
6201 */
6202static struct hda_verb alc260_favorit100_init_verbs[] = {
6203 /* GPIO 0 enables the output jack.
6204 * Turn this on and rely on the standard mute
6205 * methods whenever the user wants to turn these outputs off.
6206 */
6207 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6208 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6209 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6210 /* Line/Mic input jack is connected to Mic1 pin */
6211 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6212 /* Ensure all other unused pins are disabled and muted. */
6213 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6214 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6215 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6216 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6217 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6218 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6219 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6220 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6221 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6222 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6223 /* Disable digital (SPDIF) pins */
6224 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6225 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6226
6227 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6228 * bus when acting as outputs.
6229 */
6230 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6231 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6232
6233 /* Start with output sum widgets muted and their output gains at min */
6234 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6235 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6236 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6237 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6238 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6239 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6240 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6241 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6242 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6243
6244 /* Unmute Line-out pin widget amp left and right
6245 * (no equiv mixer ctrl)
6246 */
6247 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6248 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6249 * inputs. If the pin mode is changed by the user the pin mode control
6250 * will take care of enabling the pin's input/output buffers as needed.
6251 * Therefore there's no need to enable the input buffer at this
6252 * stage.
6253 */
6254 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6255
6256 /* Mute capture amp left and right */
6257 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6258 /* Set ADC connection select to match default mixer setting - mic
6259 * (on mic1 pin)
6260 */
6261 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6262
6263 /* Do similar with the second ADC: mute capture input amp and
6264 * set ADC connection to mic to match ALSA's default state.
6265 */
6266 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6267 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6268
6269 /* Mute all inputs to mixer widget (even unconnected ones) */
6270 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6271 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6272 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6273 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6274 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6275 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6276 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6277 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6278
6279 { }
6280};
6281
bc9f98a9
KY
6282static struct hda_verb alc260_will_verbs[] = {
6283 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6284 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6285 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6286 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6287 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6288 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6289 {}
6290};
6291
6292static struct hda_verb alc260_replacer_672v_verbs[] = {
6293 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6294 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6295 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6296
6297 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6298 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6299 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6300
6301 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6302 {}
6303};
6304
6305/* toggle speaker-output according to the hp-jack state */
6306static void alc260_replacer_672v_automute(struct hda_codec *codec)
6307{
6308 unsigned int present;
6309
6310 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6311 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6312 if (present) {
82beb8fd
TI
6313 snd_hda_codec_write_cache(codec, 0x01, 0,
6314 AC_VERB_SET_GPIO_DATA, 1);
6315 snd_hda_codec_write_cache(codec, 0x0f, 0,
6316 AC_VERB_SET_PIN_WIDGET_CONTROL,
6317 PIN_HP);
bc9f98a9 6318 } else {
82beb8fd
TI
6319 snd_hda_codec_write_cache(codec, 0x01, 0,
6320 AC_VERB_SET_GPIO_DATA, 0);
6321 snd_hda_codec_write_cache(codec, 0x0f, 0,
6322 AC_VERB_SET_PIN_WIDGET_CONTROL,
6323 PIN_OUT);
bc9f98a9
KY
6324 }
6325}
6326
6327static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6328 unsigned int res)
6329{
6330 if ((res >> 26) == ALC880_HP_EVENT)
6331 alc260_replacer_672v_automute(codec);
6332}
6333
3f878308
KY
6334static struct hda_verb alc260_hp_dc7600_verbs[] = {
6335 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6336 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6337 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6338 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6339 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6340 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6341 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6342 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6343 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6344 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6345 {}
6346};
6347
7cf51e48
JW
6348/* Test configuration for debugging, modelled after the ALC880 test
6349 * configuration.
6350 */
6351#ifdef CONFIG_SND_DEBUG
6352static hda_nid_t alc260_test_dac_nids[1] = {
6353 0x02,
6354};
6355static hda_nid_t alc260_test_adc_nids[2] = {
6356 0x04, 0x05,
6357};
a1e8d2da 6358/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6359 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6360 * is NID 0x04.
17e7aec6 6361 */
a1e8d2da
JW
6362static struct hda_input_mux alc260_test_capture_sources[2] = {
6363 {
6364 .num_items = 7,
6365 .items = {
6366 { "MIC1 pin", 0x0 },
6367 { "MIC2 pin", 0x1 },
6368 { "LINE1 pin", 0x2 },
6369 { "LINE2 pin", 0x3 },
6370 { "CD pin", 0x4 },
6371 { "LINE-OUT pin", 0x5 },
6372 { "HP-OUT pin", 0x6 },
6373 },
6374 },
6375 {
6376 .num_items = 8,
6377 .items = {
6378 { "MIC1 pin", 0x0 },
6379 { "MIC2 pin", 0x1 },
6380 { "LINE1 pin", 0x2 },
6381 { "LINE2 pin", 0x3 },
6382 { "CD pin", 0x4 },
6383 { "Mixer", 0x5 },
6384 { "LINE-OUT pin", 0x6 },
6385 { "HP-OUT pin", 0x7 },
6386 },
7cf51e48
JW
6387 },
6388};
6389static struct snd_kcontrol_new alc260_test_mixer[] = {
6390 /* Output driver widgets */
6391 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6392 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6393 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6394 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6395 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6396 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6397
a1e8d2da
JW
6398 /* Modes for retasking pin widgets
6399 * Note: the ALC260 doesn't seem to act on requests to enable mic
6400 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6401 * mention this restriction. At this stage it's not clear whether
6402 * this behaviour is intentional or is a hardware bug in chip
6403 * revisions available at least up until early 2006. Therefore for
6404 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6405 * choices, but if it turns out that the lack of mic bias for these
6406 * NIDs is intentional we could change their modes from
6407 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6408 */
7cf51e48
JW
6409 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6410 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6411 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6412 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6413 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6414 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6415
6416 /* Loopback mixer controls */
6417 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6418 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6419 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6420 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6421 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6422 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6423 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6424 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6425 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6426 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6427 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6428 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6429 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6430 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6431
6432 /* Controls for GPIO pins, assuming they are configured as outputs */
6433 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6434 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6435 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6436 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6437
92621f13
JW
6438 /* Switches to allow the digital IO pins to be enabled. The datasheet
6439 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6440 * make this output available should provide clarification.
92621f13
JW
6441 */
6442 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6443 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6444
f8225f6d
JW
6445 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6446 * this output to turn on an external amplifier.
6447 */
6448 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6449 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6450
7cf51e48
JW
6451 { } /* end */
6452};
6453static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6454 /* Enable all GPIOs as outputs with an initial value of 0 */
6455 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6456 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6457 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6458
7cf51e48
JW
6459 /* Enable retasking pins as output, initially without power amp */
6460 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6461 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6462 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6463 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6464 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6465 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6466
92621f13
JW
6467 /* Disable digital (SPDIF) pins initially, but users can enable
6468 * them via a mixer switch. In the case of SPDIF-out, this initverb
6469 * payload also sets the generation to 0, output to be in "consumer"
6470 * PCM format, copyright asserted, no pre-emphasis and no validity
6471 * control.
6472 */
7cf51e48
JW
6473 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6474 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6475
ea1fb29a 6476 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6477 * OUT1 sum bus when acting as an output.
6478 */
6479 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6480 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6481 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6482 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6483
6484 /* Start with output sum widgets muted and their output gains at min */
6485 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6486 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6487 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6488 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6489 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6490 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6491 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6492 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6493 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6494
cdcd9268
JW
6495 /* Unmute retasking pin widget output buffers since the default
6496 * state appears to be output. As the pin mode is changed by the
6497 * user the pin mode control will take care of enabling the pin's
6498 * input/output buffers as needed.
6499 */
7cf51e48
JW
6500 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6501 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6502 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6503 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6504 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6505 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6506 /* Also unmute the mono-out pin widget */
6507 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6508
7cf51e48
JW
6509 /* Mute capture amp left and right */
6510 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6511 /* Set ADC connection select to match default mixer setting (mic1
6512 * pin)
7cf51e48
JW
6513 */
6514 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6515
6516 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6517 * set ADC connection to mic1 pin
7cf51e48
JW
6518 */
6519 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6520 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6521
6522 /* Mute all inputs to mixer widget (even unconnected ones) */
6523 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6524 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6525 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6526 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6527 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6528 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6529 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6530 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6531
6532 { }
6533};
6534#endif
6535
6330079f
TI
6536#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6537#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6538
a3bcba38
TI
6539#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6540#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6541
df694daa
KY
6542/*
6543 * for BIOS auto-configuration
6544 */
16ded525 6545
df694daa 6546static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6547 const char *pfx, int *vol_bits)
df694daa
KY
6548{
6549 hda_nid_t nid_vol;
6550 unsigned long vol_val, sw_val;
df694daa
KY
6551 int err;
6552
6553 if (nid >= 0x0f && nid < 0x11) {
6554 nid_vol = nid - 0x7;
6555 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6556 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6557 } else if (nid == 0x11) {
6558 nid_vol = nid - 0x7;
6559 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6560 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6561 } else if (nid >= 0x12 && nid <= 0x15) {
6562 nid_vol = 0x08;
6563 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6564 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6565 } else
6566 return 0; /* N/A */
ea1fb29a 6567
863b4518
TI
6568 if (!(*vol_bits & (1 << nid_vol))) {
6569 /* first control for the volume widget */
0afe5f89 6570 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6571 if (err < 0)
6572 return err;
6573 *vol_bits |= (1 << nid_vol);
6574 }
0afe5f89 6575 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6576 if (err < 0)
df694daa
KY
6577 return err;
6578 return 1;
6579}
6580
6581/* add playback controls from the parsed DAC table */
6582static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6583 const struct auto_pin_cfg *cfg)
6584{
6585 hda_nid_t nid;
6586 int err;
863b4518 6587 int vols = 0;
df694daa
KY
6588
6589 spec->multiout.num_dacs = 1;
6590 spec->multiout.dac_nids = spec->private_dac_nids;
6591 spec->multiout.dac_nids[0] = 0x02;
6592
6593 nid = cfg->line_out_pins[0];
6594 if (nid) {
23112d6d
TI
6595 const char *pfx;
6596 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6597 pfx = "Master";
6598 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6599 pfx = "Speaker";
6600 else
6601 pfx = "Front";
6602 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6603 if (err < 0)
6604 return err;
6605 }
6606
82bc955f 6607 nid = cfg->speaker_pins[0];
df694daa 6608 if (nid) {
863b4518 6609 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6610 if (err < 0)
6611 return err;
6612 }
6613
eb06ed8f 6614 nid = cfg->hp_pins[0];
df694daa 6615 if (nid) {
863b4518
TI
6616 err = alc260_add_playback_controls(spec, nid, "Headphone",
6617 &vols);
df694daa
KY
6618 if (err < 0)
6619 return err;
6620 }
f12ab1e0 6621 return 0;
df694daa
KY
6622}
6623
6624/* create playback/capture controls for input pins */
05f5f477 6625static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6626 const struct auto_pin_cfg *cfg)
6627{
05f5f477 6628 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6629}
6630
6631static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6632 hda_nid_t nid, int pin_type,
6633 int sel_idx)
6634{
f6c7e546 6635 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6636 /* need the manual connection? */
6637 if (nid >= 0x12) {
6638 int idx = nid - 0x12;
6639 snd_hda_codec_write(codec, idx + 0x0b, 0,
6640 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6641 }
6642}
6643
6644static void alc260_auto_init_multi_out(struct hda_codec *codec)
6645{
6646 struct alc_spec *spec = codec->spec;
6647 hda_nid_t nid;
6648
f12ab1e0 6649 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6650 if (nid) {
6651 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6652 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6653 }
ea1fb29a 6654
82bc955f 6655 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6656 if (nid)
6657 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6658
eb06ed8f 6659 nid = spec->autocfg.hp_pins[0];
df694daa 6660 if (nid)
baba8ee9 6661 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6662}
df694daa
KY
6663
6664#define ALC260_PIN_CD_NID 0x16
6665static void alc260_auto_init_analog_input(struct hda_codec *codec)
6666{
6667 struct alc_spec *spec = codec->spec;
6668 int i;
6669
6670 for (i = 0; i < AUTO_PIN_LAST; i++) {
6671 hda_nid_t nid = spec->autocfg.input_pins[i];
6672 if (nid >= 0x12) {
23f0c048 6673 alc_set_input_pin(codec, nid, i);
e82c025b
TI
6674 if (nid != ALC260_PIN_CD_NID &&
6675 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6676 snd_hda_codec_write(codec, nid, 0,
6677 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6678 AMP_OUT_MUTE);
6679 }
6680 }
6681}
6682
7f311a46
TI
6683#define alc260_auto_init_input_src alc880_auto_init_input_src
6684
df694daa
KY
6685/*
6686 * generic initialization of ADC, input mixers and output mixers
6687 */
6688static struct hda_verb alc260_volume_init_verbs[] = {
6689 /*
6690 * Unmute ADC0-1 and set the default input to mic-in
6691 */
6692 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6693 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6694 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6695 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 6696
df694daa
KY
6697 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6698 * mixer widget
f12ab1e0
TI
6699 * Note: PASD motherboards uses the Line In 2 as the input for
6700 * front panel mic (mic 2)
df694daa
KY
6701 */
6702 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6703 /* mute analog inputs */
6704 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6705 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6706 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6707 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6708 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6709
6710 /*
6711 * Set up output mixers (0x08 - 0x0a)
6712 */
6713 /* set vol=0 to output mixers */
6714 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6715 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6716 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6717 /* set up input amps for analog loopback */
6718 /* Amp Indices: DAC = 0, mixer = 1 */
6719 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6720 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6721 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6722 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6723 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6724 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 6725
df694daa
KY
6726 { }
6727};
6728
6729static int alc260_parse_auto_config(struct hda_codec *codec)
6730{
6731 struct alc_spec *spec = codec->spec;
df694daa
KY
6732 int err;
6733 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6734
f12ab1e0
TI
6735 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6736 alc260_ignore);
6737 if (err < 0)
df694daa 6738 return err;
f12ab1e0
TI
6739 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6740 if (err < 0)
4a471b7d 6741 return err;
603c4019 6742 if (!spec->kctls.list)
df694daa 6743 return 0; /* can't find valid BIOS pin config */
05f5f477 6744 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 6745 if (err < 0)
df694daa
KY
6746 return err;
6747
6748 spec->multiout.max_channels = 2;
6749
0852d7a6 6750 if (spec->autocfg.dig_outs)
df694daa 6751 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 6752 if (spec->kctls.list)
d88897ea 6753 add_mixer(spec, spec->kctls.list);
df694daa 6754
d88897ea 6755 add_verb(spec, alc260_volume_init_verbs);
df694daa 6756
a1e8d2da 6757 spec->num_mux_defs = 1;
61b9b9b1 6758 spec->input_mux = &spec->private_imux[0];
df694daa 6759
6227cdce 6760 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 6761
df694daa
KY
6762 return 1;
6763}
6764
ae6b813a
TI
6765/* additional initialization for auto-configuration model */
6766static void alc260_auto_init(struct hda_codec *codec)
df694daa 6767{
f6c7e546 6768 struct alc_spec *spec = codec->spec;
df694daa
KY
6769 alc260_auto_init_multi_out(codec);
6770 alc260_auto_init_analog_input(codec);
7f311a46 6771 alc260_auto_init_input_src(codec);
757899ac 6772 alc_auto_init_digital(codec);
f6c7e546 6773 if (spec->unsol_event)
7fb0d78f 6774 alc_inithook(codec);
df694daa
KY
6775}
6776
cb53c626
TI
6777#ifdef CONFIG_SND_HDA_POWER_SAVE
6778static struct hda_amp_list alc260_loopbacks[] = {
6779 { 0x07, HDA_INPUT, 0 },
6780 { 0x07, HDA_INPUT, 1 },
6781 { 0x07, HDA_INPUT, 2 },
6782 { 0x07, HDA_INPUT, 3 },
6783 { 0x07, HDA_INPUT, 4 },
6784 { } /* end */
6785};
6786#endif
6787
df694daa
KY
6788/*
6789 * ALC260 configurations
6790 */
f5fcc13c
TI
6791static const char *alc260_models[ALC260_MODEL_LAST] = {
6792 [ALC260_BASIC] = "basic",
6793 [ALC260_HP] = "hp",
6794 [ALC260_HP_3013] = "hp-3013",
2922c9af 6795 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
6796 [ALC260_FUJITSU_S702X] = "fujitsu",
6797 [ALC260_ACER] = "acer",
bc9f98a9
KY
6798 [ALC260_WILL] = "will",
6799 [ALC260_REPLACER_672V] = "replacer",
cc959489 6800 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 6801#ifdef CONFIG_SND_DEBUG
f5fcc13c 6802 [ALC260_TEST] = "test",
7cf51e48 6803#endif
f5fcc13c
TI
6804 [ALC260_AUTO] = "auto",
6805};
6806
6807static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 6808 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 6809 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 6810 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 6811 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 6812 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 6813 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 6814 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 6815 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 6816 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
6817 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6818 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6819 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6820 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6821 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6822 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6823 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6824 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6825 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 6826 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 6827 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
6828 {}
6829};
6830
6831static struct alc_config_preset alc260_presets[] = {
6832 [ALC260_BASIC] = {
6833 .mixers = { alc260_base_output_mixer,
45bdd1c1 6834 alc260_input_mixer },
df694daa
KY
6835 .init_verbs = { alc260_init_verbs },
6836 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6837 .dac_nids = alc260_dac_nids,
f9e336f6 6838 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 6839 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
6840 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6841 .channel_mode = alc260_modes,
6842 .input_mux = &alc260_capture_source,
6843 },
6844 [ALC260_HP] = {
bec15c3a 6845 .mixers = { alc260_hp_output_mixer,
f9e336f6 6846 alc260_input_mixer },
bec15c3a
TI
6847 .init_verbs = { alc260_init_verbs,
6848 alc260_hp_unsol_verbs },
df694daa
KY
6849 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6850 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6851 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6852 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6853 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6854 .channel_mode = alc260_modes,
6855 .input_mux = &alc260_capture_source,
bec15c3a
TI
6856 .unsol_event = alc260_hp_unsol_event,
6857 .init_hook = alc260_hp_automute,
df694daa 6858 },
3f878308
KY
6859 [ALC260_HP_DC7600] = {
6860 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 6861 alc260_input_mixer },
3f878308
KY
6862 .init_verbs = { alc260_init_verbs,
6863 alc260_hp_dc7600_verbs },
6864 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6865 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6866 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6867 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
6868 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6869 .channel_mode = alc260_modes,
6870 .input_mux = &alc260_capture_source,
6871 .unsol_event = alc260_hp_3012_unsol_event,
6872 .init_hook = alc260_hp_3012_automute,
6873 },
df694daa
KY
6874 [ALC260_HP_3013] = {
6875 .mixers = { alc260_hp_3013_mixer,
f9e336f6 6876 alc260_input_mixer },
bec15c3a
TI
6877 .init_verbs = { alc260_hp_3013_init_verbs,
6878 alc260_hp_3013_unsol_verbs },
df694daa
KY
6879 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6880 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6881 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6882 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6883 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6884 .channel_mode = alc260_modes,
6885 .input_mux = &alc260_capture_source,
bec15c3a
TI
6886 .unsol_event = alc260_hp_3013_unsol_event,
6887 .init_hook = alc260_hp_3013_automute,
df694daa
KY
6888 },
6889 [ALC260_FUJITSU_S702X] = {
f9e336f6 6890 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
6891 .init_verbs = { alc260_fujitsu_init_verbs },
6892 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6893 .dac_nids = alc260_dac_nids,
d57fdac0
JW
6894 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6895 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
6896 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6897 .channel_mode = alc260_modes,
a1e8d2da
JW
6898 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6899 .input_mux = alc260_fujitsu_capture_sources,
df694daa 6900 },
0bfc90e9 6901 [ALC260_ACER] = {
f9e336f6 6902 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
6903 .init_verbs = { alc260_acer_init_verbs },
6904 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6905 .dac_nids = alc260_dac_nids,
6906 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6907 .adc_nids = alc260_dual_adc_nids,
6908 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6909 .channel_mode = alc260_modes,
a1e8d2da
JW
6910 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6911 .input_mux = alc260_acer_capture_sources,
0bfc90e9 6912 },
cc959489
MS
6913 [ALC260_FAVORIT100] = {
6914 .mixers = { alc260_favorit100_mixer },
6915 .init_verbs = { alc260_favorit100_init_verbs },
6916 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6917 .dac_nids = alc260_dac_nids,
6918 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6919 .adc_nids = alc260_dual_adc_nids,
6920 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6921 .channel_mode = alc260_modes,
6922 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6923 .input_mux = alc260_favorit100_capture_sources,
6924 },
bc9f98a9 6925 [ALC260_WILL] = {
f9e336f6 6926 .mixers = { alc260_will_mixer },
bc9f98a9
KY
6927 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6928 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6929 .dac_nids = alc260_dac_nids,
6930 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6931 .adc_nids = alc260_adc_nids,
6932 .dig_out_nid = ALC260_DIGOUT_NID,
6933 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6934 .channel_mode = alc260_modes,
6935 .input_mux = &alc260_capture_source,
6936 },
6937 [ALC260_REPLACER_672V] = {
f9e336f6 6938 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
6939 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6940 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6941 .dac_nids = alc260_dac_nids,
6942 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6943 .adc_nids = alc260_adc_nids,
6944 .dig_out_nid = ALC260_DIGOUT_NID,
6945 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6946 .channel_mode = alc260_modes,
6947 .input_mux = &alc260_capture_source,
6948 .unsol_event = alc260_replacer_672v_unsol_event,
6949 .init_hook = alc260_replacer_672v_automute,
6950 },
7cf51e48
JW
6951#ifdef CONFIG_SND_DEBUG
6952 [ALC260_TEST] = {
f9e336f6 6953 .mixers = { alc260_test_mixer },
7cf51e48
JW
6954 .init_verbs = { alc260_test_init_verbs },
6955 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6956 .dac_nids = alc260_test_dac_nids,
6957 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6958 .adc_nids = alc260_test_adc_nids,
6959 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6960 .channel_mode = alc260_modes,
a1e8d2da
JW
6961 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6962 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
6963 },
6964#endif
df694daa
KY
6965};
6966
6967static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
6968{
6969 struct alc_spec *spec;
df694daa 6970 int err, board_config;
1da177e4 6971
e560d8d8 6972 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
6973 if (spec == NULL)
6974 return -ENOMEM;
6975
6976 codec->spec = spec;
6977
f5fcc13c
TI
6978 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6979 alc260_models,
6980 alc260_cfg_tbl);
6981 if (board_config < 0) {
9a11f1aa 6982 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 6983 codec->chip_name);
df694daa 6984 board_config = ALC260_AUTO;
16ded525 6985 }
1da177e4 6986
df694daa
KY
6987 if (board_config == ALC260_AUTO) {
6988 /* automatic parse from the BIOS config */
6989 err = alc260_parse_auto_config(codec);
6990 if (err < 0) {
6991 alc_free(codec);
6992 return err;
f12ab1e0 6993 } else if (!err) {
9c7f852e
TI
6994 printk(KERN_INFO
6995 "hda_codec: Cannot set up configuration "
6996 "from BIOS. Using base mode...\n");
df694daa
KY
6997 board_config = ALC260_BASIC;
6998 }
a9430dd8 6999 }
e9edcee0 7000
680cd536
KK
7001 err = snd_hda_attach_beep_device(codec, 0x1);
7002 if (err < 0) {
7003 alc_free(codec);
7004 return err;
7005 }
7006
df694daa 7007 if (board_config != ALC260_AUTO)
e9c364c0 7008 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7009
1da177e4
LT
7010 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7011 spec->stream_analog_capture = &alc260_pcm_analog_capture;
7012
a3bcba38
TI
7013 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7014 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7015
4ef0ef19
TI
7016 if (!spec->adc_nids && spec->input_mux) {
7017 /* check whether NID 0x04 is valid */
7018 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7019 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7020 /* get type */
7021 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7022 spec->adc_nids = alc260_adc_nids_alt;
7023 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7024 } else {
7025 spec->adc_nids = alc260_adc_nids;
7026 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7027 }
7028 }
b59bdf3b 7029 set_capture_mixer(codec);
45bdd1c1 7030 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7031
2134ea4f
TI
7032 spec->vmaster_nid = 0x08;
7033
1da177e4 7034 codec->patch_ops = alc_patch_ops;
df694daa 7035 if (board_config == ALC260_AUTO)
ae6b813a 7036 spec->init_hook = alc260_auto_init;
cb53c626
TI
7037#ifdef CONFIG_SND_HDA_POWER_SAVE
7038 if (!spec->loopback.amplist)
7039 spec->loopback.amplist = alc260_loopbacks;
7040#endif
1da177e4
LT
7041
7042 return 0;
7043}
7044
e9edcee0 7045
1da177e4 7046/*
4953550a 7047 * ALC882/883/885/888/889 support
1da177e4
LT
7048 *
7049 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7050 * configuration. Each pin widget can choose any input DACs and a mixer.
7051 * Each ADC is connected from a mixer of all inputs. This makes possible
7052 * 6-channel independent captures.
7053 *
7054 * In addition, an independent DAC for the multi-playback (not used in this
7055 * driver yet).
7056 */
df694daa
KY
7057#define ALC882_DIGOUT_NID 0x06
7058#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7059#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7060#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7061#define ALC1200_DIGOUT_NID 0x10
7062
1da177e4 7063
d2a6d7dc 7064static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7065 { 8, NULL }
7066};
7067
4953550a 7068/* DACs */
1da177e4
LT
7069static hda_nid_t alc882_dac_nids[4] = {
7070 /* front, rear, clfe, rear_surr */
7071 0x02, 0x03, 0x04, 0x05
7072};
4953550a 7073#define alc883_dac_nids alc882_dac_nids
1da177e4 7074
4953550a 7075/* ADCs */
df694daa
KY
7076#define alc882_adc_nids alc880_adc_nids
7077#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
7078#define alc883_adc_nids alc882_adc_nids_alt
7079static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7080static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7081#define alc889_adc_nids alc880_adc_nids
1da177e4 7082
e1406348
TI
7083static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7084static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
7085#define alc883_capsrc_nids alc882_capsrc_nids_alt
7086static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7087#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7088
1da177e4
LT
7089/* input MUX */
7090/* FIXME: should be a matrix-type input source selection */
7091
7092static struct hda_input_mux alc882_capture_source = {
7093 .num_items = 4,
7094 .items = {
7095 { "Mic", 0x0 },
7096 { "Front Mic", 0x1 },
7097 { "Line", 0x2 },
7098 { "CD", 0x4 },
7099 },
7100};
41d5545d 7101
4953550a
TI
7102#define alc883_capture_source alc882_capture_source
7103
87a8c370
JK
7104static struct hda_input_mux alc889_capture_source = {
7105 .num_items = 3,
7106 .items = {
7107 { "Front Mic", 0x0 },
7108 { "Mic", 0x3 },
7109 { "Line", 0x2 },
7110 },
7111};
7112
41d5545d
KS
7113static struct hda_input_mux mb5_capture_source = {
7114 .num_items = 3,
7115 .items = {
7116 { "Mic", 0x1 },
b8f171e7 7117 { "Line", 0x7 },
41d5545d
KS
7118 { "CD", 0x4 },
7119 },
7120};
7121
e458b1fa
LY
7122static struct hda_input_mux macmini3_capture_source = {
7123 .num_items = 2,
7124 .items = {
7125 { "Line", 0x2 },
7126 { "CD", 0x4 },
7127 },
7128};
7129
4953550a
TI
7130static struct hda_input_mux alc883_3stack_6ch_intel = {
7131 .num_items = 4,
7132 .items = {
7133 { "Mic", 0x1 },
7134 { "Front Mic", 0x0 },
7135 { "Line", 0x2 },
7136 { "CD", 0x4 },
7137 },
7138};
7139
7140static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7141 .num_items = 2,
7142 .items = {
7143 { "Mic", 0x1 },
7144 { "Line", 0x2 },
7145 },
7146};
7147
7148static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7149 .num_items = 4,
7150 .items = {
7151 { "Mic", 0x0 },
150b432f 7152 { "Int Mic", 0x1 },
4953550a
TI
7153 { "Line", 0x2 },
7154 { "CD", 0x4 },
7155 },
7156};
7157
7158static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7159 .num_items = 2,
7160 .items = {
7161 { "Mic", 0x0 },
7162 { "Int Mic", 0x1 },
7163 },
7164};
7165
7166static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7167 .num_items = 3,
7168 .items = {
7169 { "Mic", 0x0 },
7170 { "Front Mic", 0x1 },
7171 { "Line", 0x4 },
7172 },
7173};
7174
7175static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7176 .num_items = 2,
7177 .items = {
7178 { "Mic", 0x0 },
7179 { "Line", 0x2 },
7180 },
7181};
7182
7183static struct hda_input_mux alc889A_mb31_capture_source = {
7184 .num_items = 2,
7185 .items = {
7186 { "Mic", 0x0 },
7187 /* Front Mic (0x01) unused */
7188 { "Line", 0x2 },
7189 /* Line 2 (0x03) unused */
af901ca1 7190 /* CD (0x04) unused? */
4953550a
TI
7191 },
7192};
7193
b7cccc52
JM
7194static struct hda_input_mux alc889A_imac91_capture_source = {
7195 .num_items = 2,
7196 .items = {
7197 { "Mic", 0x01 },
7198 { "Line", 0x2 }, /* Not sure! */
7199 },
7200};
7201
4953550a
TI
7202/*
7203 * 2ch mode
7204 */
7205static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7206 { 2, NULL }
7207};
7208
272a527c
KY
7209/*
7210 * 2ch mode
7211 */
7212static struct hda_verb alc882_3ST_ch2_init[] = {
7213 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7214 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7215 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7216 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7217 { } /* end */
7218};
7219
4953550a
TI
7220/*
7221 * 4ch mode
7222 */
7223static struct hda_verb alc882_3ST_ch4_init[] = {
7224 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7225 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7226 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7227 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7228 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7229 { } /* end */
7230};
7231
272a527c
KY
7232/*
7233 * 6ch mode
7234 */
7235static struct hda_verb alc882_3ST_ch6_init[] = {
7236 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7237 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7238 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7239 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7240 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7241 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7242 { } /* end */
7243};
7244
4953550a 7245static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7246 { 2, alc882_3ST_ch2_init },
4953550a 7247 { 4, alc882_3ST_ch4_init },
272a527c
KY
7248 { 6, alc882_3ST_ch6_init },
7249};
7250
4953550a
TI
7251#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7252
a65cc60f 7253/*
7254 * 2ch mode
7255 */
7256static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7257 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7258 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7259 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7260 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7261 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7262 { } /* end */
7263};
7264
7265/*
7266 * 4ch mode
7267 */
7268static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7269 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7270 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7271 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7272 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7273 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7274 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7275 { } /* end */
7276};
7277
7278/*
7279 * 6ch mode
7280 */
7281static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7282 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7283 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7284 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7285 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7286 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7287 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7288 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7289 { } /* end */
7290};
7291
7292static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7293 { 2, alc883_3ST_ch2_clevo_init },
7294 { 4, alc883_3ST_ch4_clevo_init },
7295 { 6, alc883_3ST_ch6_clevo_init },
7296};
7297
7298
df694daa
KY
7299/*
7300 * 6ch mode
7301 */
7302static struct hda_verb alc882_sixstack_ch6_init[] = {
7303 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7304 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7305 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7306 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7307 { } /* end */
7308};
7309
7310/*
7311 * 8ch mode
7312 */
7313static struct hda_verb alc882_sixstack_ch8_init[] = {
7314 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7315 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7316 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7317 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7318 { } /* end */
7319};
7320
7321static struct hda_channel_mode alc882_sixstack_modes[2] = {
7322 { 6, alc882_sixstack_ch6_init },
7323 { 8, alc882_sixstack_ch8_init },
7324};
7325
76e6f5a9
RH
7326
7327/* Macbook Air 2,1 */
7328
7329static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7330 { 2, NULL },
7331};
7332
87350ad0 7333/*
def319f9 7334 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7335 */
7336
7337/*
7338 * 2ch mode
7339 */
7340static struct hda_verb alc885_mbp_ch2_init[] = {
7341 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7342 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7343 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7344 { } /* end */
7345};
7346
7347/*
a3f730af 7348 * 4ch mode
87350ad0 7349 */
a3f730af 7350static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7351 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7352 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7353 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7354 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7355 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7356 { } /* end */
7357};
7358
a3f730af 7359static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7360 { 2, alc885_mbp_ch2_init },
a3f730af 7361 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7362};
7363
92b9de83
KS
7364/*
7365 * 2ch
7366 * Speakers/Woofer/HP = Front
7367 * LineIn = Input
7368 */
7369static struct hda_verb alc885_mb5_ch2_init[] = {
7370 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7371 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7372 { } /* end */
7373};
7374
7375/*
7376 * 6ch mode
7377 * Speakers/HP = Front
7378 * Woofer = LFE
7379 * LineIn = Surround
7380 */
7381static struct hda_verb alc885_mb5_ch6_init[] = {
7382 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7383 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7384 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7385 { } /* end */
7386};
7387
7388static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7389 { 2, alc885_mb5_ch2_init },
7390 { 6, alc885_mb5_ch6_init },
7391};
87350ad0 7392
d01aecdf 7393#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7394
7395/*
7396 * 2ch mode
7397 */
7398static struct hda_verb alc883_4ST_ch2_init[] = {
7399 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7400 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7401 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7402 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7403 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7404 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7405 { } /* end */
7406};
7407
7408/*
7409 * 4ch mode
7410 */
7411static struct hda_verb alc883_4ST_ch4_init[] = {
7412 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7413 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7414 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7415 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7416 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7417 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7418 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7419 { } /* end */
7420};
7421
7422/*
7423 * 6ch mode
7424 */
7425static struct hda_verb alc883_4ST_ch6_init[] = {
7426 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7427 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7428 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7429 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7430 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7431 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7432 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7433 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7434 { } /* end */
7435};
7436
7437/*
7438 * 8ch mode
7439 */
7440static struct hda_verb alc883_4ST_ch8_init[] = {
7441 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7442 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7443 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7444 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7445 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7446 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7447 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7448 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7449 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7450 { } /* end */
7451};
7452
7453static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7454 { 2, alc883_4ST_ch2_init },
7455 { 4, alc883_4ST_ch4_init },
7456 { 6, alc883_4ST_ch6_init },
7457 { 8, alc883_4ST_ch8_init },
7458};
7459
7460
7461/*
7462 * 2ch mode
7463 */
7464static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7465 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7466 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7467 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7468 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7469 { } /* end */
7470};
7471
7472/*
7473 * 4ch mode
7474 */
7475static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7476 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7477 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7478 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7479 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7480 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7481 { } /* end */
7482};
7483
7484/*
7485 * 6ch mode
7486 */
7487static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7488 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7489 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7490 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7491 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7492 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7493 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7494 { } /* end */
7495};
7496
7497static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7498 { 2, alc883_3ST_ch2_intel_init },
7499 { 4, alc883_3ST_ch4_intel_init },
7500 { 6, alc883_3ST_ch6_intel_init },
7501};
7502
dd7714c9
WF
7503/*
7504 * 2ch mode
7505 */
7506static struct hda_verb alc889_ch2_intel_init[] = {
7507 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7508 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7509 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7510 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7511 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7512 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7513 { } /* end */
7514};
7515
87a8c370
JK
7516/*
7517 * 6ch mode
7518 */
7519static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7520 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7521 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7522 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7523 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7524 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7525 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7526 { } /* end */
7527};
7528
7529/*
7530 * 8ch mode
7531 */
7532static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7533 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7534 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7535 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7536 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7537 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7538 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7539 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7540 { } /* end */
7541};
7542
dd7714c9
WF
7543static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7544 { 2, alc889_ch2_intel_init },
87a8c370
JK
7545 { 6, alc889_ch6_intel_init },
7546 { 8, alc889_ch8_intel_init },
7547};
7548
4953550a
TI
7549/*
7550 * 6ch mode
7551 */
7552static struct hda_verb alc883_sixstack_ch6_init[] = {
7553 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7554 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7555 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7556 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7557 { } /* end */
7558};
7559
7560/*
7561 * 8ch mode
7562 */
7563static struct hda_verb alc883_sixstack_ch8_init[] = {
7564 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7565 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7566 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7567 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7568 { } /* end */
7569};
7570
7571static struct hda_channel_mode alc883_sixstack_modes[2] = {
7572 { 6, alc883_sixstack_ch6_init },
7573 { 8, alc883_sixstack_ch8_init },
7574};
7575
7576
1da177e4
LT
7577/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7578 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7579 */
c8b6bf9b 7580static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7581 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7582 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7583 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7584 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7585 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7586 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7587 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7588 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7589 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7590 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7591 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7592 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7593 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7594 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7595 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7596 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7597 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
7598 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7599 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7600 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4 7601 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7602 { } /* end */
7603};
7604
76e6f5a9
RH
7605/* Macbook Air 2,1 same control for HP and internal Speaker */
7606
7607static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7608 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7609 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7610 { }
7611};
7612
7613
87350ad0 7614static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7615 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7616 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7617 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7618 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7619 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7620 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7621 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7622 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7623 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 7624 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
7625 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7626 { } /* end */
7627};
41d5545d
KS
7628
7629static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
7630 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7631 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7632 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7633 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7634 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7635 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
7636 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7637 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
7638 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7639 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
7640 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7641 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7642 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7643 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7644 { } /* end */
7645};
92b9de83 7646
e458b1fa
LY
7647static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7648 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7649 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7650 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7651 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7652 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7653 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7654 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7655 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7656 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7657 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7658 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7659 { } /* end */
7660};
7661
4b7e1803 7662static struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
7663 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7664 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
7665 { } /* end */
7666};
7667
7668
bdd148a3
KY
7669static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7670 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7671 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7672 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7673 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7674 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7675 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7676 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7677 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7678 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
7679 { } /* end */
7680};
7681
272a527c
KY
7682static struct snd_kcontrol_new alc882_targa_mixer[] = {
7683 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7684 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7685 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7686 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7687 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7688 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7689 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7690 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7691 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7692 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7693 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7694 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 7695 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
7696 { } /* end */
7697};
7698
7699/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7700 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7701 */
7702static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7703 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7704 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7705 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7706 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7707 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7708 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7709 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7710 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7711 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7712 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7713 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7714 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7715 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7716 { } /* end */
7717};
7718
914759b7
TI
7719static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7720 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7721 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7722 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7723 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7724 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7725 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7726 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7727 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7728 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7729 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
7730 { } /* end */
7731};
7732
df694daa
KY
7733static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7734 {
7735 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7736 .name = "Channel Mode",
7737 .info = alc_ch_mode_info,
7738 .get = alc_ch_mode_get,
7739 .put = alc_ch_mode_put,
7740 },
7741 { } /* end */
7742};
7743
4953550a 7744static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 7745 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
7746 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7747 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7748 /* Rear mixer */
05acb863
TI
7749 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7750 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7751 /* CLFE mixer */
05acb863
TI
7752 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7753 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7754 /* Side mixer */
05acb863
TI
7755 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7756 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7757
e9edcee0 7758 /* Front Pin: output 0 (0x0c) */
05acb863 7759 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7760 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7761 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 7762 /* Rear Pin: output 1 (0x0d) */
05acb863 7763 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7764 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7765 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 7766 /* CLFE Pin: output 2 (0x0e) */
05acb863 7767 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7768 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7769 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 7770 /* Side Pin: output 3 (0x0f) */
05acb863 7771 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7772 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7773 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 7774 /* Mic (rear) pin: input vref at 80% */
16ded525 7775 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7776 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7777 /* Front Mic pin: input vref at 80% */
16ded525 7778 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7779 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7780 /* Line In pin: input */
05acb863 7781 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
7782 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7783 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7784 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7785 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7786 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 7787 /* CD pin widget for input */
05acb863 7788 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
7789
7790 /* FIXME: use matrix-type input source selection */
7791 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 7792 /* Input mixer2 */
05acb863 7793 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 7794 /* Input mixer3 */
05acb863 7795 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
7796 /* ADC2: mute amp left and right */
7797 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7798 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
7799 /* ADC3: mute amp left and right */
7800 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7801 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
7802
7803 { }
7804};
7805
4953550a
TI
7806static struct hda_verb alc882_adc1_init_verbs[] = {
7807 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7808 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7809 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7810 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7811 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7812 /* ADC1: mute amp left and right */
7813 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7814 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7815 { }
7816};
7817
4b146cb0
TI
7818static struct hda_verb alc882_eapd_verbs[] = {
7819 /* change to EAPD mode */
7820 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 7821 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 7822 { }
4b146cb0
TI
7823};
7824
87a8c370
JK
7825static struct hda_verb alc889_eapd_verbs[] = {
7826 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7827 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7828 { }
7829};
7830
6732bd0d
WF
7831static struct hda_verb alc_hp15_unsol_verbs[] = {
7832 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7833 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7834 {}
7835};
87a8c370
JK
7836
7837static struct hda_verb alc885_init_verbs[] = {
7838 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
7839 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7840 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7841 /* Rear mixer */
88102f3f
KY
7842 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7843 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7844 /* CLFE mixer */
88102f3f
KY
7845 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7846 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7847 /* Side mixer */
88102f3f
KY
7848 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7849 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
7850
7851 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 7852 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
7853 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7854 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7855 /* Front Pin: output 0 (0x0c) */
7856 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7857 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7858 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7859 /* Rear Pin: output 1 (0x0d) */
7860 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7861 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7862 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
7863 /* CLFE Pin: output 2 (0x0e) */
7864 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7865 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7866 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7867 /* Side Pin: output 3 (0x0f) */
7868 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7869 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7870 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7871 /* Mic (rear) pin: input vref at 80% */
7872 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7873 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7874 /* Front Mic pin: input vref at 80% */
7875 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7876 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7877 /* Line In pin: input */
7878 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7879 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7880
7881 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7882 /* Input mixer1 */
88102f3f 7883 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
7884 /* Input mixer2 */
7885 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 7886 /* Input mixer3 */
88102f3f 7887 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
7888 /* ADC2: mute amp left and right */
7889 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7890 /* ADC3: mute amp left and right */
7891 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7892
7893 { }
7894};
7895
7896static struct hda_verb alc885_init_input_verbs[] = {
7897 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7898 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7899 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7900 { }
7901};
7902
7903
7904/* Unmute Selector 24h and set the default input to front mic */
7905static struct hda_verb alc889_init_input_verbs[] = {
7906 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7907 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7908 { }
7909};
7910
7911
4953550a
TI
7912#define alc883_init_verbs alc882_base_init_verbs
7913
9102cd1c
TD
7914/* Mac Pro test */
7915static struct snd_kcontrol_new alc882_macpro_mixer[] = {
7916 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7917 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7918 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
7919 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7920 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 7921 /* FIXME: this looks suspicious...
d355c82a
JK
7922 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
7923 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 7924 */
9102cd1c
TD
7925 { } /* end */
7926};
7927
7928static struct hda_verb alc882_macpro_init_verbs[] = {
7929 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7930 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7931 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7932 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7933 /* Front Pin: output 0 (0x0c) */
7934 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7935 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7936 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7937 /* Front Mic pin: input vref at 80% */
7938 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7939 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7940 /* Speaker: output */
7941 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7942 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7943 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
7944 /* Headphone output (output 0 - 0x0c) */
7945 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7946 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7947 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7948
7949 /* FIXME: use matrix-type input source selection */
7950 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7951 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7952 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7953 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7954 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7955 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7956 /* Input mixer2 */
7957 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7958 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7959 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7960 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7961 /* Input mixer3 */
7962 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7963 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7964 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7965 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7966 /* ADC1: mute amp left and right */
7967 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7968 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7969 /* ADC2: mute amp left and right */
7970 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7971 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7972 /* ADC3: mute amp left and right */
7973 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7974 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7975
7976 { }
7977};
f12ab1e0 7978
41d5545d
KS
7979/* Macbook 5,1 */
7980static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
7981 /* DACs */
7982 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7983 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7984 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7985 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 7986 /* Front mixer */
41d5545d
KS
7987 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7988 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7989 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
7990 /* Surround mixer */
7991 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7992 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7993 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7994 /* LFE mixer */
7995 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7996 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7997 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7998 /* HP mixer */
7999 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8000 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8001 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8002 /* Front Pin (0x0c) */
41d5545d
KS
8003 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8004 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8005 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8006 /* LFE Pin (0x0e) */
8007 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8008 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8009 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8010 /* HP Pin (0x0f) */
41d5545d
KS
8011 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8012 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8013 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8014 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8015 /* Front Mic pin: input vref at 80% */
8016 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8017 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8018 /* Line In pin */
8019 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8020 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8021
b8f171e7
AM
8022 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8023 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8024 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8025 { }
8026};
8027
e458b1fa
LY
8028/* Macmini 3,1 */
8029static struct hda_verb alc885_macmini3_init_verbs[] = {
8030 /* DACs */
8031 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8032 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8033 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8034 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8035 /* Front mixer */
8036 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8037 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8038 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8039 /* Surround mixer */
8040 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8041 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8042 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8043 /* LFE mixer */
8044 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8045 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8046 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8047 /* HP mixer */
8048 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8049 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8050 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8051 /* Front Pin (0x0c) */
8052 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8053 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8054 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8055 /* LFE Pin (0x0e) */
8056 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8057 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8058 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8059 /* HP Pin (0x0f) */
8060 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8061 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8062 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8063 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8064 /* Line In pin */
8065 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8066 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8067
8068 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8069 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8070 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8071 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8072 { }
8073};
8074
76e6f5a9
RH
8075
8076static struct hda_verb alc885_mba21_init_verbs[] = {
8077 /*Internal and HP Speaker Mixer*/
8078 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8079 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8080 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8081 /*Internal Speaker Pin (0x0c)*/
8082 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8083 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8084 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8085 /* HP Pin: output 0 (0x0e) */
8086 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8087 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8088 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8089 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8090 /* Line in (is hp when jack connected)*/
8091 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8092 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8093
8094 { }
8095 };
8096
8097
87350ad0
TI
8098/* Macbook Pro rev3 */
8099static struct hda_verb alc885_mbp3_init_verbs[] = {
8100 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8101 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8102 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8103 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8104 /* Rear mixer */
8105 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8106 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8107 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8108 /* HP mixer */
8109 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8110 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8111 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8112 /* Front Pin: output 0 (0x0c) */
8113 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8114 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8115 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8116 /* HP Pin: output 0 (0x0e) */
87350ad0 8117 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8118 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8119 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8120 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8121 /* Mic (rear) pin: input vref at 80% */
8122 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8123 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8124 /* Front Mic pin: input vref at 80% */
8125 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8126 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8127 /* Line In pin: use output 1 when in LineOut mode */
8128 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8129 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8130 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8131
8132 /* FIXME: use matrix-type input source selection */
8133 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8134 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8135 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8136 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8137 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8138 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8139 /* Input mixer2 */
8140 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8141 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8142 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8143 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8144 /* Input mixer3 */
8145 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8146 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8147 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8148 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8149 /* ADC1: mute amp left and right */
8150 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8151 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8152 /* ADC2: mute amp left and right */
8153 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8154 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8155 /* ADC3: mute amp left and right */
8156 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8157 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8158
8159 { }
8160};
8161
4b7e1803
JM
8162/* iMac 9,1 */
8163static struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8164 /* Internal Speaker Pin (0x0c) */
8165 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8166 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8167 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8168 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8169 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8170 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8171 /* HP Pin: Rear */
4b7e1803
JM
8172 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8173 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8174 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8175 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8176 /* Line in Rear */
8177 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8178 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8179 /* Front Mic pin: input vref at 80% */
8180 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8181 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8182 /* Rear mixer */
8183 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8184 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8185 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8186 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8187 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8188 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8189 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8190 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8191 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8192 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8193 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8194 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8195 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8196 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8197 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8198 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8199 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8200 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8201 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8202 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8203 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8204 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8205 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8206 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8207 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8208 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8209 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8210 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8211 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8212 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8213 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8214 { }
8215};
8216
c54728d8
NF
8217/* iMac 24 mixer. */
8218static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8219 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8220 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8221 { } /* end */
8222};
8223
8224/* iMac 24 init verbs. */
8225static struct hda_verb alc885_imac24_init_verbs[] = {
8226 /* Internal speakers: output 0 (0x0c) */
8227 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8228 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8229 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8230 /* Internal speakers: output 0 (0x0c) */
8231 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8232 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8233 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8234 /* Headphone: output 0 (0x0c) */
8235 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8236 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8237 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8238 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8239 /* Front Mic: input vref at 80% */
8240 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8241 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8242 { }
8243};
8244
8245/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8246static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8247{
a9fd4f3f 8248 struct alc_spec *spec = codec->spec;
c54728d8 8249
a9fd4f3f
TI
8250 spec->autocfg.hp_pins[0] = 0x14;
8251 spec->autocfg.speaker_pins[0] = 0x18;
8252 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8253}
8254
9d54f08b
TI
8255#define alc885_mb5_setup alc885_imac24_setup
8256#define alc885_macmini3_setup alc885_imac24_setup
8257
76e6f5a9
RH
8258/* Macbook Air 2,1 */
8259static void alc885_mba21_setup(struct hda_codec *codec)
8260{
8261 struct alc_spec *spec = codec->spec;
8262
8263 spec->autocfg.hp_pins[0] = 0x14;
8264 spec->autocfg.speaker_pins[0] = 0x18;
8265}
8266
8267
8268
4f5d1706 8269static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8270{
a9fd4f3f 8271 struct alc_spec *spec = codec->spec;
87350ad0 8272
a9fd4f3f
TI
8273 spec->autocfg.hp_pins[0] = 0x15;
8274 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8275}
8276
9d54f08b 8277static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8278{
9d54f08b 8279 struct alc_spec *spec = codec->spec;
4b7e1803 8280
9d54f08b 8281 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8282 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8283 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8284}
87350ad0 8285
272a527c
KY
8286static struct hda_verb alc882_targa_verbs[] = {
8287 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8288 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8289
8290 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8291 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8292
272a527c
KY
8293 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8294 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8295 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8296
8297 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8298 { } /* end */
8299};
8300
8301/* toggle speaker-output according to the hp-jack state */
8302static void alc882_targa_automute(struct hda_codec *codec)
8303{
a9fd4f3f
TI
8304 struct alc_spec *spec = codec->spec;
8305 alc_automute_amp(codec);
82beb8fd 8306 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8307 spec->jack_present ? 1 : 3);
8308}
8309
4f5d1706 8310static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8311{
8312 struct alc_spec *spec = codec->spec;
8313
8314 spec->autocfg.hp_pins[0] = 0x14;
8315 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8316}
8317
8318static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8319{
a9fd4f3f 8320 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8321 alc882_targa_automute(codec);
272a527c
KY
8322}
8323
8324static struct hda_verb alc882_asus_a7j_verbs[] = {
8325 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8326 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8327
8328 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8329 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8330 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8331
272a527c
KY
8332 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8333 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8334 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8335
8336 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8337 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8338 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8339 { } /* end */
8340};
8341
914759b7
TI
8342static struct hda_verb alc882_asus_a7m_verbs[] = {
8343 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8344 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8345
8346 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8347 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8348 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8349
914759b7
TI
8350 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8351 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8352 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8353
8354 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8355 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8356 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8357 { } /* end */
8358};
8359
9102cd1c
TD
8360static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8361{
8362 unsigned int gpiostate, gpiomask, gpiodir;
8363
8364 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8365 AC_VERB_GET_GPIO_DATA, 0);
8366
8367 if (!muted)
8368 gpiostate |= (1 << pin);
8369 else
8370 gpiostate &= ~(1 << pin);
8371
8372 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8373 AC_VERB_GET_GPIO_MASK, 0);
8374 gpiomask |= (1 << pin);
8375
8376 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8377 AC_VERB_GET_GPIO_DIRECTION, 0);
8378 gpiodir |= (1 << pin);
8379
8380
8381 snd_hda_codec_write(codec, codec->afg, 0,
8382 AC_VERB_SET_GPIO_MASK, gpiomask);
8383 snd_hda_codec_write(codec, codec->afg, 0,
8384 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8385
8386 msleep(1);
8387
8388 snd_hda_codec_write(codec, codec->afg, 0,
8389 AC_VERB_SET_GPIO_DATA, gpiostate);
8390}
8391
7debbe51
TI
8392/* set up GPIO at initialization */
8393static void alc885_macpro_init_hook(struct hda_codec *codec)
8394{
8395 alc882_gpio_mute(codec, 0, 0);
8396 alc882_gpio_mute(codec, 1, 0);
8397}
8398
8399/* set up GPIO and update auto-muting at initialization */
8400static void alc885_imac24_init_hook(struct hda_codec *codec)
8401{
8402 alc885_macpro_init_hook(codec);
4f5d1706 8403 alc_automute_amp(codec);
7debbe51
TI
8404}
8405
df694daa
KY
8406/*
8407 * generic initialization of ADC, input mixers and output mixers
8408 */
4953550a 8409static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8410 /*
8411 * Unmute ADC0-2 and set the default input to mic-in
8412 */
4953550a
TI
8413 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8414 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8415 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8416 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8417
4953550a
TI
8418 /*
8419 * Set up output mixers (0x0c - 0x0f)
8420 */
8421 /* set vol=0 to output mixers */
8422 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8423 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8424 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8425 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8426 /* set up input amps for analog loopback */
8427 /* Amp Indices: DAC = 0, mixer = 1 */
8428 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8429 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8430 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8431 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8432 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8433 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8434 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8435 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8436 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8437 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8438
4953550a
TI
8439 /* FIXME: use matrix-type input source selection */
8440 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8441 /* Input mixer2 */
88102f3f 8442 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8443 /* Input mixer3 */
88102f3f 8444 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8445 { }
9c7f852e
TI
8446};
8447
eb4c41d3
TS
8448/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8449static struct hda_verb alc889A_mb31_ch2_init[] = {
8450 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8451 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8452 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8453 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8454 { } /* end */
8455};
8456
8457/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8458static struct hda_verb alc889A_mb31_ch4_init[] = {
8459 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8460 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8461 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8462 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8463 { } /* end */
8464};
8465
8466/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8467static struct hda_verb alc889A_mb31_ch5_init[] = {
8468 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8469 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8470 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8471 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8472 { } /* end */
8473};
8474
8475/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8476static struct hda_verb alc889A_mb31_ch6_init[] = {
8477 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8478 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8479 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8480 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8481 { } /* end */
8482};
8483
8484static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8485 { 2, alc889A_mb31_ch2_init },
8486 { 4, alc889A_mb31_ch4_init },
8487 { 5, alc889A_mb31_ch5_init },
8488 { 6, alc889A_mb31_ch6_init },
8489};
8490
b373bdeb
AN
8491static struct hda_verb alc883_medion_eapd_verbs[] = {
8492 /* eanable EAPD on medion laptop */
8493 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8494 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8495 { }
8496};
8497
4953550a 8498#define alc883_base_mixer alc882_base_mixer
834be88d 8499
a8848bd6
AS
8500static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8501 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8502 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8503 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8504 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8505 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8506 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8507 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8508 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8509 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8510 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8511 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8512 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8513 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8514 { } /* end */
8515};
8516
0c4cc443 8517static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8518 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8519 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8520 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8521 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8522 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8523 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8524 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8525 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8526 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8527 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8528 { } /* end */
8529};
8530
fb97dc67
J
8531static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8532 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8533 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8534 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8535 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8536 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8537 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8538 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8539 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8540 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8541 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8542 { } /* end */
8543};
8544
9c7f852e
TI
8545static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8546 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8547 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8548 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8549 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8550 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8551 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8552 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8553 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8554 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8555 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8556 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8557 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8558 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8559 { } /* end */
8560};
df694daa 8561
9c7f852e
TI
8562static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8563 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8564 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8565 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8566 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8567 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8568 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8569 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8570 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8571 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8572 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8573 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8574 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8575 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8576 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8577 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8578 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8579 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8580 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8581 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8582 { } /* end */
8583};
8584
17bba1b7
J
8585static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8586 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8587 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8588 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8589 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8590 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8591 HDA_OUTPUT),
8592 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8593 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8594 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8595 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8596 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8597 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8598 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8599 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8600 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8601 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8602 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8603 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8604 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8605 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8606 { } /* end */
8607};
8608
87a8c370
JK
8609static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8610 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8611 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8612 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8613 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8614 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8615 HDA_OUTPUT),
8616 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8617 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8618 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8619 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8620 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8621 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8622 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8623 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8624 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8625 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
8626 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8627 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8628 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8629 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8630 { } /* end */
8631};
8632
d1d985f0 8633static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8634 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8635 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8636 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8637 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8638 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8639 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8640 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8641 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8642 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8643 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8644 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8645 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8646 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8647 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8648 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
8649 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8650 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8651 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8 8652 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
8653 { } /* end */
8654};
8655
c259249f 8656static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 8657 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8658 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8659 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8660 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8661 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8662 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8663 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8664 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8665 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8666 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8667 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8668 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8669 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8670 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8671 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8672 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8673 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 8674 { } /* end */
f12ab1e0 8675};
ccc656ce 8676
c259249f 8677static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 8678 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8679 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8680 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8681 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8682 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8683 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8684 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8685 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8686 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
8687 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8688 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8689 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 8690 { } /* end */
f12ab1e0 8691};
ccc656ce 8692
b99dba34
TI
8693static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8694 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8695 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8696 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8697 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8698 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8699 { } /* end */
8700};
8701
bc9f98a9
KY
8702static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8703 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8704 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
8705 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8706 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
8707 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8708 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8709 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8710 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 8711 { } /* end */
f12ab1e0 8712};
bc9f98a9 8713
272a527c
KY
8714static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8715 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8716 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8717 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8718 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8719 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8720 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8721 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
150b432f
DH
8722 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8723 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
8724 { } /* end */
8725};
8726
8727static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8728 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8729 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8730 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8731 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8732 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8733 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8734 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8735 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8736 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
272a527c 8737 { } /* end */
ea1fb29a 8738};
272a527c 8739
7ad7b218
MC
8740static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
8741 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8742 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8743 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8744 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
8745 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
8746 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
8747 { } /* end */
8748};
8749
8750static struct hda_verb alc883_medion_wim2160_verbs[] = {
8751 /* Unmute front mixer */
8752 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8753 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8754
8755 /* Set speaker pin to front mixer */
8756 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8757
8758 /* Init headphone pin */
8759 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8760 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8761 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8762 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8763
8764 { } /* end */
8765};
8766
8767/* toggle speaker-output according to the hp-jack state */
8768static void alc883_medion_wim2160_setup(struct hda_codec *codec)
8769{
8770 struct alc_spec *spec = codec->spec;
8771
8772 spec->autocfg.hp_pins[0] = 0x1a;
8773 spec->autocfg.speaker_pins[0] = 0x15;
8774}
8775
2880a867 8776static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
8777 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8778 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 8779 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
8780 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8781 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
8782 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8783 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8784 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 8785 { } /* end */
d1a991a6 8786};
2880a867 8787
d2fd4b09
TV
8788static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8789 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 8790 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
8791 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8792 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
8793 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8794 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8795 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8796 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8797 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8798 { } /* end */
8799};
8800
e2757d5e
KY
8801static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8802 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8803 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8804 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8805 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8806 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8807 0x0d, 1, 0x0, HDA_OUTPUT),
8808 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8809 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8810 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8811 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8812 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
8813 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8814 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8815 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8816 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8817 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8818 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8819 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8820 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8821 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8822 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
8823 { } /* end */
8824};
8825
eb4c41d3
TS
8826static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8827 /* Output mixers */
8828 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8829 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8830 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8831 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8832 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8833 HDA_OUTPUT),
8834 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8835 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8836 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8837 /* Output switches */
8838 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8839 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8840 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8841 /* Boost mixers */
8842 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8843 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8844 /* Input mixers */
8845 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8846 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8847 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8848 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8849 { } /* end */
8850};
8851
3e1647c5
GG
8852static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8853 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8854 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8855 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8856 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8857 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8858 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8859 { } /* end */
8860};
8861
e2757d5e
KY
8862static struct hda_bind_ctls alc883_bind_cap_vol = {
8863 .ops = &snd_hda_bind_vol,
8864 .values = {
8865 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8866 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8867 0
8868 },
8869};
8870
8871static struct hda_bind_ctls alc883_bind_cap_switch = {
8872 .ops = &snd_hda_bind_sw,
8873 .values = {
8874 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8875 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8876 0
8877 },
8878};
8879
8880static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8881 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8882 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8883 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8884 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8885 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8886 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4953550a
TI
8887 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8888 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8889 { } /* end */
8890};
df694daa 8891
4953550a
TI
8892static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8893 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8894 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8895 {
8896 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8897 /* .name = "Capture Source", */
8898 .name = "Input Source",
8899 .count = 1,
8900 .info = alc_mux_enum_info,
8901 .get = alc_mux_enum_get,
8902 .put = alc_mux_enum_put,
8903 },
8904 { } /* end */
8905};
9c7f852e 8906
4953550a
TI
8907static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8908 {
8909 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8910 .name = "Channel Mode",
8911 .info = alc_ch_mode_info,
8912 .get = alc_ch_mode_get,
8913 .put = alc_ch_mode_put,
8914 },
8915 { } /* end */
9c7f852e
TI
8916};
8917
a8848bd6 8918/* toggle speaker-output according to the hp-jack state */
4f5d1706 8919static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 8920{
a9fd4f3f 8921 struct alc_spec *spec = codec->spec;
a8848bd6 8922
a9fd4f3f
TI
8923 spec->autocfg.hp_pins[0] = 0x15;
8924 spec->autocfg.speaker_pins[0] = 0x14;
8925 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
8926}
8927
8928/* auto-toggle front mic */
8929/*
8930static void alc883_mitac_mic_automute(struct hda_codec *codec)
8931{
864f92be 8932 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
a8848bd6 8933
a8848bd6
AS
8934 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8935}
8936*/
8937
a8848bd6
AS
8938static struct hda_verb alc883_mitac_verbs[] = {
8939 /* HP */
8940 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8941 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8942 /* Subwoofer */
8943 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8944 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8945
8946 /* enable unsolicited event */
8947 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8948 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8949
8950 { } /* end */
8951};
8952
a65cc60f 8953static struct hda_verb alc883_clevo_m540r_verbs[] = {
8954 /* HP */
8955 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8956 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8957 /* Int speaker */
8958 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
8959
8960 /* enable unsolicited event */
8961 /*
8962 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8963 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8964 */
8965
8966 { } /* end */
8967};
8968
0c4cc443 8969static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
8970 /* HP */
8971 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8972 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8973 /* Int speaker */
8974 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8975 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8976
8977 /* enable unsolicited event */
8978 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 8979 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
8980
8981 { } /* end */
8982};
8983
fb97dc67
J
8984static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8985 /* HP */
8986 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8987 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8988 /* Subwoofer */
8989 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8990 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8991
8992 /* enable unsolicited event */
8993 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8994
8995 { } /* end */
8996};
8997
c259249f 8998static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
8999 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9000 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9001
9002 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9003 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9004
64a8be74
DH
9005/* Connect Line-Out side jack (SPDIF) to Side */
9006 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9007 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9008 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9009/* Connect Mic jack to CLFE */
9010 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9011 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9012 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9013/* Connect Line-in jack to Surround */
9014 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9015 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9016 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9017/* Connect HP out jack to Front */
9018 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9019 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9020 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9021
9022 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9023
9024 { } /* end */
9025};
9026
bc9f98a9
KY
9027static struct hda_verb alc883_lenovo_101e_verbs[] = {
9028 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9029 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9030 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9031 { } /* end */
9032};
9033
272a527c
KY
9034static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9035 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9036 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9037 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9038 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9039 { } /* end */
9040};
9041
9042static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9043 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9044 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9045 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9046 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9047 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9048 { } /* end */
9049};
9050
189609ae
KY
9051static struct hda_verb alc883_haier_w66_verbs[] = {
9052 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9053 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9054
9055 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9056
9057 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9058 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9059 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9060 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9061 { } /* end */
9062};
9063
e2757d5e
KY
9064static struct hda_verb alc888_lenovo_sky_verbs[] = {
9065 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9066 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9067 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9068 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9069 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9070 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9071 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9072 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9073 { } /* end */
9074};
9075
8718b700
HRK
9076static struct hda_verb alc888_6st_dell_verbs[] = {
9077 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9078 { }
9079};
9080
3e1647c5
GG
9081static struct hda_verb alc883_vaiott_verbs[] = {
9082 /* HP */
9083 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9084 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9085
9086 /* enable unsolicited event */
9087 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9088
9089 { } /* end */
9090};
9091
4f5d1706 9092static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9093{
a9fd4f3f 9094 struct alc_spec *spec = codec->spec;
8718b700 9095
a9fd4f3f
TI
9096 spec->autocfg.hp_pins[0] = 0x1b;
9097 spec->autocfg.speaker_pins[0] = 0x14;
9098 spec->autocfg.speaker_pins[1] = 0x16;
9099 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
9100}
9101
4723c022 9102static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9103 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9104 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9105 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9106 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9107 { } /* end */
5795b9e6
CM
9108};
9109
3ea0d7cf
HRK
9110/*
9111 * 2ch mode
9112 */
4723c022 9113static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9114 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9115 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9116 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9117 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9118 { } /* end */
8341de60
CM
9119};
9120
3ea0d7cf
HRK
9121/*
9122 * 4ch mode
9123 */
9124static struct hda_verb alc888_3st_hp_4ch_init[] = {
9125 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9126 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9127 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9128 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9129 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9130 { } /* end */
9131};
9132
9133/*
9134 * 6ch mode
9135 */
4723c022 9136static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9137 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9138 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9139 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9140 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9141 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9142 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9143 { } /* end */
8341de60
CM
9144};
9145
3ea0d7cf 9146static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9147 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9148 { 4, alc888_3st_hp_4ch_init },
4723c022 9149 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9150};
9151
272a527c
KY
9152/* toggle front-jack and RCA according to the hp-jack state */
9153static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9154{
864f92be 9155 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 9156
47fd830a
TI
9157 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9158 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9159 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9160 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
9161}
9162
9163/* toggle RCA according to the front-jack state */
9164static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9165{
864f92be 9166 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 9167
47fd830a
TI
9168 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9169 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 9170}
47fd830a 9171
272a527c
KY
9172static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9173 unsigned int res)
9174{
9175 if ((res >> 26) == ALC880_HP_EVENT)
9176 alc888_lenovo_ms7195_front_automute(codec);
9177 if ((res >> 26) == ALC880_FRONT_EVENT)
9178 alc888_lenovo_ms7195_rca_automute(codec);
9179}
9180
9181static struct hda_verb alc883_medion_md2_verbs[] = {
9182 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9183 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9184
9185 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9186
9187 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9188 { } /* end */
9189};
9190
9191/* toggle speaker-output according to the hp-jack state */
4f5d1706 9192static void alc883_medion_md2_setup(struct hda_codec *codec)
272a527c 9193{
a9fd4f3f 9194 struct alc_spec *spec = codec->spec;
272a527c 9195
a9fd4f3f
TI
9196 spec->autocfg.hp_pins[0] = 0x14;
9197 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
9198}
9199
ccc656ce 9200/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9201#define alc883_targa_init_hook alc882_targa_init_hook
9202#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9203
0c4cc443
HRK
9204static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
9205{
9206 unsigned int present;
9207
d56757ab 9208 present = snd_hda_jack_detect(codec, 0x18);
0c4cc443
HRK
9209 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
9210 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9211}
9212
4f5d1706 9213static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9214{
a9fd4f3f
TI
9215 struct alc_spec *spec = codec->spec;
9216
9217 spec->autocfg.hp_pins[0] = 0x15;
9218 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
9219}
9220
9221static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9222{
a9fd4f3f 9223 alc_automute_amp(codec);
0c4cc443
HRK
9224 alc883_clevo_m720_mic_automute(codec);
9225}
9226
9227static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9228 unsigned int res)
9229{
0c4cc443 9230 switch (res >> 26) {
0c4cc443
HRK
9231 case ALC880_MIC_EVENT:
9232 alc883_clevo_m720_mic_automute(codec);
9233 break;
a9fd4f3f
TI
9234 default:
9235 alc_automute_amp_unsol_event(codec, res);
9236 break;
0c4cc443 9237 }
368c7a95
J
9238}
9239
fb97dc67 9240/* toggle speaker-output according to the hp-jack state */
4f5d1706 9241static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9242{
a9fd4f3f 9243 struct alc_spec *spec = codec->spec;
fb97dc67 9244
a9fd4f3f
TI
9245 spec->autocfg.hp_pins[0] = 0x14;
9246 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9247}
9248
4f5d1706 9249static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9250{
a9fd4f3f 9251 struct alc_spec *spec = codec->spec;
189609ae 9252
a9fd4f3f
TI
9253 spec->autocfg.hp_pins[0] = 0x1b;
9254 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9255}
9256
bc9f98a9
KY
9257static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9258{
864f92be 9259 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9260
47fd830a
TI
9261 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9262 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9263}
9264
9265static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9266{
864f92be 9267 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9268
47fd830a
TI
9269 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9270 HDA_AMP_MUTE, bits);
9271 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9272 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9273}
9274
9275static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9276 unsigned int res)
9277{
9278 if ((res >> 26) == ALC880_HP_EVENT)
9279 alc883_lenovo_101e_all_automute(codec);
9280 if ((res >> 26) == ALC880_FRONT_EVENT)
9281 alc883_lenovo_101e_ispeaker_automute(codec);
9282}
9283
676a9b53 9284/* toggle speaker-output according to the hp-jack state */
4f5d1706 9285static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9286{
a9fd4f3f 9287 struct alc_spec *spec = codec->spec;
676a9b53 9288
a9fd4f3f
TI
9289 spec->autocfg.hp_pins[0] = 0x14;
9290 spec->autocfg.speaker_pins[0] = 0x15;
9291 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9292}
9293
d1a991a6
KY
9294static struct hda_verb alc883_acer_eapd_verbs[] = {
9295 /* HP Pin: output 0 (0x0c) */
9296 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9297 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9298 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9299 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9300 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9301 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9302 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9303 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9304 /* eanable EAPD on medion laptop */
9305 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9306 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9307 /* enable unsolicited event */
9308 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9309 { }
9310};
9311
fc86f954
DK
9312static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
9313 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9314 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9315 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9316 { } /* end */
9317};
9318
4f5d1706 9319static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9320{
a9fd4f3f 9321 struct alc_spec *spec = codec->spec;
5795b9e6 9322
a9fd4f3f
TI
9323 spec->autocfg.hp_pins[0] = 0x1b;
9324 spec->autocfg.speaker_pins[0] = 0x14;
9325 spec->autocfg.speaker_pins[1] = 0x15;
9326 spec->autocfg.speaker_pins[2] = 0x16;
9327 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9328}
9329
4f5d1706 9330static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9331{
a9fd4f3f 9332 struct alc_spec *spec = codec->spec;
e2757d5e 9333
a9fd4f3f
TI
9334 spec->autocfg.hp_pins[0] = 0x1b;
9335 spec->autocfg.speaker_pins[0] = 0x14;
9336 spec->autocfg.speaker_pins[1] = 0x15;
9337 spec->autocfg.speaker_pins[2] = 0x16;
9338 spec->autocfg.speaker_pins[3] = 0x17;
9339 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9340}
9341
4f5d1706 9342static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9343{
9344 struct alc_spec *spec = codec->spec;
9345
9346 spec->autocfg.hp_pins[0] = 0x15;
9347 spec->autocfg.speaker_pins[0] = 0x14;
9348 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9349}
9350
e2757d5e
KY
9351static struct hda_verb alc888_asus_m90v_verbs[] = {
9352 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9353 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9354 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9355 /* enable unsolicited event */
9356 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9357 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9358 { } /* end */
9359};
9360
4f5d1706 9361static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9362{
a9fd4f3f 9363 struct alc_spec *spec = codec->spec;
e2757d5e 9364
a9fd4f3f
TI
9365 spec->autocfg.hp_pins[0] = 0x1b;
9366 spec->autocfg.speaker_pins[0] = 0x14;
9367 spec->autocfg.speaker_pins[1] = 0x15;
9368 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9369 spec->ext_mic.pin = 0x18;
9370 spec->int_mic.pin = 0x19;
9371 spec->ext_mic.mux_idx = 0;
9372 spec->int_mic.mux_idx = 1;
9373 spec->auto_mic = 1;
e2757d5e
KY
9374}
9375
9376static struct hda_verb alc888_asus_eee1601_verbs[] = {
9377 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9378 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9379 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9380 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9381 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9382 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9383 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9384 /* enable unsolicited event */
9385 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9386 { } /* end */
9387};
9388
e2757d5e
KY
9389static void alc883_eee1601_inithook(struct hda_codec *codec)
9390{
a9fd4f3f
TI
9391 struct alc_spec *spec = codec->spec;
9392
9393 spec->autocfg.hp_pins[0] = 0x14;
9394 spec->autocfg.speaker_pins[0] = 0x1b;
9395 alc_automute_pin(codec);
e2757d5e
KY
9396}
9397
eb4c41d3
TS
9398static struct hda_verb alc889A_mb31_verbs[] = {
9399 /* Init rear pin (used as headphone output) */
9400 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9401 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9402 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9403 /* Init line pin (used as output in 4ch and 6ch mode) */
9404 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9405 /* Init line 2 pin (used as headphone out by default) */
9406 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9407 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9408 { } /* end */
9409};
9410
9411/* Mute speakers according to the headphone jack state */
9412static void alc889A_mb31_automute(struct hda_codec *codec)
9413{
9414 unsigned int present;
9415
9416 /* Mute only in 2ch or 4ch mode */
9417 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9418 == 0x00) {
864f92be 9419 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9420 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9421 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9422 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9423 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9424 }
9425}
9426
9427static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9428{
9429 if ((res >> 26) == ALC880_HP_EVENT)
9430 alc889A_mb31_automute(codec);
9431}
9432
4953550a 9433
cb53c626 9434#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9435#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9436#endif
9437
def319f9 9438/* pcm configuration: identical with ALC880 */
4953550a
TI
9439#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9440#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9441#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9442#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9443
9444static hda_nid_t alc883_slave_dig_outs[] = {
9445 ALC1200_DIGOUT_NID, 0,
9446};
9447
9448static hda_nid_t alc1200_slave_dig_outs[] = {
9449 ALC883_DIGOUT_NID, 0,
9450};
9c7f852e
TI
9451
9452/*
9453 * configuration and preset
9454 */
4953550a
TI
9455static const char *alc882_models[ALC882_MODEL_LAST] = {
9456 [ALC882_3ST_DIG] = "3stack-dig",
9457 [ALC882_6ST_DIG] = "6stack-dig",
9458 [ALC882_ARIMA] = "arima",
9459 [ALC882_W2JC] = "w2jc",
9460 [ALC882_TARGA] = "targa",
9461 [ALC882_ASUS_A7J] = "asus-a7j",
9462 [ALC882_ASUS_A7M] = "asus-a7m",
9463 [ALC885_MACPRO] = "macpro",
9464 [ALC885_MB5] = "mb5",
e458b1fa 9465 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9466 [ALC885_MBA21] = "mba21",
4953550a
TI
9467 [ALC885_MBP3] = "mbp3",
9468 [ALC885_IMAC24] = "imac24",
4b7e1803 9469 [ALC885_IMAC91] = "imac91",
4953550a 9470 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9471 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9472 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9473 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9474 [ALC883_TARGA_DIG] = "targa-dig",
9475 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9476 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9477 [ALC883_ACER] = "acer",
2880a867 9478 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9479 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9480 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9481 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9482 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9483 [ALC883_MEDION] = "medion",
272a527c 9484 [ALC883_MEDION_MD2] = "medion-md2",
7ad7b218 9485 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9486 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9487 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9488 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9489 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9490 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9491 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9492 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9493 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9494 [ALC883_MITAC] = "mitac",
a65cc60f 9495 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9496 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9497 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9498 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9499 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9500 [ALC889A_INTEL] = "intel-alc889a",
9501 [ALC889_INTEL] = "intel-x58",
3ab90935 9502 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9503 [ALC889A_MB31] = "mb31",
3e1647c5 9504 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9505 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9506};
9507
4953550a
TI
9508static struct snd_pci_quirk alc882_cfg_tbl[] = {
9509 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9510
ac3e3741 9511 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9512 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9513 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9514 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9515 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9516 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9517 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9518 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9519 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9520 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9521 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9522 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9523 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9524 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9525 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9526 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9527 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9528 ALC888_ACER_ASPIRE_6530G),
cc374c47 9529 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9530 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9531 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9532 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9533 /* default Acer -- disabled as it causes more problems.
9534 * model=auto should work fine now
9535 */
9536 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9537
5795b9e6 9538 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9539
febe3375 9540 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9541 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9542 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9543 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9544 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9545 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9546
9547 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9548 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9549 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9550 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9551 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9552 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9553 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9554 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9555 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9556 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9557 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9558
9559 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9560 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9561 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9562 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9563 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9564 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9565 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9566 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9567 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9568
6f3bf657 9569 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9570 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9571 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9572 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9573 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9574 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9575 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9576 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9577 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9578 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9579 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9580 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9581 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9582 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9583 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9584 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9585 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9586 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9587 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9588 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9589 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9590 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9591 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9592 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9593 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9594 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9595 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9596 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9597 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9598 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9599 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9600
ac3e3741 9601 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9602 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9603 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9604 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9605 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9606 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9607 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9608 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9609 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9610 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9611 ALC883_FUJITSU_PI2515),
bfb53037 9612 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9613 ALC888_FUJITSU_XA3530),
272a527c 9614 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9615 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9616 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9617 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9618 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
272a527c 9619 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
959973b9 9620 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9621 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9622 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9623
17bba1b7
J
9624 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9625 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9626 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9627 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9628 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9629 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9630 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9631
4953550a 9632 {}
f3cd3f5d
WF
9633};
9634
4953550a
TI
9635/* codec SSID table for Intel Mac */
9636static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9637 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9638 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9639 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9640 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9641 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9642 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9643 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 9644 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 9645 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 9646 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 9647 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
9648 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9649 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9650 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9651 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9652 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 9653 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
9654 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9655 * so apparently no perfect solution yet
4953550a
TI
9656 */
9657 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9658 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9659 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9660 {} /* terminator */
b25c9da1
WF
9661};
9662
4953550a
TI
9663static struct alc_config_preset alc882_presets[] = {
9664 [ALC882_3ST_DIG] = {
9665 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9666 .init_verbs = { alc882_base_init_verbs,
9667 alc882_adc1_init_verbs },
4953550a
TI
9668 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9669 .dac_nids = alc882_dac_nids,
9670 .dig_out_nid = ALC882_DIGOUT_NID,
9671 .dig_in_nid = ALC882_DIGIN_NID,
9672 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9673 .channel_mode = alc882_ch_modes,
9674 .need_dac_fix = 1,
9675 .input_mux = &alc882_capture_source,
9676 },
9677 [ALC882_6ST_DIG] = {
9678 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9679 .init_verbs = { alc882_base_init_verbs,
9680 alc882_adc1_init_verbs },
4953550a
TI
9681 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9682 .dac_nids = alc882_dac_nids,
9683 .dig_out_nid = ALC882_DIGOUT_NID,
9684 .dig_in_nid = ALC882_DIGIN_NID,
9685 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9686 .channel_mode = alc882_sixstack_modes,
9687 .input_mux = &alc882_capture_source,
9688 },
9689 [ALC882_ARIMA] = {
9690 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9691 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9692 alc882_eapd_verbs },
4953550a
TI
9693 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9694 .dac_nids = alc882_dac_nids,
9695 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9696 .channel_mode = alc882_sixstack_modes,
9697 .input_mux = &alc882_capture_source,
9698 },
9699 [ALC882_W2JC] = {
9700 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9701 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9702 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
9703 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9704 .dac_nids = alc882_dac_nids,
9705 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9706 .channel_mode = alc880_threestack_modes,
9707 .need_dac_fix = 1,
9708 .input_mux = &alc882_capture_source,
9709 .dig_out_nid = ALC882_DIGOUT_NID,
9710 },
76e6f5a9
RH
9711 [ALC885_MBA21] = {
9712 .mixers = { alc885_mba21_mixer },
9713 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9714 .num_dacs = 2,
9715 .dac_nids = alc882_dac_nids,
9716 .channel_mode = alc885_mba21_ch_modes,
9717 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9718 .input_mux = &alc882_capture_source,
9719 .unsol_event = alc_automute_amp_unsol_event,
9720 .setup = alc885_mba21_setup,
9721 .init_hook = alc_automute_amp,
9722 },
4953550a
TI
9723 [ALC885_MBP3] = {
9724 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9725 .init_verbs = { alc885_mbp3_init_verbs,
9726 alc880_gpio1_init_verbs },
be0ae923 9727 .num_dacs = 2,
4953550a 9728 .dac_nids = alc882_dac_nids,
be0ae923
TI
9729 .hp_nid = 0x04,
9730 .channel_mode = alc885_mbp_4ch_modes,
9731 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
9732 .input_mux = &alc882_capture_source,
9733 .dig_out_nid = ALC882_DIGOUT_NID,
9734 .dig_in_nid = ALC882_DIGIN_NID,
9735 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9736 .setup = alc885_mbp3_setup,
9737 .init_hook = alc_automute_amp,
4953550a
TI
9738 },
9739 [ALC885_MB5] = {
9740 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
9741 .init_verbs = { alc885_mb5_init_verbs,
9742 alc880_gpio1_init_verbs },
9743 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9744 .dac_nids = alc882_dac_nids,
9745 .channel_mode = alc885_mb5_6ch_modes,
9746 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
9747 .input_mux = &mb5_capture_source,
9748 .dig_out_nid = ALC882_DIGOUT_NID,
9749 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9750 .unsol_event = alc_automute_amp_unsol_event,
9751 .setup = alc885_mb5_setup,
9752 .init_hook = alc_automute_amp,
4953550a 9753 },
e458b1fa
LY
9754 [ALC885_MACMINI3] = {
9755 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9756 .init_verbs = { alc885_macmini3_init_verbs,
9757 alc880_gpio1_init_verbs },
9758 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9759 .dac_nids = alc882_dac_nids,
9760 .channel_mode = alc885_macmini3_6ch_modes,
9761 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9762 .input_mux = &macmini3_capture_source,
9763 .dig_out_nid = ALC882_DIGOUT_NID,
9764 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9765 .unsol_event = alc_automute_amp_unsol_event,
9766 .setup = alc885_macmini3_setup,
9767 .init_hook = alc_automute_amp,
e458b1fa 9768 },
4953550a
TI
9769 [ALC885_MACPRO] = {
9770 .mixers = { alc882_macpro_mixer },
9771 .init_verbs = { alc882_macpro_init_verbs },
9772 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9773 .dac_nids = alc882_dac_nids,
9774 .dig_out_nid = ALC882_DIGOUT_NID,
9775 .dig_in_nid = ALC882_DIGIN_NID,
9776 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9777 .channel_mode = alc882_ch_modes,
9778 .input_mux = &alc882_capture_source,
9779 .init_hook = alc885_macpro_init_hook,
9780 },
9781 [ALC885_IMAC24] = {
9782 .mixers = { alc885_imac24_mixer },
9783 .init_verbs = { alc885_imac24_init_verbs },
9784 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9785 .dac_nids = alc882_dac_nids,
9786 .dig_out_nid = ALC882_DIGOUT_NID,
9787 .dig_in_nid = ALC882_DIGIN_NID,
9788 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9789 .channel_mode = alc882_ch_modes,
9790 .input_mux = &alc882_capture_source,
9791 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 9792 .setup = alc885_imac24_setup,
4953550a
TI
9793 .init_hook = alc885_imac24_init_hook,
9794 },
4b7e1803 9795 [ALC885_IMAC91] = {
b7cccc52 9796 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
9797 .init_verbs = { alc885_imac91_init_verbs,
9798 alc880_gpio1_init_verbs },
9799 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9800 .dac_nids = alc882_dac_nids,
b7cccc52
JM
9801 .channel_mode = alc885_mba21_ch_modes,
9802 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9803 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
9804 .dig_out_nid = ALC882_DIGOUT_NID,
9805 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9806 .unsol_event = alc_automute_amp_unsol_event,
9807 .setup = alc885_imac91_setup,
9808 .init_hook = alc_automute_amp,
4b7e1803 9809 },
4953550a
TI
9810 [ALC882_TARGA] = {
9811 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 9812 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 9813 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
9814 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9815 .dac_nids = alc882_dac_nids,
9816 .dig_out_nid = ALC882_DIGOUT_NID,
9817 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9818 .adc_nids = alc882_adc_nids,
9819 .capsrc_nids = alc882_capsrc_nids,
9820 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9821 .channel_mode = alc882_3ST_6ch_modes,
9822 .need_dac_fix = 1,
9823 .input_mux = &alc882_capture_source,
9824 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
9825 .setup = alc882_targa_setup,
9826 .init_hook = alc882_targa_automute,
4953550a
TI
9827 },
9828 [ALC882_ASUS_A7J] = {
9829 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9830 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9831 alc882_asus_a7j_verbs},
4953550a
TI
9832 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9833 .dac_nids = alc882_dac_nids,
9834 .dig_out_nid = ALC882_DIGOUT_NID,
9835 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9836 .adc_nids = alc882_adc_nids,
9837 .capsrc_nids = alc882_capsrc_nids,
9838 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9839 .channel_mode = alc882_3ST_6ch_modes,
9840 .need_dac_fix = 1,
9841 .input_mux = &alc882_capture_source,
9842 },
9843 [ALC882_ASUS_A7M] = {
9844 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9845 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9846 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
9847 alc882_asus_a7m_verbs },
9848 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9849 .dac_nids = alc882_dac_nids,
9850 .dig_out_nid = ALC882_DIGOUT_NID,
9851 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9852 .channel_mode = alc880_threestack_modes,
9853 .need_dac_fix = 1,
9854 .input_mux = &alc882_capture_source,
9855 },
9c7f852e
TI
9856 [ALC883_3ST_2ch_DIG] = {
9857 .mixers = { alc883_3ST_2ch_mixer },
9858 .init_verbs = { alc883_init_verbs },
9859 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9860 .dac_nids = alc883_dac_nids,
9861 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9862 .dig_in_nid = ALC883_DIGIN_NID,
9863 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9864 .channel_mode = alc883_3ST_2ch_modes,
9865 .input_mux = &alc883_capture_source,
9866 },
9867 [ALC883_3ST_6ch_DIG] = {
9868 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9869 .init_verbs = { alc883_init_verbs },
9870 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9871 .dac_nids = alc883_dac_nids,
9872 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9873 .dig_in_nid = ALC883_DIGIN_NID,
9874 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9875 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9876 .need_dac_fix = 1,
9c7f852e 9877 .input_mux = &alc883_capture_source,
f12ab1e0 9878 },
9c7f852e
TI
9879 [ALC883_3ST_6ch] = {
9880 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9881 .init_verbs = { alc883_init_verbs },
9882 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9883 .dac_nids = alc883_dac_nids,
9c7f852e
TI
9884 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9885 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9886 .need_dac_fix = 1,
9c7f852e 9887 .input_mux = &alc883_capture_source,
f12ab1e0 9888 },
17bba1b7
J
9889 [ALC883_3ST_6ch_INTEL] = {
9890 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
9891 .init_verbs = { alc883_init_verbs },
9892 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9893 .dac_nids = alc883_dac_nids,
9894 .dig_out_nid = ALC883_DIGOUT_NID,
9895 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 9896 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
9897 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
9898 .channel_mode = alc883_3ST_6ch_intel_modes,
9899 .need_dac_fix = 1,
9900 .input_mux = &alc883_3stack_6ch_intel,
9901 },
87a8c370
JK
9902 [ALC889A_INTEL] = {
9903 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
9904 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
9905 alc_hp15_unsol_verbs },
87a8c370
JK
9906 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9907 .dac_nids = alc883_dac_nids,
9908 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9909 .adc_nids = alc889_adc_nids,
9910 .dig_out_nid = ALC883_DIGOUT_NID,
9911 .dig_in_nid = ALC883_DIGIN_NID,
9912 .slave_dig_outs = alc883_slave_dig_outs,
9913 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9914 .channel_mode = alc889_8ch_intel_modes,
9915 .capsrc_nids = alc889_capsrc_nids,
9916 .input_mux = &alc889_capture_source,
4f5d1706
TI
9917 .setup = alc889_automute_setup,
9918 .init_hook = alc_automute_amp,
6732bd0d 9919 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
9920 .need_dac_fix = 1,
9921 },
9922 [ALC889_INTEL] = {
9923 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9924 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 9925 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
9926 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9927 .dac_nids = alc883_dac_nids,
9928 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9929 .adc_nids = alc889_adc_nids,
9930 .dig_out_nid = ALC883_DIGOUT_NID,
9931 .dig_in_nid = ALC883_DIGIN_NID,
9932 .slave_dig_outs = alc883_slave_dig_outs,
9933 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9934 .channel_mode = alc889_8ch_intel_modes,
9935 .capsrc_nids = alc889_capsrc_nids,
9936 .input_mux = &alc889_capture_source,
4f5d1706 9937 .setup = alc889_automute_setup,
6732bd0d
WF
9938 .init_hook = alc889_intel_init_hook,
9939 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
9940 .need_dac_fix = 1,
9941 },
9c7f852e
TI
9942 [ALC883_6ST_DIG] = {
9943 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9944 .init_verbs = { alc883_init_verbs },
9945 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9946 .dac_nids = alc883_dac_nids,
9947 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9948 .dig_in_nid = ALC883_DIGIN_NID,
9949 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9950 .channel_mode = alc883_sixstack_modes,
9951 .input_mux = &alc883_capture_source,
9952 },
ccc656ce 9953 [ALC883_TARGA_DIG] = {
c259249f 9954 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
9955 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9956 alc883_targa_verbs},
ccc656ce
KY
9957 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9958 .dac_nids = alc883_dac_nids,
9959 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9960 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9961 .channel_mode = alc883_3ST_6ch_modes,
9962 .need_dac_fix = 1,
9963 .input_mux = &alc883_capture_source,
c259249f 9964 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9965 .setup = alc882_targa_setup,
9966 .init_hook = alc882_targa_automute,
ccc656ce
KY
9967 },
9968 [ALC883_TARGA_2ch_DIG] = {
c259249f 9969 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
9970 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9971 alc883_targa_verbs},
ccc656ce
KY
9972 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9973 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9974 .adc_nids = alc883_adc_nids_alt,
9975 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 9976 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 9977 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9978 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9979 .channel_mode = alc883_3ST_2ch_modes,
9980 .input_mux = &alc883_capture_source,
c259249f 9981 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9982 .setup = alc882_targa_setup,
9983 .init_hook = alc882_targa_automute,
ccc656ce 9984 },
64a8be74 9985 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
9986 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
9987 alc883_chmode_mixer },
64a8be74 9988 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 9989 alc883_targa_verbs },
64a8be74
DH
9990 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9991 .dac_nids = alc883_dac_nids,
9992 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9993 .adc_nids = alc883_adc_nids_rev,
9994 .capsrc_nids = alc883_capsrc_nids_rev,
9995 .dig_out_nid = ALC883_DIGOUT_NID,
9996 .dig_in_nid = ALC883_DIGIN_NID,
9997 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
9998 .channel_mode = alc883_4ST_8ch_modes,
9999 .need_dac_fix = 1,
10000 .input_mux = &alc883_capture_source,
c259249f 10001 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10002 .setup = alc882_targa_setup,
10003 .init_hook = alc882_targa_automute,
64a8be74 10004 },
bab282b9 10005 [ALC883_ACER] = {
676a9b53 10006 .mixers = { alc883_base_mixer },
bab282b9
VA
10007 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10008 * and the headphone jack. Turn this on and rely on the
10009 * standard mute methods whenever the user wants to turn
10010 * these outputs off.
10011 */
10012 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10013 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10014 .dac_nids = alc883_dac_nids,
bab282b9
VA
10015 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10016 .channel_mode = alc883_3ST_2ch_modes,
10017 .input_mux = &alc883_capture_source,
10018 },
2880a867 10019 [ALC883_ACER_ASPIRE] = {
676a9b53 10020 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10021 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10022 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10023 .dac_nids = alc883_dac_nids,
10024 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10025 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10026 .channel_mode = alc883_3ST_2ch_modes,
10027 .input_mux = &alc883_capture_source,
a9fd4f3f 10028 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10029 .setup = alc883_acer_aspire_setup,
10030 .init_hook = alc_automute_amp,
d1a991a6 10031 },
5b2d1eca 10032 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 10033 .mixers = { alc888_base_mixer,
5b2d1eca
VP
10034 alc883_chmode_mixer },
10035 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10036 alc888_acer_aspire_4930g_verbs },
10037 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10038 .dac_nids = alc883_dac_nids,
10039 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10040 .adc_nids = alc883_adc_nids_rev,
10041 .capsrc_nids = alc883_capsrc_nids_rev,
10042 .dig_out_nid = ALC883_DIGOUT_NID,
10043 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10044 .channel_mode = alc883_3ST_6ch_modes,
10045 .need_dac_fix = 1,
973b8cb0 10046 .const_channel_count = 6,
5b2d1eca 10047 .num_mux_defs =
ef8ef5fb
VP
10048 ARRAY_SIZE(alc888_2_capture_sources),
10049 .input_mux = alc888_2_capture_sources,
d2fd4b09 10050 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10051 .setup = alc888_acer_aspire_4930g_setup,
10052 .init_hook = alc_automute_amp,
d2fd4b09
TV
10053 },
10054 [ALC888_ACER_ASPIRE_6530G] = {
10055 .mixers = { alc888_acer_aspire_6530_mixer },
10056 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10057 alc888_acer_aspire_6530g_verbs },
10058 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10059 .dac_nids = alc883_dac_nids,
10060 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10061 .adc_nids = alc883_adc_nids_rev,
10062 .capsrc_nids = alc883_capsrc_nids_rev,
10063 .dig_out_nid = ALC883_DIGOUT_NID,
10064 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10065 .channel_mode = alc883_3ST_2ch_modes,
10066 .num_mux_defs =
10067 ARRAY_SIZE(alc888_2_capture_sources),
10068 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 10069 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10070 .setup = alc888_acer_aspire_6530g_setup,
10071 .init_hook = alc_automute_amp,
5b2d1eca 10072 },
3b315d70 10073 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10074 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10075 alc883_chmode_mixer },
10076 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10077 alc889_acer_aspire_8930g_verbs,
10078 alc889_eapd_verbs},
3b315d70
HM
10079 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10080 .dac_nids = alc883_dac_nids,
018df418
HM
10081 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10082 .adc_nids = alc889_adc_nids,
10083 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10084 .dig_out_nid = ALC883_DIGOUT_NID,
10085 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10086 .channel_mode = alc883_3ST_6ch_modes,
10087 .need_dac_fix = 1,
10088 .const_channel_count = 6,
10089 .num_mux_defs =
018df418
HM
10090 ARRAY_SIZE(alc889_capture_sources),
10091 .input_mux = alc889_capture_sources,
3b315d70 10092 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10093 .setup = alc889_acer_aspire_8930g_setup,
10094 .init_hook = alc_automute_amp,
f5de24b0 10095#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10096 .power_hook = alc_power_eapd,
f5de24b0 10097#endif
3b315d70 10098 },
fc86f954
DK
10099 [ALC888_ACER_ASPIRE_7730G] = {
10100 .mixers = { alc883_3ST_6ch_mixer,
10101 alc883_chmode_mixer },
10102 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10103 alc888_acer_aspire_7730G_verbs },
10104 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10105 .dac_nids = alc883_dac_nids,
10106 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10107 .adc_nids = alc883_adc_nids_rev,
10108 .capsrc_nids = alc883_capsrc_nids_rev,
10109 .dig_out_nid = ALC883_DIGOUT_NID,
10110 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10111 .channel_mode = alc883_3ST_6ch_modes,
10112 .need_dac_fix = 1,
10113 .const_channel_count = 6,
10114 .input_mux = &alc883_capture_source,
10115 .unsol_event = alc_automute_amp_unsol_event,
10116 .setup = alc888_acer_aspire_6530g_setup,
10117 .init_hook = alc_automute_amp,
10118 },
c07584c8
TD
10119 [ALC883_MEDION] = {
10120 .mixers = { alc883_fivestack_mixer,
10121 alc883_chmode_mixer },
10122 .init_verbs = { alc883_init_verbs,
b373bdeb 10123 alc883_medion_eapd_verbs },
c07584c8
TD
10124 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10125 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10126 .adc_nids = alc883_adc_nids_alt,
10127 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10128 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10129 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10130 .channel_mode = alc883_sixstack_modes,
10131 .input_mux = &alc883_capture_source,
b373bdeb 10132 },
272a527c
KY
10133 [ALC883_MEDION_MD2] = {
10134 .mixers = { alc883_medion_md2_mixer},
10135 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
10136 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10137 .dac_nids = alc883_dac_nids,
10138 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10139 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10140 .channel_mode = alc883_3ST_2ch_modes,
10141 .input_mux = &alc883_capture_source,
a9fd4f3f 10142 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10143 .setup = alc883_medion_md2_setup,
10144 .init_hook = alc_automute_amp,
ea1fb29a 10145 },
7ad7b218
MC
10146 [ALC883_MEDION_WIM2160] = {
10147 .mixers = { alc883_medion_wim2160_mixer },
10148 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10149 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10150 .dac_nids = alc883_dac_nids,
10151 .dig_out_nid = ALC883_DIGOUT_NID,
10152 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10153 .adc_nids = alc883_adc_nids,
10154 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10155 .channel_mode = alc883_3ST_2ch_modes,
10156 .input_mux = &alc883_capture_source,
10157 .unsol_event = alc_automute_amp_unsol_event,
10158 .setup = alc883_medion_wim2160_setup,
10159 .init_hook = alc_automute_amp,
10160 },
b373bdeb 10161 [ALC883_LAPTOP_EAPD] = {
676a9b53 10162 .mixers = { alc883_base_mixer },
b373bdeb
AN
10163 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10164 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10165 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10166 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10167 .channel_mode = alc883_3ST_2ch_modes,
10168 .input_mux = &alc883_capture_source,
10169 },
a65cc60f 10170 [ALC883_CLEVO_M540R] = {
10171 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10172 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10173 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10174 .dac_nids = alc883_dac_nids,
10175 .dig_out_nid = ALC883_DIGOUT_NID,
10176 .dig_in_nid = ALC883_DIGIN_NID,
10177 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10178 .channel_mode = alc883_3ST_6ch_clevo_modes,
10179 .need_dac_fix = 1,
10180 .input_mux = &alc883_capture_source,
10181 /* This machine has the hardware HP auto-muting, thus
10182 * we need no software mute via unsol event
10183 */
10184 },
0c4cc443
HRK
10185 [ALC883_CLEVO_M720] = {
10186 .mixers = { alc883_clevo_m720_mixer },
10187 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10188 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10189 .dac_nids = alc883_dac_nids,
10190 .dig_out_nid = ALC883_DIGOUT_NID,
10191 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10192 .channel_mode = alc883_3ST_2ch_modes,
10193 .input_mux = &alc883_capture_source,
0c4cc443 10194 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10195 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10196 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10197 },
bc9f98a9
KY
10198 [ALC883_LENOVO_101E_2ch] = {
10199 .mixers = { alc883_lenovo_101e_2ch_mixer},
10200 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10201 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10202 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10203 .adc_nids = alc883_adc_nids_alt,
10204 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10205 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10206 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10207 .channel_mode = alc883_3ST_2ch_modes,
10208 .input_mux = &alc883_lenovo_101e_capture_source,
10209 .unsol_event = alc883_lenovo_101e_unsol_event,
10210 .init_hook = alc883_lenovo_101e_all_automute,
10211 },
272a527c
KY
10212 [ALC883_LENOVO_NB0763] = {
10213 .mixers = { alc883_lenovo_nb0763_mixer },
10214 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10215 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10216 .dac_nids = alc883_dac_nids,
272a527c
KY
10217 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10218 .channel_mode = alc883_3ST_2ch_modes,
10219 .need_dac_fix = 1,
10220 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 10221 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10222 .setup = alc883_medion_md2_setup,
10223 .init_hook = alc_automute_amp,
272a527c
KY
10224 },
10225 [ALC888_LENOVO_MS7195_DIG] = {
10226 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10227 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10228 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10229 .dac_nids = alc883_dac_nids,
10230 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10231 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10232 .channel_mode = alc883_3ST_6ch_modes,
10233 .need_dac_fix = 1,
10234 .input_mux = &alc883_capture_source,
10235 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10236 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
10237 },
10238 [ALC883_HAIER_W66] = {
c259249f 10239 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10240 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10241 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10242 .dac_nids = alc883_dac_nids,
10243 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10244 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10245 .channel_mode = alc883_3ST_2ch_modes,
10246 .input_mux = &alc883_capture_source,
a9fd4f3f 10247 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10248 .setup = alc883_haier_w66_setup,
10249 .init_hook = alc_automute_amp,
eea6419e 10250 },
4723c022 10251 [ALC888_3ST_HP] = {
eea6419e 10252 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10253 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10254 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10255 .dac_nids = alc883_dac_nids,
4723c022
CM
10256 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10257 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10258 .need_dac_fix = 1,
10259 .input_mux = &alc883_capture_source,
a9fd4f3f 10260 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10261 .setup = alc888_3st_hp_setup,
10262 .init_hook = alc_automute_amp,
8341de60 10263 },
5795b9e6 10264 [ALC888_6ST_DELL] = {
f24dbdc6 10265 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10266 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10267 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10268 .dac_nids = alc883_dac_nids,
10269 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10270 .dig_in_nid = ALC883_DIGIN_NID,
10271 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10272 .channel_mode = alc883_sixstack_modes,
10273 .input_mux = &alc883_capture_source,
a9fd4f3f 10274 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10275 .setup = alc888_6st_dell_setup,
10276 .init_hook = alc_automute_amp,
5795b9e6 10277 },
a8848bd6
AS
10278 [ALC883_MITAC] = {
10279 .mixers = { alc883_mitac_mixer },
10280 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10281 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10282 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10283 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10284 .channel_mode = alc883_3ST_2ch_modes,
10285 .input_mux = &alc883_capture_source,
a9fd4f3f 10286 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10287 .setup = alc883_mitac_setup,
10288 .init_hook = alc_automute_amp,
a8848bd6 10289 },
fb97dc67
J
10290 [ALC883_FUJITSU_PI2515] = {
10291 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10292 .init_verbs = { alc883_init_verbs,
10293 alc883_2ch_fujitsu_pi2515_verbs},
10294 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10295 .dac_nids = alc883_dac_nids,
10296 .dig_out_nid = ALC883_DIGOUT_NID,
10297 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10298 .channel_mode = alc883_3ST_2ch_modes,
10299 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10300 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10301 .setup = alc883_2ch_fujitsu_pi2515_setup,
10302 .init_hook = alc_automute_amp,
fb97dc67 10303 },
ef8ef5fb
VP
10304 [ALC888_FUJITSU_XA3530] = {
10305 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10306 .init_verbs = { alc883_init_verbs,
10307 alc888_fujitsu_xa3530_verbs },
10308 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10309 .dac_nids = alc883_dac_nids,
10310 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10311 .adc_nids = alc883_adc_nids_rev,
10312 .capsrc_nids = alc883_capsrc_nids_rev,
10313 .dig_out_nid = ALC883_DIGOUT_NID,
10314 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10315 .channel_mode = alc888_4ST_8ch_intel_modes,
10316 .num_mux_defs =
10317 ARRAY_SIZE(alc888_2_capture_sources),
10318 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10319 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10320 .setup = alc888_fujitsu_xa3530_setup,
10321 .init_hook = alc_automute_amp,
ef8ef5fb 10322 },
e2757d5e
KY
10323 [ALC888_LENOVO_SKY] = {
10324 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10325 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10326 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10327 .dac_nids = alc883_dac_nids,
10328 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10329 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10330 .channel_mode = alc883_sixstack_modes,
10331 .need_dac_fix = 1,
10332 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10333 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10334 .setup = alc888_lenovo_sky_setup,
10335 .init_hook = alc_automute_amp,
e2757d5e
KY
10336 },
10337 [ALC888_ASUS_M90V] = {
10338 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10339 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10340 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10341 .dac_nids = alc883_dac_nids,
10342 .dig_out_nid = ALC883_DIGOUT_NID,
10343 .dig_in_nid = ALC883_DIGIN_NID,
10344 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10345 .channel_mode = alc883_3ST_6ch_modes,
10346 .need_dac_fix = 1,
10347 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10348 .unsol_event = alc_sku_unsol_event,
10349 .setup = alc883_mode2_setup,
10350 .init_hook = alc_inithook,
e2757d5e
KY
10351 },
10352 [ALC888_ASUS_EEE1601] = {
10353 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10354 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10355 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10356 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10357 .dac_nids = alc883_dac_nids,
10358 .dig_out_nid = ALC883_DIGOUT_NID,
10359 .dig_in_nid = ALC883_DIGIN_NID,
10360 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10361 .channel_mode = alc883_3ST_2ch_modes,
10362 .need_dac_fix = 1,
10363 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10364 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10365 .init_hook = alc883_eee1601_inithook,
10366 },
3ab90935
WF
10367 [ALC1200_ASUS_P5Q] = {
10368 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10369 .init_verbs = { alc883_init_verbs },
10370 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10371 .dac_nids = alc883_dac_nids,
10372 .dig_out_nid = ALC1200_DIGOUT_NID,
10373 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10374 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10375 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10376 .channel_mode = alc883_sixstack_modes,
10377 .input_mux = &alc883_capture_source,
10378 },
eb4c41d3
TS
10379 [ALC889A_MB31] = {
10380 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10381 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10382 alc880_gpio1_init_verbs },
10383 .adc_nids = alc883_adc_nids,
10384 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10385 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10386 .dac_nids = alc883_dac_nids,
10387 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10388 .channel_mode = alc889A_mb31_6ch_modes,
10389 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10390 .input_mux = &alc889A_mb31_capture_source,
10391 .dig_out_nid = ALC883_DIGOUT_NID,
10392 .unsol_event = alc889A_mb31_unsol_event,
10393 .init_hook = alc889A_mb31_automute,
10394 },
3e1647c5
GG
10395 [ALC883_SONY_VAIO_TT] = {
10396 .mixers = { alc883_vaiott_mixer },
10397 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10398 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10399 .dac_nids = alc883_dac_nids,
10400 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10401 .channel_mode = alc883_3ST_2ch_modes,
10402 .input_mux = &alc883_capture_source,
10403 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10404 .setup = alc883_vaiott_setup,
10405 .init_hook = alc_automute_amp,
3e1647c5 10406 },
9c7f852e
TI
10407};
10408
10409
4953550a
TI
10410/*
10411 * Pin config fixes
10412 */
10413enum {
954a29c8
TI
10414 PINFIX_ABIT_AW9D_MAX,
10415 PINFIX_PB_M5210,
4953550a
TI
10416};
10417
10418static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
10419 { 0x15, 0x01080104 }, /* side */
10420 { 0x16, 0x01011012 }, /* rear */
10421 { 0x17, 0x01016011 }, /* clfe */
10422 { }
10423};
10424
954a29c8
TI
10425static const struct hda_verb pb_m5210_verbs[] = {
10426 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10427 {}
10428};
10429
f8f25ba3
TI
10430static const struct alc_fixup alc882_fixups[] = {
10431 [PINFIX_ABIT_AW9D_MAX] = {
10432 .pins = alc882_abit_aw9d_pinfix
10433 },
954a29c8
TI
10434 [PINFIX_PB_M5210] = {
10435 .verbs = pb_m5210_verbs
10436 },
4953550a
TI
10437};
10438
f8f25ba3 10439static struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10440 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
4953550a
TI
10441 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10442 {}
10443};
10444
9c7f852e
TI
10445/*
10446 * BIOS auto configuration
10447 */
05f5f477
TI
10448static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10449 const struct auto_pin_cfg *cfg)
10450{
10451 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10452}
10453
4953550a 10454static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10455 hda_nid_t nid, int pin_type,
489008cd 10456 hda_nid_t dac)
9c7f852e 10457{
f12ab1e0
TI
10458 int idx;
10459
489008cd 10460 /* set as output */
f6c7e546 10461 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10462
10463 if (dac == 0x25)
9c7f852e 10464 idx = 4;
489008cd
TI
10465 else if (dac >= 0x02 && dac <= 0x05)
10466 idx = dac - 2;
f9700d5a 10467 else
489008cd 10468 return;
9c7f852e 10469 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
10470}
10471
4953550a 10472static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10473{
10474 struct alc_spec *spec = codec->spec;
10475 int i;
10476
10477 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10478 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10479 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10480 if (nid)
4953550a 10481 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 10482 spec->multiout.dac_nids[i]);
9c7f852e
TI
10483 }
10484}
10485
4953550a 10486static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10487{
10488 struct alc_spec *spec = codec->spec;
489008cd 10489 hda_nid_t pin, dac;
9c7f852e 10490
eb06ed8f 10491 pin = spec->autocfg.hp_pins[0];
489008cd
TI
10492 if (pin) {
10493 dac = spec->multiout.hp_nid;
10494 if (!dac)
10495 dac = spec->multiout.dac_nids[0]; /* to front */
10496 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10497 }
f6c7e546 10498 pin = spec->autocfg.speaker_pins[0];
489008cd
TI
10499 if (pin) {
10500 dac = spec->multiout.extra_out_nid[0];
10501 if (!dac)
10502 dac = spec->multiout.dac_nids[0]; /* to front */
10503 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10504 }
9c7f852e
TI
10505}
10506
4953550a 10507static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10508{
10509 struct alc_spec *spec = codec->spec;
10510 int i;
10511
10512 for (i = 0; i < AUTO_PIN_LAST; i++) {
10513 hda_nid_t nid = spec->autocfg.input_pins[i];
4953550a
TI
10514 if (!nid)
10515 continue;
0d971c9f 10516 alc_set_input_pin(codec, nid, i);
4953550a
TI
10517 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10518 snd_hda_codec_write(codec, nid, 0,
10519 AC_VERB_SET_AMP_GAIN_MUTE,
10520 AMP_OUT_MUTE);
10521 }
10522}
10523
10524static void alc882_auto_init_input_src(struct hda_codec *codec)
10525{
10526 struct alc_spec *spec = codec->spec;
10527 int c;
10528
10529 for (c = 0; c < spec->num_adc_nids; c++) {
10530 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10531 hda_nid_t nid = spec->capsrc_nids[c];
10532 unsigned int mux_idx;
10533 const struct hda_input_mux *imux;
10534 int conns, mute, idx, item;
10535
10536 conns = snd_hda_get_connections(codec, nid, conn_list,
10537 ARRAY_SIZE(conn_list));
10538 if (conns < 0)
10539 continue;
10540 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10541 imux = &spec->input_mux[mux_idx];
5311114d
TI
10542 if (!imux->num_items && mux_idx > 0)
10543 imux = &spec->input_mux[0];
4953550a
TI
10544 for (idx = 0; idx < conns; idx++) {
10545 /* if the current connection is the selected one,
10546 * unmute it as default - otherwise mute it
10547 */
10548 mute = AMP_IN_MUTE(idx);
10549 for (item = 0; item < imux->num_items; item++) {
10550 if (imux->items[item].index == idx) {
10551 if (spec->cur_mux[c] == item)
10552 mute = AMP_IN_UNMUTE(idx);
10553 break;
10554 }
10555 }
10556 /* check if we have a selector or mixer
10557 * we could check for the widget type instead, but
10558 * just check for Amp-In presence (in case of mixer
10559 * without amp-in there is something wrong, this
10560 * function shouldn't be used or capsrc nid is wrong)
10561 */
10562 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10563 snd_hda_codec_write(codec, nid, 0,
10564 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10565 mute);
10566 else if (mute != AMP_IN_MUTE(idx))
10567 snd_hda_codec_write(codec, nid, 0,
10568 AC_VERB_SET_CONNECT_SEL,
10569 idx);
9c7f852e
TI
10570 }
10571 }
10572}
10573
4953550a
TI
10574/* add mic boosts if needed */
10575static int alc_auto_add_mic_boost(struct hda_codec *codec)
10576{
10577 struct alc_spec *spec = codec->spec;
10578 int err;
10579 hda_nid_t nid;
10580
10581 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
10582 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10583 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10584 "Mic Boost",
10585 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10586 if (err < 0)
10587 return err;
10588 }
10589 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
10590 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10591 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10592 "Front Mic Boost",
10593 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10594 if (err < 0)
10595 return err;
10596 }
10597 return 0;
10598}
f511b01c 10599
9c7f852e 10600/* almost identical with ALC880 parser... */
4953550a 10601static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10602{
10603 struct alc_spec *spec = codec->spec;
05f5f477 10604 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 10605 int err;
9c7f852e 10606
05f5f477
TI
10607 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10608 alc882_ignore);
9c7f852e
TI
10609 if (err < 0)
10610 return err;
05f5f477
TI
10611 if (!spec->autocfg.line_outs)
10612 return 0; /* can't find valid BIOS pin config */
776e184e 10613
05f5f477
TI
10614 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10615 if (err < 0)
10616 return err;
10617 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
10618 if (err < 0)
10619 return err;
10620 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10621 "Headphone");
05f5f477
TI
10622 if (err < 0)
10623 return err;
10624 err = alc880_auto_create_extra_out(spec,
10625 spec->autocfg.speaker_pins[0],
10626 "Speaker");
10627 if (err < 0)
10628 return err;
05f5f477 10629 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10630 if (err < 0)
10631 return err;
10632
05f5f477
TI
10633 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10634
757899ac 10635 alc_auto_parse_digital(codec);
05f5f477
TI
10636
10637 if (spec->kctls.list)
10638 add_mixer(spec, spec->kctls.list);
10639
10640 add_verb(spec, alc883_auto_init_verbs);
4953550a 10641 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10642 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10643 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10644
05f5f477
TI
10645 spec->num_mux_defs = 1;
10646 spec->input_mux = &spec->private_imux[0];
10647
6227cdce 10648 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10649
10650 err = alc_auto_add_mic_boost(codec);
10651 if (err < 0)
10652 return err;
61b9b9b1 10653
776e184e 10654 return 1; /* config found */
9c7f852e
TI
10655}
10656
10657/* additional initialization for auto-configuration model */
4953550a 10658static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10659{
f6c7e546 10660 struct alc_spec *spec = codec->spec;
4953550a
TI
10661 alc882_auto_init_multi_out(codec);
10662 alc882_auto_init_hp_out(codec);
10663 alc882_auto_init_analog_input(codec);
10664 alc882_auto_init_input_src(codec);
757899ac 10665 alc_auto_init_digital(codec);
f6c7e546 10666 if (spec->unsol_event)
7fb0d78f 10667 alc_inithook(codec);
9c7f852e
TI
10668}
10669
4953550a 10670static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10671{
10672 struct alc_spec *spec;
10673 int err, board_config;
10674
10675 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10676 if (spec == NULL)
10677 return -ENOMEM;
10678
10679 codec->spec = spec;
10680
da00c244
KY
10681 alc_auto_parse_customize_define(codec);
10682
4953550a
TI
10683 switch (codec->vendor_id) {
10684 case 0x10ec0882:
10685 case 0x10ec0885:
10686 break;
10687 default:
10688 /* ALC883 and variants */
10689 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10690 break;
10691 }
2c3bf9ab 10692
4953550a
TI
10693 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10694 alc882_models,
10695 alc882_cfg_tbl);
10696
10697 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10698 board_config = snd_hda_check_board_codec_sid_config(codec,
10699 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10700
10701 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 10702 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
10703 codec->chip_name);
10704 board_config = ALC882_AUTO;
9c7f852e
TI
10705 }
10706
7fa90e87
TI
10707 if (board_config == ALC882_AUTO)
10708 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
4953550a
TI
10709
10710 if (board_config == ALC882_AUTO) {
9c7f852e 10711 /* automatic parse from the BIOS config */
4953550a 10712 err = alc882_parse_auto_config(codec);
9c7f852e
TI
10713 if (err < 0) {
10714 alc_free(codec);
10715 return err;
f12ab1e0 10716 } else if (!err) {
9c7f852e
TI
10717 printk(KERN_INFO
10718 "hda_codec: Cannot set up configuration "
10719 "from BIOS. Using base mode...\n");
4953550a 10720 board_config = ALC882_3ST_DIG;
9c7f852e
TI
10721 }
10722 }
10723
dc1eae25 10724 if (has_cdefine_beep(codec)) {
8af2591d
TI
10725 err = snd_hda_attach_beep_device(codec, 0x1);
10726 if (err < 0) {
10727 alc_free(codec);
10728 return err;
10729 }
680cd536
KK
10730 }
10731
4953550a 10732 if (board_config != ALC882_AUTO)
e9c364c0 10733 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 10734
4953550a
TI
10735 spec->stream_analog_playback = &alc882_pcm_analog_playback;
10736 spec->stream_analog_capture = &alc882_pcm_analog_capture;
10737 /* FIXME: setup DAC5 */
10738 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
10739 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
10740
10741 spec->stream_digital_playback = &alc882_pcm_digital_playback;
10742 spec->stream_digital_capture = &alc882_pcm_digital_capture;
10743
4953550a 10744 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 10745 int i, j;
4953550a
TI
10746 spec->num_adc_nids = 0;
10747 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 10748 const struct hda_input_mux *imux = spec->input_mux;
4953550a 10749 hda_nid_t cap;
d11f74c6 10750 hda_nid_t items[16];
4953550a
TI
10751 hda_nid_t nid = alc882_adc_nids[i];
10752 unsigned int wcap = get_wcaps(codec, nid);
10753 /* get type */
a22d543a 10754 wcap = get_wcaps_type(wcap);
4953550a
TI
10755 if (wcap != AC_WID_AUD_IN)
10756 continue;
10757 spec->private_adc_nids[spec->num_adc_nids] = nid;
10758 err = snd_hda_get_connections(codec, nid, &cap, 1);
10759 if (err < 0)
10760 continue;
d11f74c6
TI
10761 err = snd_hda_get_connections(codec, cap, items,
10762 ARRAY_SIZE(items));
10763 if (err < 0)
10764 continue;
10765 for (j = 0; j < imux->num_items; j++)
10766 if (imux->items[j].index >= err)
10767 break;
10768 if (j < imux->num_items)
10769 continue;
4953550a
TI
10770 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
10771 spec->num_adc_nids++;
61b9b9b1 10772 }
4953550a
TI
10773 spec->adc_nids = spec->private_adc_nids;
10774 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
10775 }
10776
b59bdf3b 10777 set_capture_mixer(codec);
da00c244 10778
dc1eae25 10779 if (has_cdefine_beep(codec))
da00c244 10780 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 10781
7fa90e87
TI
10782 if (board_config == ALC882_AUTO)
10783 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
10784
2134ea4f
TI
10785 spec->vmaster_nid = 0x0c;
10786
9c7f852e 10787 codec->patch_ops = alc_patch_ops;
4953550a
TI
10788 if (board_config == ALC882_AUTO)
10789 spec->init_hook = alc882_auto_init;
cb53c626
TI
10790#ifdef CONFIG_SND_HDA_POWER_SAVE
10791 if (!spec->loopback.amplist)
4953550a 10792 spec->loopback.amplist = alc882_loopbacks;
cb53c626 10793#endif
9c7f852e
TI
10794
10795 return 0;
10796}
10797
4953550a 10798
9c7f852e
TI
10799/*
10800 * ALC262 support
10801 */
10802
10803#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
10804#define ALC262_DIGIN_NID ALC880_DIGIN_NID
10805
10806#define alc262_dac_nids alc260_dac_nids
10807#define alc262_adc_nids alc882_adc_nids
10808#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
10809#define alc262_capsrc_nids alc882_capsrc_nids
10810#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
10811
10812#define alc262_modes alc260_modes
10813#define alc262_capture_source alc882_capture_source
10814
4e555fe5
KY
10815static hda_nid_t alc262_dmic_adc_nids[1] = {
10816 /* ADC0 */
10817 0x09
10818};
10819
10820static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
10821
9c7f852e
TI
10822static struct snd_kcontrol_new alc262_base_mixer[] = {
10823 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10824 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10825 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10826 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10827 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10828 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10829 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10830 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10831 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
10832 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10833 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 10834 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
10835 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
10836 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10837 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
10838 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10839 { } /* end */
10840};
10841
ce875f07
TI
10842/* update HP, line and mono-out pins according to the master switch */
10843static void alc262_hp_master_update(struct hda_codec *codec)
10844{
10845 struct alc_spec *spec = codec->spec;
10846 int val = spec->master_sw;
10847
10848 /* HP & line-out */
10849 snd_hda_codec_write_cache(codec, 0x1b, 0,
10850 AC_VERB_SET_PIN_WIDGET_CONTROL,
10851 val ? PIN_HP : 0);
10852 snd_hda_codec_write_cache(codec, 0x15, 0,
10853 AC_VERB_SET_PIN_WIDGET_CONTROL,
10854 val ? PIN_HP : 0);
10855 /* mono (speaker) depending on the HP jack sense */
10856 val = val && !spec->jack_present;
10857 snd_hda_codec_write_cache(codec, 0x16, 0,
10858 AC_VERB_SET_PIN_WIDGET_CONTROL,
10859 val ? PIN_OUT : 0);
10860}
10861
10862static void alc262_hp_bpc_automute(struct hda_codec *codec)
10863{
10864 struct alc_spec *spec = codec->spec;
864f92be
WF
10865
10866 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
10867 alc262_hp_master_update(codec);
10868}
10869
10870static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
10871{
10872 if ((res >> 26) != ALC880_HP_EVENT)
10873 return;
10874 alc262_hp_bpc_automute(codec);
10875}
10876
10877static void alc262_hp_wildwest_automute(struct hda_codec *codec)
10878{
10879 struct alc_spec *spec = codec->spec;
864f92be
WF
10880
10881 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
10882 alc262_hp_master_update(codec);
10883}
10884
10885static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
10886 unsigned int res)
10887{
10888 if ((res >> 26) != ALC880_HP_EVENT)
10889 return;
10890 alc262_hp_wildwest_automute(codec);
10891}
10892
b72519b5 10893#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
10894
10895static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10896 struct snd_ctl_elem_value *ucontrol)
10897{
10898 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10899 struct alc_spec *spec = codec->spec;
10900 int val = !!*ucontrol->value.integer.value;
10901
10902 if (val == spec->master_sw)
10903 return 0;
10904 spec->master_sw = val;
10905 alc262_hp_master_update(codec);
10906 return 1;
10907}
10908
b72519b5
TI
10909#define ALC262_HP_MASTER_SWITCH \
10910 { \
10911 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10912 .name = "Master Playback Switch", \
10913 .info = snd_ctl_boolean_mono_info, \
10914 .get = alc262_hp_master_sw_get, \
10915 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
10916 }, \
10917 { \
10918 .iface = NID_MAPPING, \
10919 .name = "Master Playback Switch", \
10920 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
10921 }
10922
5b0cb1d8 10923
9c7f852e 10924static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 10925 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
10926 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10927 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10928 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
10929 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10930 HDA_OUTPUT),
10931 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10932 HDA_OUTPUT),
9c7f852e
TI
10933 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10934 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10935 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
10936 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10937 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 10938 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
10939 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10940 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10941 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10942 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
10943 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
10944 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
10945 { } /* end */
10946};
10947
cd7509a4 10948static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 10949 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
10950 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10951 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10952 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10953 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
10954 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10955 HDA_OUTPUT),
10956 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10957 HDA_OUTPUT),
cd7509a4
KY
10958 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
10959 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 10960 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
10961 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10962 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10963 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10964 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
10965 { } /* end */
10966};
10967
10968static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
10969 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10970 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10971 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
10972 { } /* end */
10973};
10974
66d2a9d6 10975/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 10976static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
10977{
10978 struct alc_spec *spec = codec->spec;
66d2a9d6 10979
a9fd4f3f 10980 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 10981 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
10982}
10983
66d2a9d6 10984static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
10985 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10986 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
10987 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10988 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10989 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10990 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10991 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10992 { } /* end */
10993};
10994
10995static struct hda_verb alc262_hp_t5735_verbs[] = {
10996 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10997 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10998
10999 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11000 { }
11001};
11002
8c427226 11003static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11004 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11005 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11006 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11007 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11008 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11009 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11010 { } /* end */
11011};
11012
11013static struct hda_verb alc262_hp_rp5700_verbs[] = {
11014 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11015 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11016 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11017 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11018 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11019 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11020 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11021 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11022 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11023 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11024 {}
11025};
11026
11027static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11028 .num_items = 1,
11029 .items = {
11030 { "Line", 0x1 },
11031 },
11032};
11033
42171c17
TI
11034/* bind hp and internal speaker mute (with plug check) as master switch */
11035static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 11036{
42171c17
TI
11037 struct alc_spec *spec = codec->spec;
11038 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11039 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11040 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11041 unsigned int mute;
0724ea2a 11042
42171c17
TI
11043 /* HP */
11044 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11045 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11046 HDA_AMP_MUTE, mute);
11047 /* mute internal speaker per jack sense */
11048 if (spec->jack_present)
11049 mute = HDA_AMP_MUTE;
11050 if (line_nid)
11051 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11052 HDA_AMP_MUTE, mute);
11053 if (speaker_nid && speaker_nid != line_nid)
11054 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 11055 HDA_AMP_MUTE, mute);
42171c17
TI
11056}
11057
11058#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11059
11060static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11061 struct snd_ctl_elem_value *ucontrol)
11062{
11063 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11064 struct alc_spec *spec = codec->spec;
11065 int val = !!*ucontrol->value.integer.value;
11066
11067 if (val == spec->master_sw)
11068 return 0;
11069 spec->master_sw = val;
11070 alc262_hippo_master_update(codec);
11071 return 1;
11072}
11073
11074#define ALC262_HIPPO_MASTER_SWITCH \
11075 { \
11076 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11077 .name = "Master Playback Switch", \
11078 .info = snd_ctl_boolean_mono_info, \
11079 .get = alc262_hippo_master_sw_get, \
11080 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11081 }, \
11082 { \
11083 .iface = NID_MAPPING, \
11084 .name = "Master Playback Switch", \
11085 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11086 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11087 }
42171c17
TI
11088
11089static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11090 ALC262_HIPPO_MASTER_SWITCH,
11091 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11092 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11093 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11094 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11095 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11096 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11097 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11098 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11099 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11100 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11101 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11102 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11103 { } /* end */
11104};
11105
11106static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11107 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11108 ALC262_HIPPO_MASTER_SWITCH,
11109 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11110 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11111 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11112 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11113 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11114 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11115 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11116 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11117 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11118 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11119 { } /* end */
11120};
11121
11122/* mute/unmute internal speaker according to the hp jack and mute state */
11123static void alc262_hippo_automute(struct hda_codec *codec)
11124{
11125 struct alc_spec *spec = codec->spec;
11126 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 11127
864f92be 11128 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 11129 alc262_hippo_master_update(codec);
0724ea2a 11130}
5b31954e 11131
42171c17
TI
11132static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11133{
11134 if ((res >> 26) != ALC880_HP_EVENT)
11135 return;
11136 alc262_hippo_automute(codec);
11137}
11138
4f5d1706 11139static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11140{
11141 struct alc_spec *spec = codec->spec;
11142
11143 spec->autocfg.hp_pins[0] = 0x15;
11144 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11145}
11146
4f5d1706 11147static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11148{
11149 struct alc_spec *spec = codec->spec;
11150
11151 spec->autocfg.hp_pins[0] = 0x1b;
11152 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11153}
11154
11155
272a527c 11156static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11157 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11158 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11159 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11160 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11161 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11162 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11163 { } /* end */
11164};
11165
83c34218 11166static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11167 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11168 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11169 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11170 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11171 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11172 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11173 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11174 { } /* end */
11175};
272a527c 11176
ba340e82
TV
11177static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11178 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11179 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11180 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11181 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11182 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11183 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11184 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11185 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11186 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11187 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11188 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11189 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11190 { } /* end */
11191};
11192
11193static struct hda_verb alc262_tyan_verbs[] = {
11194 /* Headphone automute */
11195 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11196 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11197 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11198
11199 /* P11 AUX_IN, white 4-pin connector */
11200 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11201 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11202 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11203 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11204
11205 {}
11206};
11207
11208/* unsolicited event for HP jack sensing */
4f5d1706 11209static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11210{
a9fd4f3f 11211 struct alc_spec *spec = codec->spec;
ba340e82 11212
a9fd4f3f
TI
11213 spec->autocfg.hp_pins[0] = 0x1b;
11214 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
11215}
11216
ba340e82 11217
9c7f852e
TI
11218#define alc262_capture_mixer alc882_capture_mixer
11219#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11220
11221/*
11222 * generic initialization of ADC, input mixers and output mixers
11223 */
11224static struct hda_verb alc262_init_verbs[] = {
11225 /*
11226 * Unmute ADC0-2 and set the default input to mic-in
11227 */
11228 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11229 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11230 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11231 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11232 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11233 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11234
cb53c626 11235 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11236 * mixer widget
f12ab1e0
TI
11237 * Note: PASD motherboards uses the Line In 2 as the input for
11238 * front panel mic (mic 2)
9c7f852e
TI
11239 */
11240 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11241 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11242 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11243 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11244 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11245 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11246
11247 /*
df694daa
KY
11248 * Set up output mixers (0x0c - 0x0e)
11249 */
11250 /* set vol=0 to output mixers */
11251 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11252 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11253 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11254 /* set up input amps for analog loopback */
11255 /* Amp Indices: DAC = 0, mixer = 1 */
11256 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11257 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11258 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11259 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11260 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11261 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11262
11263 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11264 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11265 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11266 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11267 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11268 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11269
11270 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11271 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11272 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11273 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11274 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11275
df694daa
KY
11276 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11277 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11278
df694daa
KY
11279 /* FIXME: use matrix-type input source selection */
11280 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11281 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11282 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11283 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11284 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11285 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11286 /* Input mixer2 */
11287 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11288 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11289 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11290 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11291 /* Input mixer3 */
11292 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11293 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11294 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11295 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11296
11297 { }
11298};
1da177e4 11299
4e555fe5
KY
11300static struct hda_verb alc262_eapd_verbs[] = {
11301 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11302 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11303 { }
11304};
11305
ccc656ce
KY
11306static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11307 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11308 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11309 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11310
11311 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11312 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11313 {}
11314};
11315
272a527c
KY
11316static struct hda_verb alc262_sony_unsol_verbs[] = {
11317 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11318 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11319 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11320
11321 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11322 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11323 {}
272a527c
KY
11324};
11325
4e555fe5
KY
11326static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11327 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11328 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11329 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11330 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11331 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11332 { } /* end */
11333};
11334
11335static struct hda_verb alc262_toshiba_s06_verbs[] = {
11336 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11337 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11338 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11339 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11340 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11341 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11342 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11343 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11344 {}
11345};
11346
4f5d1706 11347static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11348{
a9fd4f3f
TI
11349 struct alc_spec *spec = codec->spec;
11350
11351 spec->autocfg.hp_pins[0] = 0x15;
11352 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11353 spec->ext_mic.pin = 0x18;
11354 spec->ext_mic.mux_idx = 0;
11355 spec->int_mic.pin = 0x12;
11356 spec->int_mic.mux_idx = 9;
11357 spec->auto_mic = 1;
4e555fe5
KY
11358}
11359
e8f9ae2a
PT
11360/*
11361 * nec model
11362 * 0x15 = headphone
11363 * 0x16 = internal speaker
11364 * 0x18 = external mic
11365 */
11366
11367static struct snd_kcontrol_new alc262_nec_mixer[] = {
11368 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11369 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11370
11371 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11372 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11373 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11374
11375 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11376 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11377 { } /* end */
11378};
11379
11380static struct hda_verb alc262_nec_verbs[] = {
11381 /* Unmute Speaker */
11382 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11383
11384 /* Headphone */
11385 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11386 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11387
11388 /* External mic to headphone */
11389 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11390 /* External mic to speaker */
11391 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11392 {}
11393};
11394
834be88d
TI
11395/*
11396 * fujitsu model
5d9fab2d
TV
11397 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11398 * 0x1b = port replicator headphone out
834be88d
TI
11399 */
11400
11401#define ALC_HP_EVENT 0x37
11402
11403static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11404 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11405 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11406 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11407 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11408 {}
11409};
11410
0e31daf7
J
11411static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11412 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11413 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11414 {}
11415};
11416
e2595322
DC
11417static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11418 /* Front Mic pin: input vref at 50% */
11419 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11420 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11421 {}
11422};
11423
834be88d 11424static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11425 .num_items = 3,
834be88d
TI
11426 .items = {
11427 { "Mic", 0x0 },
39d3ed38 11428 { "Int Mic", 0x1 },
834be88d
TI
11429 { "CD", 0x4 },
11430 },
11431};
11432
9c7f852e
TI
11433static struct hda_input_mux alc262_HP_capture_source = {
11434 .num_items = 5,
11435 .items = {
11436 { "Mic", 0x0 },
accbe498 11437 { "Front Mic", 0x1 },
9c7f852e
TI
11438 { "Line", 0x2 },
11439 { "CD", 0x4 },
11440 { "AUX IN", 0x6 },
11441 },
11442};
11443
accbe498 11444static struct hda_input_mux alc262_HP_D7000_capture_source = {
11445 .num_items = 4,
11446 .items = {
11447 { "Mic", 0x0 },
11448 { "Front Mic", 0x2 },
11449 { "Line", 0x1 },
11450 { "CD", 0x4 },
11451 },
11452};
11453
ebc7a406 11454/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11455static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11456{
11457 struct alc_spec *spec = codec->spec;
11458 unsigned int mute;
11459
f12ab1e0 11460 if (force || !spec->sense_updated) {
864f92be
WF
11461 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11462 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11463 spec->sense_updated = 1;
11464 }
ebc7a406
TI
11465 /* unmute internal speaker only if both HPs are unplugged and
11466 * master switch is on
11467 */
11468 if (spec->jack_present)
11469 mute = HDA_AMP_MUTE;
11470 else
834be88d 11471 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11472 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11473 HDA_AMP_MUTE, mute);
834be88d
TI
11474}
11475
11476/* unsolicited event for HP jack sensing */
11477static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11478 unsigned int res)
11479{
11480 if ((res >> 26) != ALC_HP_EVENT)
11481 return;
11482 alc262_fujitsu_automute(codec, 1);
11483}
11484
ebc7a406
TI
11485static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11486{
11487 alc262_fujitsu_automute(codec, 1);
11488}
11489
834be88d 11490/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11491static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11492 .ops = &snd_hda_bind_vol,
11493 .values = {
11494 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11495 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11496 0
11497 },
11498};
834be88d 11499
0e31daf7
J
11500/* mute/unmute internal speaker according to the hp jack and mute state */
11501static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11502{
11503 struct alc_spec *spec = codec->spec;
11504 unsigned int mute;
11505
11506 if (force || !spec->sense_updated) {
864f92be 11507 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11508 spec->sense_updated = 1;
11509 }
11510 if (spec->jack_present) {
11511 /* mute internal speaker */
11512 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11513 HDA_AMP_MUTE, HDA_AMP_MUTE);
11514 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11515 HDA_AMP_MUTE, HDA_AMP_MUTE);
11516 } else {
11517 /* unmute internal speaker if necessary */
11518 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11519 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11520 HDA_AMP_MUTE, mute);
11521 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11522 HDA_AMP_MUTE, mute);
11523 }
11524}
11525
11526/* unsolicited event for HP jack sensing */
11527static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11528 unsigned int res)
11529{
11530 if ((res >> 26) != ALC_HP_EVENT)
11531 return;
11532 alc262_lenovo_3000_automute(codec, 1);
11533}
11534
8de56b7d
TI
11535static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11536 int dir, int idx, long *valp)
11537{
11538 int i, change = 0;
11539
11540 for (i = 0; i < 2; i++, valp++)
11541 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11542 HDA_AMP_MUTE,
11543 *valp ? 0 : HDA_AMP_MUTE);
11544 return change;
11545}
11546
834be88d
TI
11547/* bind hp and internal speaker mute (with plug check) */
11548static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11549 struct snd_ctl_elem_value *ucontrol)
11550{
11551 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11552 long *valp = ucontrol->value.integer.value;
11553 int change;
11554
8de56b7d
TI
11555 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11556 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11557 if (change)
11558 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11559 return change;
11560}
11561
11562static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11563 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11564 {
11565 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11566 .name = "Master Playback Switch",
5e26dfd0 11567 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11568 .info = snd_hda_mixer_amp_switch_info,
11569 .get = snd_hda_mixer_amp_switch_get,
11570 .put = alc262_fujitsu_master_sw_put,
11571 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11572 },
5b0cb1d8
JK
11573 {
11574 .iface = NID_MAPPING,
11575 .name = "Master Playback Switch",
11576 .private_value = 0x1b,
11577 },
834be88d
TI
11578 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11579 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11580 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11581 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11582 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
11583 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11584 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11585 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11586 { } /* end */
11587};
11588
0e31daf7
J
11589/* bind hp and internal speaker mute (with plug check) */
11590static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11591 struct snd_ctl_elem_value *ucontrol)
11592{
11593 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11594 long *valp = ucontrol->value.integer.value;
11595 int change;
11596
8de56b7d 11597 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11598 if (change)
11599 alc262_lenovo_3000_automute(codec, 0);
11600 return change;
11601}
11602
11603static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11604 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11605 {
11606 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11607 .name = "Master Playback Switch",
5e26dfd0 11608 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11609 .info = snd_hda_mixer_amp_switch_info,
11610 .get = snd_hda_mixer_amp_switch_get,
11611 .put = alc262_lenovo_3000_master_sw_put,
11612 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11613 },
11614 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11615 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11616 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11617 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11618 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11619 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11620 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11621 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11622 { } /* end */
11623};
11624
9f99a638
HM
11625static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11626 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11627 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11628 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11629 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11630 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11631 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11632 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11633 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11634 { } /* end */
11635};
11636
304dcaac
TI
11637/* additional init verbs for Benq laptops */
11638static struct hda_verb alc262_EAPD_verbs[] = {
11639 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11640 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11641 {}
11642};
11643
83c34218
KY
11644static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11645 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11646 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11647
11648 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11649 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11650 {}
11651};
11652
f651b50b
TD
11653/* Samsung Q1 Ultra Vista model setup */
11654static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11655 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11656 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11657 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11658 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11659 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 11660 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
11661 { } /* end */
11662};
11663
11664static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11665 /* output mixer */
11666 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11667 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11668 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11669 /* speaker */
11670 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11671 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11672 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11673 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11674 /* HP */
f651b50b 11675 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11676 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11677 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11678 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11679 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11680 /* internal mic */
11681 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11682 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11683 /* ADC, choose mic */
11684 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11685 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11686 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11687 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11688 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11689 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11690 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11691 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11692 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11693 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
11694 {}
11695};
11696
f651b50b
TD
11697/* mute/unmute internal speaker according to the hp jack and mute state */
11698static void alc262_ultra_automute(struct hda_codec *codec)
11699{
11700 struct alc_spec *spec = codec->spec;
11701 unsigned int mute;
f651b50b 11702
bb9f76cd
TI
11703 mute = 0;
11704 /* auto-mute only when HP is used as HP */
11705 if (!spec->cur_mux[0]) {
864f92be 11706 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
11707 if (spec->jack_present)
11708 mute = HDA_AMP_MUTE;
f651b50b 11709 }
bb9f76cd
TI
11710 /* mute/unmute internal speaker */
11711 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11712 HDA_AMP_MUTE, mute);
11713 /* mute/unmute HP */
11714 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11715 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
11716}
11717
11718/* unsolicited event for HP jack sensing */
11719static void alc262_ultra_unsol_event(struct hda_codec *codec,
11720 unsigned int res)
11721{
11722 if ((res >> 26) != ALC880_HP_EVENT)
11723 return;
11724 alc262_ultra_automute(codec);
11725}
11726
bb9f76cd
TI
11727static struct hda_input_mux alc262_ultra_capture_source = {
11728 .num_items = 2,
11729 .items = {
11730 { "Mic", 0x1 },
11731 { "Headphone", 0x7 },
11732 },
11733};
11734
11735static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11736 struct snd_ctl_elem_value *ucontrol)
11737{
11738 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11739 struct alc_spec *spec = codec->spec;
11740 int ret;
11741
54cbc9ab 11742 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
11743 if (!ret)
11744 return 0;
11745 /* reprogram the HP pin as mic or HP according to the input source */
11746 snd_hda_codec_write_cache(codec, 0x15, 0,
11747 AC_VERB_SET_PIN_WIDGET_CONTROL,
11748 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11749 alc262_ultra_automute(codec); /* mute/unmute HP */
11750 return ret;
11751}
11752
11753static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11754 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11755 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11756 {
11757 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11758 .name = "Capture Source",
54cbc9ab
TI
11759 .info = alc_mux_enum_info,
11760 .get = alc_mux_enum_get,
bb9f76cd
TI
11761 .put = alc262_ultra_mux_enum_put,
11762 },
5b0cb1d8
JK
11763 {
11764 .iface = NID_MAPPING,
11765 .name = "Capture Source",
11766 .private_value = 0x15,
11767 },
bb9f76cd
TI
11768 { } /* end */
11769};
11770
c3fc1f50
TI
11771/* We use two mixers depending on the output pin; 0x16 is a mono output
11772 * and thus it's bound with a different mixer.
11773 * This function returns which mixer amp should be used.
11774 */
11775static int alc262_check_volbit(hda_nid_t nid)
11776{
11777 if (!nid)
11778 return 0;
11779 else if (nid == 0x16)
11780 return 2;
11781 else
11782 return 1;
11783}
11784
11785static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
11786 const char *pfx, int *vbits)
11787{
c3fc1f50
TI
11788 unsigned long val;
11789 int vbit;
11790
11791 vbit = alc262_check_volbit(nid);
11792 if (!vbit)
11793 return 0;
11794 if (*vbits & vbit) /* a volume control for this mixer already there */
11795 return 0;
11796 *vbits |= vbit;
c3fc1f50
TI
11797 if (vbit == 2)
11798 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11799 else
11800 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
0afe5f89 11801 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val);
c3fc1f50
TI
11802}
11803
11804static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
11805 const char *pfx)
11806{
c3fc1f50
TI
11807 unsigned long val;
11808
11809 if (!nid)
11810 return 0;
c3fc1f50
TI
11811 if (nid == 0x16)
11812 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11813 else
11814 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
0afe5f89 11815 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
c3fc1f50
TI
11816}
11817
df694daa 11818/* add playback controls from the parsed DAC table */
f12ab1e0
TI
11819static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11820 const struct auto_pin_cfg *cfg)
df694daa 11821{
c3fc1f50
TI
11822 const char *pfx;
11823 int vbits;
df694daa
KY
11824 int err;
11825
11826 spec->multiout.num_dacs = 1; /* only use one dac */
11827 spec->multiout.dac_nids = spec->private_dac_nids;
11828 spec->multiout.dac_nids[0] = 2;
11829
c3fc1f50
TI
11830 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
11831 pfx = "Master";
11832 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11833 pfx = "Speaker";
11834 else
11835 pfx = "Front";
11836 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx);
11837 if (err < 0)
11838 return err;
11839 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker");
11840 if (err < 0)
11841 return err;
11842 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone");
11843 if (err < 0)
11844 return err;
df694daa 11845
c3fc1f50
TI
11846 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
11847 alc262_check_volbit(cfg->speaker_pins[0]) |
11848 alc262_check_volbit(cfg->hp_pins[0]);
11849 if (vbits == 1 || vbits == 2)
11850 pfx = "Master"; /* only one mixer is used */
11851 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11852 pfx = "Speaker";
11853 else
11854 pfx = "Front";
11855 vbits = 0;
11856 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits);
11857 if (err < 0)
11858 return err;
11859 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker",
11860 &vbits);
11861 if (err < 0)
11862 return err;
11863 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone",
11864 &vbits);
11865 if (err < 0)
11866 return err;
f12ab1e0 11867 return 0;
df694daa
KY
11868}
11869
05f5f477 11870#define alc262_auto_create_input_ctls \
eaa9b3a7 11871 alc882_auto_create_input_ctls
df694daa
KY
11872
11873/*
11874 * generic initialization of ADC, input mixers and output mixers
11875 */
11876static struct hda_verb alc262_volume_init_verbs[] = {
11877 /*
11878 * Unmute ADC0-2 and set the default input to mic-in
11879 */
11880 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11881 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11882 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11883 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11884 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11885 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11886
cb53c626 11887 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 11888 * mixer widget
f12ab1e0
TI
11889 * Note: PASD motherboards uses the Line In 2 as the input for
11890 * front panel mic (mic 2)
df694daa
KY
11891 */
11892 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11893 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11894 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11895 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11896 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11897 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
11898
11899 /*
11900 * Set up output mixers (0x0c - 0x0f)
11901 */
11902 /* set vol=0 to output mixers */
11903 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11904 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11905 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 11906
df694daa
KY
11907 /* set up input amps for analog loopback */
11908 /* Amp Indices: DAC = 0, mixer = 1 */
11909 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11910 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11911 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11912 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11913 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11914 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11915
11916 /* FIXME: use matrix-type input source selection */
11917 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11918 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11919 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11920 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11921 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11922 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11923 /* Input mixer2 */
11924 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11925 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11926 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11927 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11928 /* Input mixer3 */
11929 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11930 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11931 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11932 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11933
11934 { }
11935};
11936
9c7f852e
TI
11937static struct hda_verb alc262_HP_BPC_init_verbs[] = {
11938 /*
11939 * Unmute ADC0-2 and set the default input to mic-in
11940 */
11941 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11942 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11943 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11944 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11945 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11946 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11947
cb53c626 11948 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11949 * mixer widget
f12ab1e0
TI
11950 * Note: PASD motherboards uses the Line In 2 as the input for
11951 * front panel mic (mic 2)
9c7f852e
TI
11952 */
11953 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11954 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11955 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11956 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11957 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11958 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11959 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11960 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 11961
9c7f852e
TI
11962 /*
11963 * Set up output mixers (0x0c - 0x0e)
11964 */
11965 /* set vol=0 to output mixers */
11966 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11967 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11968 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11969
11970 /* set up input amps for analog loopback */
11971 /* Amp Indices: DAC = 0, mixer = 1 */
11972 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11973 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11974 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11975 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11976 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11977 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11978
ce875f07 11979 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
11980 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11981 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11982
11983 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11984 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11985
11986 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11987 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11988
11989 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11990 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11991 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11992 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11993 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11994
0e4835c1 11995 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
11996 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11997 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 11998 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
11999 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12000 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12001
12002
12003 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12004 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12005 /* Input mixer1: only unmute Mic */
9c7f852e 12006 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12007 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12008 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12009 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12010 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12011 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12012 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12013 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12014 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12015 /* Input mixer2 */
12016 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12017 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12018 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12019 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12020 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12021 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12022 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12023 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12024 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12025 /* Input mixer3 */
12026 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12027 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12028 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12029 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12030 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12031 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12032 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12033 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12034 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12035
ce875f07
TI
12036 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12037
9c7f852e
TI
12038 { }
12039};
12040
cd7509a4
KY
12041static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12042 /*
12043 * Unmute ADC0-2 and set the default input to mic-in
12044 */
12045 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12046 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12047 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12048 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12049 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12050 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12051
cb53c626 12052 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12053 * mixer widget
12054 * Note: PASD motherboards uses the Line In 2 as the input for front
12055 * panel mic (mic 2)
12056 */
12057 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12058 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12059 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12060 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12061 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12062 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12063 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12064 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12065 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12066 /*
12067 * Set up output mixers (0x0c - 0x0e)
12068 */
12069 /* set vol=0 to output mixers */
12070 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12071 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12072 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12073
12074 /* set up input amps for analog loopback */
12075 /* Amp Indices: DAC = 0, mixer = 1 */
12076 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12077 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12078 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12079 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12080 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12081 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12082
12083
12084 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12085 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12086 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12087 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12088 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12089 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12090 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12091
12092 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12093 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12094
12095 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12096 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12097
12098 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12099 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12100 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12101 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12102 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12103 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12104
12105 /* FIXME: use matrix-type input source selection */
12106 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12107 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12108 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12109 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12110 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12111 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12112 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12113 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12114 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12115 /* Input mixer2 */
12116 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12117 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12118 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12119 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12120 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12121 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12122 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12123 /* Input mixer3 */
12124 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12125 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12126 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12127 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12128 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12129 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12130 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12131
ce875f07
TI
12132 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12133
cd7509a4
KY
12134 { }
12135};
12136
9f99a638
HM
12137static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12138
12139 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12140 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12141 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12142
12143 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12144 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12145 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12146 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12147
12148 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12149 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12150 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12151 {}
12152};
12153
12154
cb53c626
TI
12155#ifdef CONFIG_SND_HDA_POWER_SAVE
12156#define alc262_loopbacks alc880_loopbacks
12157#endif
12158
def319f9 12159/* pcm configuration: identical with ALC880 */
df694daa
KY
12160#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12161#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12162#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12163#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12164
12165/*
12166 * BIOS auto configuration
12167 */
12168static int alc262_parse_auto_config(struct hda_codec *codec)
12169{
12170 struct alc_spec *spec = codec->spec;
12171 int err;
12172 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12173
f12ab1e0
TI
12174 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12175 alc262_ignore);
12176 if (err < 0)
df694daa 12177 return err;
e64f14f4 12178 if (!spec->autocfg.line_outs) {
0852d7a6 12179 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12180 spec->multiout.max_channels = 2;
12181 spec->no_analog = 1;
12182 goto dig_only;
12183 }
df694daa 12184 return 0; /* can't find valid BIOS pin config */
e64f14f4 12185 }
f12ab1e0
TI
12186 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12187 if (err < 0)
12188 return err;
05f5f477 12189 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12190 if (err < 0)
df694daa
KY
12191 return err;
12192
12193 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12194
e64f14f4 12195 dig_only:
757899ac 12196 alc_auto_parse_digital(codec);
df694daa 12197
603c4019 12198 if (spec->kctls.list)
d88897ea 12199 add_mixer(spec, spec->kctls.list);
df694daa 12200
d88897ea 12201 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12202 spec->num_mux_defs = 1;
61b9b9b1 12203 spec->input_mux = &spec->private_imux[0];
df694daa 12204
776e184e
TI
12205 err = alc_auto_add_mic_boost(codec);
12206 if (err < 0)
12207 return err;
12208
6227cdce 12209 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12210
df694daa
KY
12211 return 1;
12212}
12213
12214#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12215#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12216#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12217#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12218
12219
12220/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12221static void alc262_auto_init(struct hda_codec *codec)
df694daa 12222{
f6c7e546 12223 struct alc_spec *spec = codec->spec;
df694daa
KY
12224 alc262_auto_init_multi_out(codec);
12225 alc262_auto_init_hp_out(codec);
12226 alc262_auto_init_analog_input(codec);
f511b01c 12227 alc262_auto_init_input_src(codec);
757899ac 12228 alc_auto_init_digital(codec);
f6c7e546 12229 if (spec->unsol_event)
7fb0d78f 12230 alc_inithook(codec);
df694daa
KY
12231}
12232
12233/*
12234 * configuration and preset
12235 */
f5fcc13c
TI
12236static const char *alc262_models[ALC262_MODEL_LAST] = {
12237 [ALC262_BASIC] = "basic",
12238 [ALC262_HIPPO] = "hippo",
12239 [ALC262_HIPPO_1] = "hippo_1",
12240 [ALC262_FUJITSU] = "fujitsu",
12241 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12242 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12243 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12244 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12245 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12246 [ALC262_BENQ_T31] = "benq-t31",
12247 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12248 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12249 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12250 [ALC262_ULTRA] = "ultra",
0e31daf7 12251 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12252 [ALC262_NEC] = "nec",
ba340e82 12253 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12254 [ALC262_AUTO] = "auto",
12255};
12256
12257static struct snd_pci_quirk alc262_cfg_tbl[] = {
12258 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12259 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12260 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12261 ALC262_HP_BPC),
12262 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12263 ALC262_HP_BPC),
53eff7e1
TI
12264 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12265 ALC262_HP_BPC),
cd7509a4 12266 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12267 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12268 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12269 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12270 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12271 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12272 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12273 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12274 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12275 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12276 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12277 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12278 ALC262_HP_TC_T5735),
8c427226 12279 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12280 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12281 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12282 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12283 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12284 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12285 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12286 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12287#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12288 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12289 ALC262_SONY_ASSAMD),
c5b5165c 12290#endif
36ca6e13 12291 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12292 ALC262_TOSHIBA_RX1),
80ffe869 12293 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12294 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12295 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12296 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12297 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12298 ALC262_ULTRA),
3e420e78 12299 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12300 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12301 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12302 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12303 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12304 {}
12305};
12306
12307static struct alc_config_preset alc262_presets[] = {
12308 [ALC262_BASIC] = {
12309 .mixers = { alc262_base_mixer },
12310 .init_verbs = { alc262_init_verbs },
12311 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12312 .dac_nids = alc262_dac_nids,
12313 .hp_nid = 0x03,
12314 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12315 .channel_mode = alc262_modes,
a3bcba38 12316 .input_mux = &alc262_capture_source,
df694daa 12317 },
ccc656ce 12318 [ALC262_HIPPO] = {
42171c17 12319 .mixers = { alc262_hippo_mixer },
6732bd0d 12320 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12321 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12322 .dac_nids = alc262_dac_nids,
12323 .hp_nid = 0x03,
12324 .dig_out_nid = ALC262_DIGOUT_NID,
12325 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12326 .channel_mode = alc262_modes,
12327 .input_mux = &alc262_capture_source,
12328 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12329 .setup = alc262_hippo_setup,
12330 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12331 },
12332 [ALC262_HIPPO_1] = {
12333 .mixers = { alc262_hippo1_mixer },
12334 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12335 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12336 .dac_nids = alc262_dac_nids,
12337 .hp_nid = 0x02,
12338 .dig_out_nid = ALC262_DIGOUT_NID,
12339 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12340 .channel_mode = alc262_modes,
12341 .input_mux = &alc262_capture_source,
42171c17 12342 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12343 .setup = alc262_hippo1_setup,
12344 .init_hook = alc262_hippo_automute,
ccc656ce 12345 },
834be88d
TI
12346 [ALC262_FUJITSU] = {
12347 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12348 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12349 alc262_fujitsu_unsol_verbs },
834be88d
TI
12350 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12351 .dac_nids = alc262_dac_nids,
12352 .hp_nid = 0x03,
12353 .dig_out_nid = ALC262_DIGOUT_NID,
12354 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12355 .channel_mode = alc262_modes,
12356 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12357 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12358 .init_hook = alc262_fujitsu_init_hook,
834be88d 12359 },
9c7f852e
TI
12360 [ALC262_HP_BPC] = {
12361 .mixers = { alc262_HP_BPC_mixer },
12362 .init_verbs = { alc262_HP_BPC_init_verbs },
12363 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12364 .dac_nids = alc262_dac_nids,
12365 .hp_nid = 0x03,
12366 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12367 .channel_mode = alc262_modes,
12368 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12369 .unsol_event = alc262_hp_bpc_unsol_event,
12370 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12371 },
cd7509a4
KY
12372 [ALC262_HP_BPC_D7000_WF] = {
12373 .mixers = { alc262_HP_BPC_WildWest_mixer },
12374 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12375 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12376 .dac_nids = alc262_dac_nids,
12377 .hp_nid = 0x03,
12378 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12379 .channel_mode = alc262_modes,
accbe498 12380 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12381 .unsol_event = alc262_hp_wildwest_unsol_event,
12382 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12383 },
cd7509a4
KY
12384 [ALC262_HP_BPC_D7000_WL] = {
12385 .mixers = { alc262_HP_BPC_WildWest_mixer,
12386 alc262_HP_BPC_WildWest_option_mixer },
12387 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12388 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12389 .dac_nids = alc262_dac_nids,
12390 .hp_nid = 0x03,
12391 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12392 .channel_mode = alc262_modes,
accbe498 12393 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12394 .unsol_event = alc262_hp_wildwest_unsol_event,
12395 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12396 },
66d2a9d6
KY
12397 [ALC262_HP_TC_T5735] = {
12398 .mixers = { alc262_hp_t5735_mixer },
12399 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12400 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12401 .dac_nids = alc262_dac_nids,
12402 .hp_nid = 0x03,
12403 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12404 .channel_mode = alc262_modes,
12405 .input_mux = &alc262_capture_source,
dc99be47 12406 .unsol_event = alc_sku_unsol_event,
4f5d1706 12407 .setup = alc262_hp_t5735_setup,
dc99be47 12408 .init_hook = alc_inithook,
8c427226
KY
12409 },
12410 [ALC262_HP_RP5700] = {
12411 .mixers = { alc262_hp_rp5700_mixer },
12412 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12413 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12414 .dac_nids = alc262_dac_nids,
12415 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12416 .channel_mode = alc262_modes,
12417 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12418 },
304dcaac
TI
12419 [ALC262_BENQ_ED8] = {
12420 .mixers = { alc262_base_mixer },
12421 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12422 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12423 .dac_nids = alc262_dac_nids,
12424 .hp_nid = 0x03,
12425 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12426 .channel_mode = alc262_modes,
12427 .input_mux = &alc262_capture_source,
f12ab1e0 12428 },
272a527c
KY
12429 [ALC262_SONY_ASSAMD] = {
12430 .mixers = { alc262_sony_mixer },
12431 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12432 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12433 .dac_nids = alc262_dac_nids,
12434 .hp_nid = 0x02,
12435 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12436 .channel_mode = alc262_modes,
12437 .input_mux = &alc262_capture_source,
12438 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12439 .setup = alc262_hippo_setup,
12440 .init_hook = alc262_hippo_automute,
83c34218
KY
12441 },
12442 [ALC262_BENQ_T31] = {
12443 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12444 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12445 alc_hp15_unsol_verbs },
83c34218
KY
12446 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12447 .dac_nids = alc262_dac_nids,
12448 .hp_nid = 0x03,
12449 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12450 .channel_mode = alc262_modes,
12451 .input_mux = &alc262_capture_source,
12452 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12453 .setup = alc262_hippo_setup,
12454 .init_hook = alc262_hippo_automute,
ea1fb29a 12455 },
f651b50b 12456 [ALC262_ULTRA] = {
f9e336f6
TI
12457 .mixers = { alc262_ultra_mixer },
12458 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12459 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12460 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12461 .dac_nids = alc262_dac_nids,
f651b50b
TD
12462 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12463 .channel_mode = alc262_modes,
12464 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12465 .adc_nids = alc262_adc_nids, /* ADC0 */
12466 .capsrc_nids = alc262_capsrc_nids,
12467 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12468 .unsol_event = alc262_ultra_unsol_event,
12469 .init_hook = alc262_ultra_automute,
12470 },
0e31daf7
J
12471 [ALC262_LENOVO_3000] = {
12472 .mixers = { alc262_lenovo_3000_mixer },
12473 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12474 alc262_lenovo_3000_unsol_verbs,
12475 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12476 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12477 .dac_nids = alc262_dac_nids,
12478 .hp_nid = 0x03,
12479 .dig_out_nid = ALC262_DIGOUT_NID,
12480 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12481 .channel_mode = alc262_modes,
12482 .input_mux = &alc262_fujitsu_capture_source,
12483 .unsol_event = alc262_lenovo_3000_unsol_event,
12484 },
e8f9ae2a
PT
12485 [ALC262_NEC] = {
12486 .mixers = { alc262_nec_mixer },
12487 .init_verbs = { alc262_nec_verbs },
12488 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12489 .dac_nids = alc262_dac_nids,
12490 .hp_nid = 0x03,
12491 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12492 .channel_mode = alc262_modes,
12493 .input_mux = &alc262_capture_source,
12494 },
4e555fe5
KY
12495 [ALC262_TOSHIBA_S06] = {
12496 .mixers = { alc262_toshiba_s06_mixer },
12497 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12498 alc262_eapd_verbs },
12499 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12500 .capsrc_nids = alc262_dmic_capsrc_nids,
12501 .dac_nids = alc262_dac_nids,
12502 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12503 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12504 .dig_out_nid = ALC262_DIGOUT_NID,
12505 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12506 .channel_mode = alc262_modes,
4f5d1706
TI
12507 .unsol_event = alc_sku_unsol_event,
12508 .setup = alc262_toshiba_s06_setup,
12509 .init_hook = alc_inithook,
4e555fe5 12510 },
9f99a638
HM
12511 [ALC262_TOSHIBA_RX1] = {
12512 .mixers = { alc262_toshiba_rx1_mixer },
12513 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12514 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12515 .dac_nids = alc262_dac_nids,
12516 .hp_nid = 0x03,
12517 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12518 .channel_mode = alc262_modes,
12519 .input_mux = &alc262_capture_source,
12520 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12521 .setup = alc262_hippo_setup,
12522 .init_hook = alc262_hippo_automute,
9f99a638 12523 },
ba340e82
TV
12524 [ALC262_TYAN] = {
12525 .mixers = { alc262_tyan_mixer },
12526 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12527 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12528 .dac_nids = alc262_dac_nids,
12529 .hp_nid = 0x02,
12530 .dig_out_nid = ALC262_DIGOUT_NID,
12531 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12532 .channel_mode = alc262_modes,
12533 .input_mux = &alc262_capture_source,
a9fd4f3f 12534 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12535 .setup = alc262_tyan_setup,
12536 .init_hook = alc_automute_amp,
ba340e82 12537 },
df694daa
KY
12538};
12539
12540static int patch_alc262(struct hda_codec *codec)
12541{
12542 struct alc_spec *spec;
12543 int board_config;
12544 int err;
12545
dc041e0b 12546 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12547 if (spec == NULL)
12548 return -ENOMEM;
12549
12550 codec->spec = spec;
12551#if 0
f12ab1e0
TI
12552 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12553 * under-run
12554 */
df694daa
KY
12555 {
12556 int tmp;
12557 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12558 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12559 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12560 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12561 }
12562#endif
da00c244 12563 alc_auto_parse_customize_define(codec);
df694daa 12564
2c3bf9ab
TI
12565 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12566
f5fcc13c
TI
12567 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12568 alc262_models,
12569 alc262_cfg_tbl);
cd7509a4 12570
f5fcc13c 12571 if (board_config < 0) {
9a11f1aa
TI
12572 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12573 codec->chip_name);
df694daa
KY
12574 board_config = ALC262_AUTO;
12575 }
12576
12577 if (board_config == ALC262_AUTO) {
12578 /* automatic parse from the BIOS config */
12579 err = alc262_parse_auto_config(codec);
12580 if (err < 0) {
12581 alc_free(codec);
12582 return err;
f12ab1e0 12583 } else if (!err) {
9c7f852e
TI
12584 printk(KERN_INFO
12585 "hda_codec: Cannot set up configuration "
12586 "from BIOS. Using base mode...\n");
df694daa
KY
12587 board_config = ALC262_BASIC;
12588 }
12589 }
12590
dc1eae25 12591 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12592 err = snd_hda_attach_beep_device(codec, 0x1);
12593 if (err < 0) {
12594 alc_free(codec);
12595 return err;
12596 }
680cd536
KK
12597 }
12598
df694daa 12599 if (board_config != ALC262_AUTO)
e9c364c0 12600 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12601
df694daa
KY
12602 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12603 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12604
df694daa
KY
12605 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12606 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12607
f12ab1e0 12608 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12609 int i;
12610 /* check whether the digital-mic has to be supported */
12611 for (i = 0; i < spec->input_mux->num_items; i++) {
12612 if (spec->input_mux->items[i].index >= 9)
12613 break;
12614 }
12615 if (i < spec->input_mux->num_items) {
12616 /* use only ADC0 */
12617 spec->adc_nids = alc262_dmic_adc_nids;
12618 spec->num_adc_nids = 1;
12619 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12620 } else {
8c927b4a
TI
12621 /* all analog inputs */
12622 /* check whether NID 0x07 is valid */
12623 unsigned int wcap = get_wcaps(codec, 0x07);
12624
12625 /* get type */
a22d543a 12626 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12627 if (wcap != AC_WID_AUD_IN) {
12628 spec->adc_nids = alc262_adc_nids_alt;
12629 spec->num_adc_nids =
12630 ARRAY_SIZE(alc262_adc_nids_alt);
12631 spec->capsrc_nids = alc262_capsrc_nids_alt;
12632 } else {
12633 spec->adc_nids = alc262_adc_nids;
12634 spec->num_adc_nids =
12635 ARRAY_SIZE(alc262_adc_nids);
12636 spec->capsrc_nids = alc262_capsrc_nids;
12637 }
df694daa
KY
12638 }
12639 }
e64f14f4 12640 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12641 set_capture_mixer(codec);
dc1eae25 12642 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 12643 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12644
2134ea4f
TI
12645 spec->vmaster_nid = 0x0c;
12646
df694daa
KY
12647 codec->patch_ops = alc_patch_ops;
12648 if (board_config == ALC262_AUTO)
ae6b813a 12649 spec->init_hook = alc262_auto_init;
cb53c626
TI
12650#ifdef CONFIG_SND_HDA_POWER_SAVE
12651 if (!spec->loopback.amplist)
12652 spec->loopback.amplist = alc262_loopbacks;
12653#endif
ea1fb29a 12654
df694daa
KY
12655 return 0;
12656}
12657
a361d84b
KY
12658/*
12659 * ALC268 channel source setting (2 channel)
12660 */
12661#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12662#define alc268_modes alc260_modes
ea1fb29a 12663
a361d84b
KY
12664static hda_nid_t alc268_dac_nids[2] = {
12665 /* front, hp */
12666 0x02, 0x03
12667};
12668
12669static hda_nid_t alc268_adc_nids[2] = {
12670 /* ADC0-1 */
12671 0x08, 0x07
12672};
12673
12674static hda_nid_t alc268_adc_nids_alt[1] = {
12675 /* ADC0 */
12676 0x08
12677};
12678
e1406348
TI
12679static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12680
a361d84b
KY
12681static struct snd_kcontrol_new alc268_base_mixer[] = {
12682 /* output mixer control */
12683 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12684 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12685 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12686 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
12687 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12688 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12689 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
12690 { }
12691};
12692
42171c17
TI
12693static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12694 /* output mixer control */
12695 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12696 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12697 ALC262_HIPPO_MASTER_SWITCH,
12698 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12699 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12700 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12701 { }
12702};
12703
aef9d318
TI
12704/* bind Beep switches of both NID 0x0f and 0x10 */
12705static struct hda_bind_ctls alc268_bind_beep_sw = {
12706 .ops = &snd_hda_bind_sw,
12707 .values = {
12708 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12709 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12710 0
12711 },
12712};
12713
12714static struct snd_kcontrol_new alc268_beep_mixer[] = {
12715 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12716 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12717 { }
12718};
12719
d1a991a6
KY
12720static struct hda_verb alc268_eapd_verbs[] = {
12721 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12722 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12723 { }
12724};
12725
d273809e 12726/* Toshiba specific */
d273809e
TI
12727static struct hda_verb alc268_toshiba_verbs[] = {
12728 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12729 { } /* end */
12730};
12731
12732/* Acer specific */
889c4395 12733/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
12734static struct hda_bind_ctls alc268_acer_bind_master_vol = {
12735 .ops = &snd_hda_bind_vol,
12736 .values = {
12737 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12738 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12739 0
12740 },
12741};
12742
889c4395
TI
12743/* mute/unmute internal speaker according to the hp jack and mute state */
12744static void alc268_acer_automute(struct hda_codec *codec, int force)
12745{
12746 struct alc_spec *spec = codec->spec;
12747 unsigned int mute;
12748
12749 if (force || !spec->sense_updated) {
864f92be 12750 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
12751 spec->sense_updated = 1;
12752 }
12753 if (spec->jack_present)
12754 mute = HDA_AMP_MUTE; /* mute internal speaker */
12755 else /* unmute internal speaker if necessary */
12756 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
12757 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12758 HDA_AMP_MUTE, mute);
12759}
12760
12761
12762/* bind hp and internal speaker mute (with plug check) */
12763static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
12764 struct snd_ctl_elem_value *ucontrol)
12765{
12766 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12767 long *valp = ucontrol->value.integer.value;
12768 int change;
12769
8de56b7d 12770 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
12771 if (change)
12772 alc268_acer_automute(codec, 0);
12773 return change;
12774}
d273809e 12775
8ef355da
KY
12776static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12777 /* output mixer control */
12778 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12779 {
12780 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12781 .name = "Master Playback Switch",
5e26dfd0 12782 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
12783 .info = snd_hda_mixer_amp_switch_info,
12784 .get = snd_hda_mixer_amp_switch_get,
12785 .put = alc268_acer_master_sw_put,
12786 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12787 },
12788 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12789 { }
12790};
12791
d273809e
TI
12792static struct snd_kcontrol_new alc268_acer_mixer[] = {
12793 /* output mixer control */
12794 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12795 {
12796 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12797 .name = "Master Playback Switch",
5e26dfd0 12798 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
12799 .info = snd_hda_mixer_amp_switch_info,
12800 .get = snd_hda_mixer_amp_switch_get,
12801 .put = alc268_acer_master_sw_put,
12802 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12803 },
33bf17ab
TI
12804 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12805 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12806 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
12807 { }
12808};
12809
c238b4f4
TI
12810static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12811 /* output mixer control */
12812 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12813 {
12814 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12815 .name = "Master Playback Switch",
5e26dfd0 12816 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
12817 .info = snd_hda_mixer_amp_switch_info,
12818 .get = snd_hda_mixer_amp_switch_get,
12819 .put = alc268_acer_master_sw_put,
12820 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12821 },
12822 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12823 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12824 { }
12825};
12826
8ef355da
KY
12827static struct hda_verb alc268_acer_aspire_one_verbs[] = {
12828 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12829 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12830 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12831 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12832 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12833 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12834 { }
12835};
12836
d273809e 12837static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
12838 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12839 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
12840 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12841 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
12842 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12843 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
12844 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12845 { }
12846};
12847
12848/* unsolicited event for HP jack sensing */
42171c17 12849#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
12850#define alc268_toshiba_setup alc262_hippo_setup
12851#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
12852
12853static void alc268_acer_unsol_event(struct hda_codec *codec,
12854 unsigned int res)
12855{
889c4395 12856 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
12857 return;
12858 alc268_acer_automute(codec, 1);
12859}
12860
889c4395
TI
12861static void alc268_acer_init_hook(struct hda_codec *codec)
12862{
12863 alc268_acer_automute(codec, 1);
12864}
12865
8ef355da
KY
12866/* toggle speaker-output according to the hp-jack state */
12867static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
12868{
12869 unsigned int present;
12870 unsigned char bits;
12871
864f92be 12872 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 12873 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 12874 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 12875 HDA_AMP_MUTE, bits);
8ef355da 12876 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 12877 HDA_AMP_MUTE, bits);
8ef355da
KY
12878}
12879
8ef355da
KY
12880static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
12881 unsigned int res)
12882{
4f5d1706
TI
12883 switch (res >> 26) {
12884 case ALC880_HP_EVENT:
8ef355da 12885 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
12886 break;
12887 case ALC880_MIC_EVENT:
12888 alc_mic_automute(codec);
12889 break;
12890 }
12891}
12892
12893static void alc268_acer_lc_setup(struct hda_codec *codec)
12894{
12895 struct alc_spec *spec = codec->spec;
12896 spec->ext_mic.pin = 0x18;
12897 spec->ext_mic.mux_idx = 0;
12898 spec->int_mic.pin = 0x12;
12899 spec->int_mic.mux_idx = 6;
12900 spec->auto_mic = 1;
8ef355da
KY
12901}
12902
12903static void alc268_acer_lc_init_hook(struct hda_codec *codec)
12904{
12905 alc268_aspire_one_speaker_automute(codec);
4f5d1706 12906 alc_mic_automute(codec);
8ef355da
KY
12907}
12908
3866f0b0
TI
12909static struct snd_kcontrol_new alc268_dell_mixer[] = {
12910 /* output mixer control */
12911 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12912 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12913 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12914 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12915 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12916 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12917 { }
12918};
12919
12920static struct hda_verb alc268_dell_verbs[] = {
12921 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12922 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12923 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 12924 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
12925 { }
12926};
12927
12928/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 12929static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 12930{
a9fd4f3f 12931 struct alc_spec *spec = codec->spec;
3866f0b0 12932
a9fd4f3f
TI
12933 spec->autocfg.hp_pins[0] = 0x15;
12934 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12935 spec->ext_mic.pin = 0x18;
12936 spec->ext_mic.mux_idx = 0;
12937 spec->int_mic.pin = 0x19;
12938 spec->int_mic.mux_idx = 1;
12939 spec->auto_mic = 1;
3866f0b0
TI
12940}
12941
eb5a6621
HRK
12942static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12943 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12944 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12945 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12946 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12947 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12948 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12949 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12950 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12951 { }
12952};
12953
12954static struct hda_verb alc267_quanta_il1_verbs[] = {
12955 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12956 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12957 { }
12958};
12959
4f5d1706 12960static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 12961{
a9fd4f3f 12962 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
12963 spec->autocfg.hp_pins[0] = 0x15;
12964 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12965 spec->ext_mic.pin = 0x18;
12966 spec->ext_mic.mux_idx = 0;
12967 spec->int_mic.pin = 0x19;
12968 spec->int_mic.mux_idx = 1;
12969 spec->auto_mic = 1;
eb5a6621
HRK
12970}
12971
a361d84b
KY
12972/*
12973 * generic initialization of ADC, input mixers and output mixers
12974 */
12975static struct hda_verb alc268_base_init_verbs[] = {
12976 /* Unmute DAC0-1 and set vol = 0 */
12977 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 12978 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
12979
12980 /*
12981 * Set up output mixers (0x0c - 0x0e)
12982 */
12983 /* set vol=0 to output mixers */
12984 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
12985 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12986
12987 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12988 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12989
12990 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12991 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12992 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12993 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12994 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12995 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12996 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12997 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12998
12999 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13000 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13001 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13002 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13003 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13004
13005 /* set PCBEEP vol = 0, mute connections */
13006 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13007 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13008 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13009
a9b3aa8a 13010 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13011
a9b3aa8a
JZ
13012 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13013 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13014 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13015 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13016
a361d84b
KY
13017 { }
13018};
13019
13020/*
13021 * generic initialization of ADC, input mixers and output mixers
13022 */
13023static struct hda_verb alc268_volume_init_verbs[] = {
13024 /* set output DAC */
4cfb91c6
TI
13025 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13026 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13027
13028 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13029 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13030 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13031 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13032 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13033
a361d84b 13034 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13035 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13036 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13037
13038 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13039 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13040
aef9d318
TI
13041 /* set PCBEEP vol = 0, mute connections */
13042 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13043 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13044 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13045
13046 { }
13047};
13048
fdbc6626
TI
13049static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13050 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13051 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13052 { } /* end */
13053};
13054
a361d84b
KY
13055static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13056 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13057 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13058 _DEFINE_CAPSRC(1),
a361d84b
KY
13059 { } /* end */
13060};
13061
13062static struct snd_kcontrol_new alc268_capture_mixer[] = {
13063 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13064 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13065 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13066 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13067 _DEFINE_CAPSRC(2),
a361d84b
KY
13068 { } /* end */
13069};
13070
13071static struct hda_input_mux alc268_capture_source = {
13072 .num_items = 4,
13073 .items = {
13074 { "Mic", 0x0 },
13075 { "Front Mic", 0x1 },
13076 { "Line", 0x2 },
13077 { "CD", 0x3 },
13078 },
13079};
13080
0ccb541c 13081static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13082 .num_items = 3,
13083 .items = {
13084 { "Mic", 0x0 },
13085 { "Internal Mic", 0x1 },
13086 { "Line", 0x2 },
13087 },
13088};
13089
13090static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13091 .num_items = 3,
13092 .items = {
13093 { "Mic", 0x0 },
13094 { "Internal Mic", 0x6 },
13095 { "Line", 0x2 },
13096 },
13097};
13098
86c53bd2
JW
13099#ifdef CONFIG_SND_DEBUG
13100static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13101 /* Volume widgets */
13102 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13103 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13104 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13105 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13106 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13107 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13108 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13109 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13110 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13111 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13112 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13113 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13114 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13115 /* The below appears problematic on some hardwares */
13116 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13117 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13118 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13119 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13120 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13121
13122 /* Modes for retasking pin widgets */
13123 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13124 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13125 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13126 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13127
13128 /* Controls for GPIO pins, assuming they are configured as outputs */
13129 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13130 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13131 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13132 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13133
13134 /* Switches to allow the digital SPDIF output pin to be enabled.
13135 * The ALC268 does not have an SPDIF input.
13136 */
13137 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13138
13139 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13140 * this output to turn on an external amplifier.
13141 */
13142 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13143 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13144
13145 { } /* end */
13146};
13147#endif
13148
a361d84b
KY
13149/* create input playback/capture controls for the given pin */
13150static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13151 const char *ctlname, int idx)
13152{
3f3b7c1a 13153 hda_nid_t dac;
a361d84b
KY
13154 int err;
13155
3f3b7c1a
TI
13156 switch (nid) {
13157 case 0x14:
13158 case 0x16:
13159 dac = 0x02;
13160 break;
13161 case 0x15:
b08b1637
TI
13162 case 0x1a: /* ALC259/269 only */
13163 case 0x1b: /* ALC259/269 only */
531d8791 13164 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13165 dac = 0x03;
13166 break;
13167 default:
c7a9434d
TI
13168 snd_printd(KERN_WARNING "hda_codec: "
13169 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13170 return 0;
13171 }
13172 if (spec->multiout.dac_nids[0] != dac &&
13173 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13174 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13175 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13176 HDA_OUTPUT));
13177 if (err < 0)
13178 return err;
3f3b7c1a
TI
13179 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13180 }
13181
3f3b7c1a 13182 if (nid != 0x16)
0afe5f89 13183 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13184 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13185 else /* mono */
0afe5f89 13186 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13187 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13188 if (err < 0)
13189 return err;
13190 return 0;
13191}
13192
13193/* add playback controls from the parsed DAC table */
13194static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13195 const struct auto_pin_cfg *cfg)
13196{
13197 hda_nid_t nid;
13198 int err;
13199
a361d84b 13200 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13201
13202 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13203 if (nid) {
13204 const char *name;
13205 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13206 name = "Speaker";
13207 else
13208 name = "Front";
13209 err = alc268_new_analog_output(spec, nid, name, 0);
13210 if (err < 0)
13211 return err;
13212 }
a361d84b
KY
13213
13214 nid = cfg->speaker_pins[0];
13215 if (nid == 0x1d) {
0afe5f89 13216 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13217 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13218 if (err < 0)
13219 return err;
7bfb9c03 13220 } else if (nid) {
3f3b7c1a
TI
13221 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13222 if (err < 0)
13223 return err;
a361d84b
KY
13224 }
13225 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13226 if (nid) {
13227 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13228 if (err < 0)
13229 return err;
13230 }
a361d84b
KY
13231
13232 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13233 if (nid == 0x16) {
0afe5f89 13234 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13235 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13236 if (err < 0)
13237 return err;
13238 }
ea1fb29a 13239 return 0;
a361d84b
KY
13240}
13241
13242/* create playback/capture controls for input pins */
05f5f477 13243static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13244 const struct auto_pin_cfg *cfg)
13245{
05f5f477 13246 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13247}
13248
e9af4f36
TI
13249static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13250 hda_nid_t nid, int pin_type)
13251{
13252 int idx;
13253
13254 alc_set_pin_output(codec, nid, pin_type);
13255 if (nid == 0x14 || nid == 0x16)
13256 idx = 0;
13257 else
13258 idx = 1;
13259 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13260}
13261
13262static void alc268_auto_init_multi_out(struct hda_codec *codec)
13263{
13264 struct alc_spec *spec = codec->spec;
13265 hda_nid_t nid = spec->autocfg.line_out_pins[0];
13266 if (nid) {
13267 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13268 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13269 }
13270}
13271
13272static void alc268_auto_init_hp_out(struct hda_codec *codec)
13273{
13274 struct alc_spec *spec = codec->spec;
13275 hda_nid_t pin;
13276
13277 pin = spec->autocfg.hp_pins[0];
13278 if (pin)
13279 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13280 pin = spec->autocfg.speaker_pins[0];
13281 if (pin)
13282 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13283}
13284
a361d84b
KY
13285static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13286{
13287 struct alc_spec *spec = codec->spec;
13288 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13289 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13290 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13291 unsigned int dac_vol1, dac_vol2;
13292
e9af4f36 13293 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13294 snd_hda_codec_write(codec, speaker_nid, 0,
13295 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13296 /* mute mixer inputs from 0x1d */
a361d84b
KY
13297 snd_hda_codec_write(codec, 0x0f, 0,
13298 AC_VERB_SET_AMP_GAIN_MUTE,
13299 AMP_IN_UNMUTE(1));
13300 snd_hda_codec_write(codec, 0x10, 0,
13301 AC_VERB_SET_AMP_GAIN_MUTE,
13302 AMP_IN_UNMUTE(1));
13303 } else {
e9af4f36 13304 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13305 snd_hda_codec_write(codec, 0x0f, 0,
13306 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13307 snd_hda_codec_write(codec, 0x10, 0,
13308 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13309 }
13310
13311 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13312 if (line_nid == 0x14)
a361d84b
KY
13313 dac_vol2 = AMP_OUT_ZERO;
13314 else if (line_nid == 0x15)
13315 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13316 if (hp_nid == 0x14)
a361d84b
KY
13317 dac_vol2 = AMP_OUT_ZERO;
13318 else if (hp_nid == 0x15)
13319 dac_vol1 = AMP_OUT_ZERO;
13320 if (line_nid != 0x16 || hp_nid != 0x16 ||
13321 spec->autocfg.line_out_pins[1] != 0x16 ||
13322 spec->autocfg.line_out_pins[2] != 0x16)
13323 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13324
13325 snd_hda_codec_write(codec, 0x02, 0,
13326 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13327 snd_hda_codec_write(codec, 0x03, 0,
13328 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13329}
13330
def319f9 13331/* pcm configuration: identical with ALC880 */
a361d84b
KY
13332#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13333#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13334#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13335#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13336
13337/*
13338 * BIOS auto configuration
13339 */
13340static int alc268_parse_auto_config(struct hda_codec *codec)
13341{
13342 struct alc_spec *spec = codec->spec;
13343 int err;
13344 static hda_nid_t alc268_ignore[] = { 0 };
13345
13346 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13347 alc268_ignore);
13348 if (err < 0)
13349 return err;
7e0e44d4
TI
13350 if (!spec->autocfg.line_outs) {
13351 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13352 spec->multiout.max_channels = 2;
13353 spec->no_analog = 1;
13354 goto dig_only;
13355 }
a361d84b 13356 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13357 }
a361d84b
KY
13358 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13359 if (err < 0)
13360 return err;
05f5f477 13361 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13362 if (err < 0)
13363 return err;
13364
13365 spec->multiout.max_channels = 2;
13366
7e0e44d4 13367 dig_only:
a361d84b 13368 /* digital only support output */
757899ac 13369 alc_auto_parse_digital(codec);
603c4019 13370 if (spec->kctls.list)
d88897ea 13371 add_mixer(spec, spec->kctls.list);
a361d84b 13372
892981ff 13373 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13374 add_mixer(spec, alc268_beep_mixer);
aef9d318 13375
d88897ea 13376 add_verb(spec, alc268_volume_init_verbs);
5908589f 13377 spec->num_mux_defs = 2;
61b9b9b1 13378 spec->input_mux = &spec->private_imux[0];
a361d84b 13379
776e184e
TI
13380 err = alc_auto_add_mic_boost(codec);
13381 if (err < 0)
13382 return err;
13383
6227cdce 13384 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13385
a361d84b
KY
13386 return 1;
13387}
13388
a361d84b
KY
13389#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13390
13391/* init callback for auto-configuration model -- overriding the default init */
13392static void alc268_auto_init(struct hda_codec *codec)
13393{
f6c7e546 13394 struct alc_spec *spec = codec->spec;
a361d84b
KY
13395 alc268_auto_init_multi_out(codec);
13396 alc268_auto_init_hp_out(codec);
13397 alc268_auto_init_mono_speaker_out(codec);
13398 alc268_auto_init_analog_input(codec);
757899ac 13399 alc_auto_init_digital(codec);
f6c7e546 13400 if (spec->unsol_event)
7fb0d78f 13401 alc_inithook(codec);
a361d84b
KY
13402}
13403
13404/*
13405 * configuration and preset
13406 */
13407static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13408 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13409 [ALC268_3ST] = "3stack",
983f8ae4 13410 [ALC268_TOSHIBA] = "toshiba",
d273809e 13411 [ALC268_ACER] = "acer",
c238b4f4 13412 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13413 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13414 [ALC268_DELL] = "dell",
f12462c5 13415 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13416#ifdef CONFIG_SND_DEBUG
13417 [ALC268_TEST] = "test",
13418#endif
a361d84b
KY
13419 [ALC268_AUTO] = "auto",
13420};
13421
13422static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13423 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13424 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13425 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13426 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13427 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13428 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13429 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13430 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13431 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13432 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13433 /* almost compatible with toshiba but with optional digital outs;
13434 * auto-probing seems working fine
13435 */
8871e5b9 13436 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13437 ALC268_AUTO),
a361d84b 13438 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13439 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13440 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13441 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13442 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
8871e5b9 13443 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
a361d84b
KY
13444 {}
13445};
13446
3abf2f36
TI
13447/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13448static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13449 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13450 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13451 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13452 ALC268_TOSHIBA),
13453 {}
13454};
13455
a361d84b 13456static struct alc_config_preset alc268_presets[] = {
eb5a6621 13457 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13458 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13459 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13460 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13461 alc267_quanta_il1_verbs },
13462 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13463 .dac_nids = alc268_dac_nids,
13464 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13465 .adc_nids = alc268_adc_nids_alt,
13466 .hp_nid = 0x03,
13467 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13468 .channel_mode = alc268_modes,
4f5d1706
TI
13469 .unsol_event = alc_sku_unsol_event,
13470 .setup = alc267_quanta_il1_setup,
13471 .init_hook = alc_inithook,
eb5a6621 13472 },
a361d84b 13473 [ALC268_3ST] = {
aef9d318
TI
13474 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13475 alc268_beep_mixer },
a361d84b
KY
13476 .init_verbs = { alc268_base_init_verbs },
13477 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13478 .dac_nids = alc268_dac_nids,
13479 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13480 .adc_nids = alc268_adc_nids_alt,
e1406348 13481 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13482 .hp_nid = 0x03,
13483 .dig_out_nid = ALC268_DIGOUT_NID,
13484 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13485 .channel_mode = alc268_modes,
13486 .input_mux = &alc268_capture_source,
13487 },
d1a991a6 13488 [ALC268_TOSHIBA] = {
42171c17 13489 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13490 alc268_beep_mixer },
d273809e
TI
13491 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13492 alc268_toshiba_verbs },
d1a991a6
KY
13493 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13494 .dac_nids = alc268_dac_nids,
13495 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13496 .adc_nids = alc268_adc_nids_alt,
e1406348 13497 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13498 .hp_nid = 0x03,
13499 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13500 .channel_mode = alc268_modes,
13501 .input_mux = &alc268_capture_source,
d273809e 13502 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13503 .setup = alc268_toshiba_setup,
13504 .init_hook = alc268_toshiba_automute,
d273809e
TI
13505 },
13506 [ALC268_ACER] = {
432fd133 13507 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13508 alc268_beep_mixer },
d273809e
TI
13509 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13510 alc268_acer_verbs },
13511 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13512 .dac_nids = alc268_dac_nids,
13513 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13514 .adc_nids = alc268_adc_nids_alt,
e1406348 13515 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13516 .hp_nid = 0x02,
13517 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13518 .channel_mode = alc268_modes,
0ccb541c 13519 .input_mux = &alc268_acer_capture_source,
d273809e 13520 .unsol_event = alc268_acer_unsol_event,
889c4395 13521 .init_hook = alc268_acer_init_hook,
d1a991a6 13522 },
c238b4f4
TI
13523 [ALC268_ACER_DMIC] = {
13524 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13525 alc268_beep_mixer },
13526 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13527 alc268_acer_verbs },
13528 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13529 .dac_nids = alc268_dac_nids,
13530 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13531 .adc_nids = alc268_adc_nids_alt,
13532 .capsrc_nids = alc268_capsrc_nids,
13533 .hp_nid = 0x02,
13534 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13535 .channel_mode = alc268_modes,
13536 .input_mux = &alc268_acer_dmic_capture_source,
13537 .unsol_event = alc268_acer_unsol_event,
13538 .init_hook = alc268_acer_init_hook,
13539 },
8ef355da
KY
13540 [ALC268_ACER_ASPIRE_ONE] = {
13541 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13542 alc268_beep_mixer,
fdbc6626 13543 alc268_capture_nosrc_mixer },
8ef355da
KY
13544 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13545 alc268_acer_aspire_one_verbs },
13546 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13547 .dac_nids = alc268_dac_nids,
13548 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13549 .adc_nids = alc268_adc_nids_alt,
13550 .capsrc_nids = alc268_capsrc_nids,
13551 .hp_nid = 0x03,
13552 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13553 .channel_mode = alc268_modes,
8ef355da 13554 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13555 .setup = alc268_acer_lc_setup,
8ef355da
KY
13556 .init_hook = alc268_acer_lc_init_hook,
13557 },
3866f0b0 13558 [ALC268_DELL] = {
fdbc6626
TI
13559 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13560 alc268_capture_nosrc_mixer },
3866f0b0
TI
13561 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13562 alc268_dell_verbs },
13563 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13564 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13565 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13566 .adc_nids = alc268_adc_nids_alt,
13567 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13568 .hp_nid = 0x02,
13569 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13570 .channel_mode = alc268_modes,
a9fd4f3f 13571 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13572 .setup = alc268_dell_setup,
13573 .init_hook = alc_inithook,
3866f0b0 13574 },
f12462c5 13575 [ALC268_ZEPTO] = {
aef9d318
TI
13576 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13577 alc268_beep_mixer },
f12462c5
MT
13578 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13579 alc268_toshiba_verbs },
13580 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13581 .dac_nids = alc268_dac_nids,
13582 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13583 .adc_nids = alc268_adc_nids_alt,
e1406348 13584 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13585 .hp_nid = 0x03,
13586 .dig_out_nid = ALC268_DIGOUT_NID,
13587 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13588 .channel_mode = alc268_modes,
13589 .input_mux = &alc268_capture_source,
4f5d1706
TI
13590 .setup = alc268_toshiba_setup,
13591 .init_hook = alc268_toshiba_automute,
f12462c5 13592 },
86c53bd2
JW
13593#ifdef CONFIG_SND_DEBUG
13594 [ALC268_TEST] = {
13595 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13596 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13597 alc268_volume_init_verbs },
13598 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13599 .dac_nids = alc268_dac_nids,
13600 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13601 .adc_nids = alc268_adc_nids_alt,
e1406348 13602 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13603 .hp_nid = 0x03,
13604 .dig_out_nid = ALC268_DIGOUT_NID,
13605 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13606 .channel_mode = alc268_modes,
13607 .input_mux = &alc268_capture_source,
13608 },
13609#endif
a361d84b
KY
13610};
13611
13612static int patch_alc268(struct hda_codec *codec)
13613{
13614 struct alc_spec *spec;
13615 int board_config;
22971e3a 13616 int i, has_beep, err;
a361d84b 13617
ef86f581 13618 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13619 if (spec == NULL)
13620 return -ENOMEM;
13621
13622 codec->spec = spec;
13623
13624 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13625 alc268_models,
13626 alc268_cfg_tbl);
13627
3abf2f36
TI
13628 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13629 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13630 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13631
a361d84b 13632 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13633 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13634 codec->chip_name);
a361d84b
KY
13635 board_config = ALC268_AUTO;
13636 }
13637
13638 if (board_config == ALC268_AUTO) {
13639 /* automatic parse from the BIOS config */
13640 err = alc268_parse_auto_config(codec);
13641 if (err < 0) {
13642 alc_free(codec);
13643 return err;
13644 } else if (!err) {
13645 printk(KERN_INFO
13646 "hda_codec: Cannot set up configuration "
13647 "from BIOS. Using base mode...\n");
13648 board_config = ALC268_3ST;
13649 }
13650 }
13651
13652 if (board_config != ALC268_AUTO)
e9c364c0 13653 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 13654
a361d84b
KY
13655 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13656 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 13657 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 13658
a361d84b
KY
13659 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13660
22971e3a
TI
13661 has_beep = 0;
13662 for (i = 0; i < spec->num_mixers; i++) {
13663 if (spec->mixers[i] == alc268_beep_mixer) {
13664 has_beep = 1;
13665 break;
13666 }
13667 }
13668
13669 if (has_beep) {
13670 err = snd_hda_attach_beep_device(codec, 0x1);
13671 if (err < 0) {
13672 alc_free(codec);
13673 return err;
13674 }
13675 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13676 /* override the amp caps for beep generator */
13677 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
13678 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13679 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13680 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13681 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 13682 }
aef9d318 13683
7e0e44d4 13684 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
13685 /* check whether NID 0x07 is valid */
13686 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 13687 int i;
3866f0b0 13688
defb5ab2 13689 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 13690 /* get type */
a22d543a 13691 wcap = get_wcaps_type(wcap);
fdbc6626
TI
13692 if (spec->auto_mic ||
13693 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
13694 spec->adc_nids = alc268_adc_nids_alt;
13695 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
13696 if (spec->auto_mic)
13697 fixup_automic_adc(codec);
fdbc6626
TI
13698 if (spec->auto_mic || spec->input_mux->num_items == 1)
13699 add_mixer(spec, alc268_capture_nosrc_mixer);
13700 else
13701 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
13702 } else {
13703 spec->adc_nids = alc268_adc_nids;
13704 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 13705 add_mixer(spec, alc268_capture_mixer);
a361d84b 13706 }
85860c06
TI
13707 /* set default input source */
13708 for (i = 0; i < spec->num_adc_nids; i++)
13709 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
13710 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
13711 i < spec->num_mux_defs ?
13712 spec->input_mux[i].items[0].index :
85860c06 13713 spec->input_mux->items[0].index);
a361d84b 13714 }
2134ea4f
TI
13715
13716 spec->vmaster_nid = 0x02;
13717
a361d84b
KY
13718 codec->patch_ops = alc_patch_ops;
13719 if (board_config == ALC268_AUTO)
13720 spec->init_hook = alc268_auto_init;
ea1fb29a 13721
a361d84b
KY
13722 return 0;
13723}
13724
f6a92248
KY
13725/*
13726 * ALC269 channel source setting (2 channel)
13727 */
13728#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13729
13730#define alc269_dac_nids alc260_dac_nids
13731
13732static hda_nid_t alc269_adc_nids[1] = {
13733 /* ADC1 */
f53281e6
KY
13734 0x08,
13735};
13736
e01bf509
TI
13737static hda_nid_t alc269_capsrc_nids[1] = {
13738 0x23,
13739};
13740
84898e87
KY
13741static hda_nid_t alc269vb_adc_nids[1] = {
13742 /* ADC1 */
13743 0x09,
13744};
13745
13746static hda_nid_t alc269vb_capsrc_nids[1] = {
13747 0x22,
13748};
13749
6694635d
TI
13750static hda_nid_t alc269_adc_candidates[] = {
13751 0x08, 0x09, 0x07,
13752};
e01bf509 13753
f6a92248
KY
13754#define alc269_modes alc260_modes
13755#define alc269_capture_source alc880_lg_lw_capture_source
13756
13757static struct snd_kcontrol_new alc269_base_mixer[] = {
13758 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13759 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13760 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13761 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13762 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13763 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13764 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13765 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13766 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13767 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13768 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13769 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
13770 { } /* end */
13771};
13772
60db6b53
KY
13773static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13774 /* output mixer control */
13775 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13776 {
13777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13778 .name = "Master Playback Switch",
5e26dfd0 13779 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
13780 .info = snd_hda_mixer_amp_switch_info,
13781 .get = snd_hda_mixer_amp_switch_get,
13782 .put = alc268_acer_master_sw_put,
13783 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13784 },
13785 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13786 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13787 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13788 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13789 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13790 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
60db6b53
KY
13791 { }
13792};
13793
64154835
TV
13794static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13795 /* output mixer control */
13796 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13797 {
13798 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13799 .name = "Master Playback Switch",
5e26dfd0 13800 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
13801 .info = snd_hda_mixer_amp_switch_info,
13802 .get = snd_hda_mixer_amp_switch_get,
13803 .put = alc268_acer_master_sw_put,
13804 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13805 },
13806 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13807 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13808 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13809 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13810 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13811 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13812 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13813 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
13814 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
64154835
TV
13815 { }
13816};
13817
84898e87 13818static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 13819 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 13820 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 13821 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 13822 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
13823 { } /* end */
13824};
13825
84898e87
KY
13826static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13827 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13828 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13829 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13830 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13831 { } /* end */
13832};
13833
f53281e6 13834/* capture mixer elements */
84898e87
KY
13835static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13836 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13837 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13838 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13839 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13840 { } /* end */
13841};
13842
13843static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
13844 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13845 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
26f5df26
TI
13846 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13847 { } /* end */
13848};
13849
84898e87
KY
13850static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13851 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13852 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13853 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13854 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13855 { } /* end */
13856};
13857
13858static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13859 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13860 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13861 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13862 { } /* end */
13863};
13864
26f5df26 13865/* FSC amilo */
84898e87 13866#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 13867
60db6b53
KY
13868static struct hda_verb alc269_quanta_fl1_verbs[] = {
13869 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13870 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13871 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13872 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13873 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13874 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13875 { }
13876};
f6a92248 13877
64154835
TV
13878static struct hda_verb alc269_lifebook_verbs[] = {
13879 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13880 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13881 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13882 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13883 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13884 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13885 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13886 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13887 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13888 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13889 { }
13890};
13891
60db6b53
KY
13892/* toggle speaker-output according to the hp-jack state */
13893static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13894{
13895 unsigned int present;
13896 unsigned char bits;
f6a92248 13897
864f92be 13898 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13899 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 13900 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 13901 HDA_AMP_MUTE, bits);
60db6b53 13902 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 13903 HDA_AMP_MUTE, bits);
f6a92248 13904
60db6b53
KY
13905 snd_hda_codec_write(codec, 0x20, 0,
13906 AC_VERB_SET_COEF_INDEX, 0x0c);
13907 snd_hda_codec_write(codec, 0x20, 0,
13908 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 13909
60db6b53
KY
13910 snd_hda_codec_write(codec, 0x20, 0,
13911 AC_VERB_SET_COEF_INDEX, 0x0c);
13912 snd_hda_codec_write(codec, 0x20, 0,
13913 AC_VERB_SET_PROC_COEF, 0x480);
13914}
f6a92248 13915
64154835
TV
13916/* toggle speaker-output according to the hp-jacks state */
13917static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
13918{
13919 unsigned int present;
13920 unsigned char bits;
13921
13922 /* Check laptop headphone socket */
864f92be 13923 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
13924
13925 /* Check port replicator headphone socket */
864f92be 13926 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 13927
5dbd5ec6 13928 bits = present ? HDA_AMP_MUTE : 0;
64154835 13929 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 13930 HDA_AMP_MUTE, bits);
64154835 13931 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 13932 HDA_AMP_MUTE, bits);
64154835
TV
13933
13934 snd_hda_codec_write(codec, 0x20, 0,
13935 AC_VERB_SET_COEF_INDEX, 0x0c);
13936 snd_hda_codec_write(codec, 0x20, 0,
13937 AC_VERB_SET_PROC_COEF, 0x680);
13938
13939 snd_hda_codec_write(codec, 0x20, 0,
13940 AC_VERB_SET_COEF_INDEX, 0x0c);
13941 snd_hda_codec_write(codec, 0x20, 0,
13942 AC_VERB_SET_PROC_COEF, 0x480);
13943}
13944
64154835
TV
13945static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13946{
13947 unsigned int present_laptop;
13948 unsigned int present_dock;
13949
864f92be
WF
13950 present_laptop = snd_hda_jack_detect(codec, 0x18);
13951 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
13952
13953 /* Laptop mic port overrides dock mic port, design decision */
13954 if (present_dock)
13955 snd_hda_codec_write(codec, 0x23, 0,
13956 AC_VERB_SET_CONNECT_SEL, 0x3);
13957 if (present_laptop)
13958 snd_hda_codec_write(codec, 0x23, 0,
13959 AC_VERB_SET_CONNECT_SEL, 0x0);
13960 if (!present_dock && !present_laptop)
13961 snd_hda_codec_write(codec, 0x23, 0,
13962 AC_VERB_SET_CONNECT_SEL, 0x1);
13963}
13964
60db6b53
KY
13965static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13966 unsigned int res)
13967{
4f5d1706
TI
13968 switch (res >> 26) {
13969 case ALC880_HP_EVENT:
60db6b53 13970 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
13971 break;
13972 case ALC880_MIC_EVENT:
13973 alc_mic_automute(codec);
13974 break;
13975 }
60db6b53 13976}
f6a92248 13977
64154835
TV
13978static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13979 unsigned int res)
13980{
13981 if ((res >> 26) == ALC880_HP_EVENT)
13982 alc269_lifebook_speaker_automute(codec);
13983 if ((res >> 26) == ALC880_MIC_EVENT)
13984 alc269_lifebook_mic_autoswitch(codec);
13985}
13986
4f5d1706
TI
13987static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13988{
13989 struct alc_spec *spec = codec->spec;
20645d70
TI
13990 spec->autocfg.hp_pins[0] = 0x15;
13991 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13992 spec->ext_mic.pin = 0x18;
13993 spec->ext_mic.mux_idx = 0;
13994 spec->int_mic.pin = 0x19;
13995 spec->int_mic.mux_idx = 1;
13996 spec->auto_mic = 1;
13997}
13998
60db6b53
KY
13999static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14000{
14001 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14002 alc_mic_automute(codec);
60db6b53 14003}
f6a92248 14004
64154835
TV
14005static void alc269_lifebook_init_hook(struct hda_codec *codec)
14006{
14007 alc269_lifebook_speaker_automute(codec);
14008 alc269_lifebook_mic_autoswitch(codec);
14009}
14010
84898e87 14011static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14012 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14013 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14014 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14015 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14016 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14017 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14018 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14019 {}
14020};
14021
84898e87 14022static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14023 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14024 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14025 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14026 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14027 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14028 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14029 {}
14030};
14031
84898e87
KY
14032static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14033 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14034 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14035 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14036 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14037 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14038 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14039 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14040 {}
14041};
14042
14043static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14044 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14045 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14046 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14047 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14048 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14049 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14050 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14051 {}
14052};
14053
f53281e6
KY
14054/* toggle speaker-output according to the hp-jack state */
14055static void alc269_speaker_automute(struct hda_codec *codec)
14056{
ebb83eeb
KY
14057 struct alc_spec *spec = codec->spec;
14058 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 14059 unsigned int present;
60db6b53 14060 unsigned char bits;
f53281e6 14061
ebb83eeb 14062 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 14063 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 14064 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14065 HDA_AMP_MUTE, bits);
f53281e6 14066 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14067 HDA_AMP_MUTE, bits);
f53281e6
KY
14068}
14069
f53281e6 14070/* unsolicited event for HP jack sensing */
84898e87 14071static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 14072 unsigned int res)
f53281e6 14073{
4f5d1706
TI
14074 switch (res >> 26) {
14075 case ALC880_HP_EVENT:
f53281e6 14076 alc269_speaker_automute(codec);
4f5d1706
TI
14077 break;
14078 case ALC880_MIC_EVENT:
14079 alc_mic_automute(codec);
14080 break;
14081 }
f53281e6
KY
14082}
14083
226b1ec8 14084static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14085{
4f5d1706 14086 struct alc_spec *spec = codec->spec;
20645d70
TI
14087 spec->autocfg.hp_pins[0] = 0x15;
14088 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14089 spec->ext_mic.pin = 0x18;
14090 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14091 spec->int_mic.pin = 0x19;
14092 spec->int_mic.mux_idx = 1;
4f5d1706 14093 spec->auto_mic = 1;
f53281e6
KY
14094}
14095
226b1ec8 14096static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14097{
14098 struct alc_spec *spec = codec->spec;
20645d70
TI
14099 spec->autocfg.hp_pins[0] = 0x15;
14100 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
14101 spec->ext_mic.pin = 0x18;
14102 spec->ext_mic.mux_idx = 0;
14103 spec->int_mic.pin = 0x12;
226b1ec8 14104 spec->int_mic.mux_idx = 5;
84898e87
KY
14105 spec->auto_mic = 1;
14106}
14107
226b1ec8 14108static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14109{
4f5d1706 14110 struct alc_spec *spec = codec->spec;
226b1ec8 14111 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14112 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14113 spec->ext_mic.pin = 0x18;
14114 spec->ext_mic.mux_idx = 0;
14115 spec->int_mic.pin = 0x19;
14116 spec->int_mic.mux_idx = 1;
14117 spec->auto_mic = 1;
f53281e6
KY
14118}
14119
226b1ec8
KY
14120static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14121{
14122 struct alc_spec *spec = codec->spec;
14123 spec->autocfg.hp_pins[0] = 0x21;
14124 spec->autocfg.speaker_pins[0] = 0x14;
14125 spec->ext_mic.pin = 0x18;
14126 spec->ext_mic.mux_idx = 0;
14127 spec->int_mic.pin = 0x12;
14128 spec->int_mic.mux_idx = 6;
14129 spec->auto_mic = 1;
14130}
14131
84898e87 14132static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
14133{
14134 alc269_speaker_automute(codec);
4f5d1706 14135 alc_mic_automute(codec);
f53281e6
KY
14136}
14137
60db6b53
KY
14138/*
14139 * generic initialization of ADC, input mixers and output mixers
14140 */
14141static struct hda_verb alc269_init_verbs[] = {
14142 /*
14143 * Unmute ADC0 and set the default input to mic-in
14144 */
84898e87 14145 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14146
14147 /*
84898e87 14148 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14149 */
14150 /* set vol=0 to output mixers */
14151 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14152 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14153
14154 /* set up input amps for analog loopback */
14155 /* Amp Indices: DAC = 0, mixer = 1 */
14156 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14157 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14158 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14159 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14160 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14161 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14162
14163 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14164 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14165 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14166 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14167 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14168 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14169 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14170
14171 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14172 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14173
84898e87
KY
14174 /* FIXME: use Mux-type input source selection */
14175 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14176 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14177 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14178
84898e87
KY
14179 /* set EAPD */
14180 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14181 { }
14182};
14183
14184static struct hda_verb alc269vb_init_verbs[] = {
14185 /*
14186 * Unmute ADC0 and set the default input to mic-in
14187 */
14188 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14189
14190 /*
14191 * Set up output mixers (0x02 - 0x03)
14192 */
14193 /* set vol=0 to output mixers */
14194 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14195 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14196
14197 /* set up input amps for analog loopback */
14198 /* Amp Indices: DAC = 0, mixer = 1 */
14199 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14200 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14201 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14202 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14203 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14204 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14205
14206 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14207 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14208 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14209 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14210 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14211 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14212 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14213
14214 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14215 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14216
14217 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14218 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14219 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14220 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14221
14222 /* set EAPD */
14223 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14224 { }
14225};
14226
9d0b71b1
TI
14227#define alc269_auto_create_multi_out_ctls \
14228 alc268_auto_create_multi_out_ctls
05f5f477
TI
14229#define alc269_auto_create_input_ctls \
14230 alc268_auto_create_input_ctls
f6a92248
KY
14231
14232#ifdef CONFIG_SND_HDA_POWER_SAVE
14233#define alc269_loopbacks alc880_loopbacks
14234#endif
14235
def319f9 14236/* pcm configuration: identical with ALC880 */
f6a92248
KY
14237#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14238#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14239#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14240#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14241
f03d3115
TI
14242static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14243 .substreams = 1,
14244 .channels_min = 2,
14245 .channels_max = 8,
14246 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14247 /* NID is set in alc_build_pcms */
14248 .ops = {
14249 .open = alc880_playback_pcm_open,
14250 .prepare = alc880_playback_pcm_prepare,
14251 .cleanup = alc880_playback_pcm_cleanup
14252 },
14253};
14254
14255static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14256 .substreams = 1,
14257 .channels_min = 2,
14258 .channels_max = 2,
14259 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14260 /* NID is set in alc_build_pcms */
14261};
14262
ad35879a
TI
14263#ifdef CONFIG_SND_HDA_POWER_SAVE
14264static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14265{
14266 switch (codec->subsystem_id) {
14267 case 0x103c1586:
14268 return 1;
14269 }
14270 return 0;
14271}
14272
14273static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14274{
14275 /* update mute-LED according to the speaker mute state */
14276 if (nid == 0x01 || nid == 0x14) {
14277 int pinval;
14278 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14279 HDA_AMP_MUTE)
14280 pinval = 0x24;
14281 else
14282 pinval = 0x20;
14283 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14284 snd_hda_codec_update_cache(codec, 0x19, 0,
14285 AC_VERB_SET_PIN_WIDGET_CONTROL,
14286 pinval);
ad35879a
TI
14287 }
14288 return alc_check_power_status(codec, nid);
14289}
14290#endif /* CONFIG_SND_HDA_POWER_SAVE */
14291
840b64c0
TI
14292static int alc275_setup_dual_adc(struct hda_codec *codec)
14293{
14294 struct alc_spec *spec = codec->spec;
14295
14296 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14297 return 0;
14298 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14299 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14300 if (spec->ext_mic.pin <= 0x12) {
14301 spec->private_adc_nids[0] = 0x08;
14302 spec->private_adc_nids[1] = 0x11;
14303 spec->private_capsrc_nids[0] = 0x23;
14304 spec->private_capsrc_nids[1] = 0x22;
14305 } else {
14306 spec->private_adc_nids[0] = 0x11;
14307 spec->private_adc_nids[1] = 0x08;
14308 spec->private_capsrc_nids[0] = 0x22;
14309 spec->private_capsrc_nids[1] = 0x23;
14310 }
14311 spec->adc_nids = spec->private_adc_nids;
14312 spec->capsrc_nids = spec->private_capsrc_nids;
14313 spec->num_adc_nids = 2;
14314 spec->dual_adc_switch = 1;
14315 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14316 spec->adc_nids[0], spec->adc_nids[1]);
14317 return 1;
14318 }
14319 return 0;
14320}
14321
f6a92248
KY
14322/*
14323 * BIOS auto configuration
14324 */
14325static int alc269_parse_auto_config(struct hda_codec *codec)
14326{
14327 struct alc_spec *spec = codec->spec;
cfb9fb55 14328 int err;
f6a92248
KY
14329 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14330
14331 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14332 alc269_ignore);
14333 if (err < 0)
14334 return err;
14335
14336 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14337 if (err < 0)
14338 return err;
05f5f477 14339 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
f6a92248
KY
14340 if (err < 0)
14341 return err;
14342
14343 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14344
757899ac 14345 alc_auto_parse_digital(codec);
f6a92248 14346
603c4019 14347 if (spec->kctls.list)
d88897ea 14348 add_mixer(spec, spec->kctls.list);
f6a92248 14349
84898e87
KY
14350 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
14351 add_verb(spec, alc269vb_init_verbs);
6227cdce 14352 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14353 } else {
14354 add_verb(spec, alc269_init_verbs);
6227cdce 14355 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14356 }
14357
f6a92248 14358 spec->num_mux_defs = 1;
61b9b9b1 14359 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14360
14361 if (!alc275_setup_dual_adc(codec))
14362 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14363 sizeof(alc269_adc_candidates));
6694635d 14364
e01bf509 14365 /* set default input source */
840b64c0
TI
14366 if (!spec->dual_adc_switch)
14367 snd_hda_codec_write_cache(codec, spec->capsrc_nids[0],
e01bf509
TI
14368 0, AC_VERB_SET_CONNECT_SEL,
14369 spec->input_mux->items[0].index);
f6a92248
KY
14370
14371 err = alc_auto_add_mic_boost(codec);
14372 if (err < 0)
14373 return err;
14374
7e0e44d4 14375 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14376 set_capture_mixer(codec);
f53281e6 14377
f6a92248
KY
14378 return 1;
14379}
14380
e9af4f36
TI
14381#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14382#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14383#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14384
14385
14386/* init callback for auto-configuration model -- overriding the default init */
14387static void alc269_auto_init(struct hda_codec *codec)
14388{
f6c7e546 14389 struct alc_spec *spec = codec->spec;
f6a92248
KY
14390 alc269_auto_init_multi_out(codec);
14391 alc269_auto_init_hp_out(codec);
14392 alc269_auto_init_analog_input(codec);
757899ac 14393 alc_auto_init_digital(codec);
f6c7e546 14394 if (spec->unsol_event)
7fb0d78f 14395 alc_inithook(codec);
f6a92248
KY
14396}
14397
ff818c24
TI
14398enum {
14399 ALC269_FIXUP_SONY_VAIO,
14400};
14401
fbc25669 14402static const struct hda_verb alc269_sony_vaio_fixup_verbs[] = {
ff818c24
TI
14403 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14404 {}
14405};
14406
14407static const struct alc_fixup alc269_fixups[] = {
14408 [ALC269_FIXUP_SONY_VAIO] = {
14409 .verbs = alc269_sony_vaio_fixup_verbs
14410 },
14411};
14412
14413static struct snd_pci_quirk alc269_fixup_tbl[] = {
14414 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14415 {}
14416};
14417
14418
f6a92248
KY
14419/*
14420 * configuration and preset
14421 */
14422static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14423 [ALC269_BASIC] = "basic",
2922c9af 14424 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14425 [ALC269_AMIC] = "laptop-amic",
14426 [ALC269_DMIC] = "laptop-dmic",
64154835 14427 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14428 [ALC269_LIFEBOOK] = "lifebook",
14429 [ALC269_AUTO] = "auto",
f6a92248
KY
14430};
14431
14432static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14433 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
f53281e6 14434 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14435 ALC269_AMIC),
14436 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14437 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14438 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14439 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14440 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14441 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14442 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14443 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14444 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14445 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14446 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14447 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14448 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14449 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14450 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14451 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14452 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14453 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14454 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14455 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14456 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14457 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14458 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14459 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14460 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14461 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14462 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14463 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14464 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14465 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14466 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14467 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14468 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14469 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14470 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14471 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14472 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14473 ALC269_DMIC),
60db6b53 14474 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14475 ALC269_DMIC),
14476 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14477 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14478 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14479 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14480 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14481 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14482 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14483 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14484 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14485 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14486 {}
14487};
14488
14489static struct alc_config_preset alc269_presets[] = {
14490 [ALC269_BASIC] = {
f9e336f6 14491 .mixers = { alc269_base_mixer },
f6a92248
KY
14492 .init_verbs = { alc269_init_verbs },
14493 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14494 .dac_nids = alc269_dac_nids,
14495 .hp_nid = 0x03,
14496 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14497 .channel_mode = alc269_modes,
14498 .input_mux = &alc269_capture_source,
14499 },
60db6b53
KY
14500 [ALC269_QUANTA_FL1] = {
14501 .mixers = { alc269_quanta_fl1_mixer },
14502 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14503 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14504 .dac_nids = alc269_dac_nids,
14505 .hp_nid = 0x03,
14506 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14507 .channel_mode = alc269_modes,
14508 .input_mux = &alc269_capture_source,
14509 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 14510 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
14511 .init_hook = alc269_quanta_fl1_init_hook,
14512 },
84898e87
KY
14513 [ALC269_AMIC] = {
14514 .mixers = { alc269_laptop_mixer },
14515 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 14516 .init_verbs = { alc269_init_verbs,
84898e87 14517 alc269_laptop_amic_init_verbs },
f53281e6
KY
14518 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14519 .dac_nids = alc269_dac_nids,
14520 .hp_nid = 0x03,
14521 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14522 .channel_mode = alc269_modes,
84898e87
KY
14523 .unsol_event = alc269_laptop_unsol_event,
14524 .setup = alc269_laptop_amic_setup,
14525 .init_hook = alc269_laptop_inithook,
f53281e6 14526 },
84898e87
KY
14527 [ALC269_DMIC] = {
14528 .mixers = { alc269_laptop_mixer },
14529 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 14530 .init_verbs = { alc269_init_verbs,
84898e87
KY
14531 alc269_laptop_dmic_init_verbs },
14532 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14533 .dac_nids = alc269_dac_nids,
14534 .hp_nid = 0x03,
14535 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14536 .channel_mode = alc269_modes,
14537 .unsol_event = alc269_laptop_unsol_event,
14538 .setup = alc269_laptop_dmic_setup,
14539 .init_hook = alc269_laptop_inithook,
14540 },
14541 [ALC269VB_AMIC] = {
14542 .mixers = { alc269vb_laptop_mixer },
14543 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14544 .init_verbs = { alc269vb_init_verbs,
14545 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
14546 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14547 .dac_nids = alc269_dac_nids,
14548 .hp_nid = 0x03,
14549 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14550 .channel_mode = alc269_modes,
84898e87 14551 .unsol_event = alc269_laptop_unsol_event,
226b1ec8 14552 .setup = alc269vb_laptop_amic_setup,
84898e87
KY
14553 .init_hook = alc269_laptop_inithook,
14554 },
14555 [ALC269VB_DMIC] = {
14556 .mixers = { alc269vb_laptop_mixer },
14557 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14558 .init_verbs = { alc269vb_init_verbs,
14559 alc269vb_laptop_dmic_init_verbs },
14560 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14561 .dac_nids = alc269_dac_nids,
14562 .hp_nid = 0x03,
14563 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14564 .channel_mode = alc269_modes,
14565 .unsol_event = alc269_laptop_unsol_event,
14566 .setup = alc269vb_laptop_dmic_setup,
14567 .init_hook = alc269_laptop_inithook,
f53281e6 14568 },
26f5df26 14569 [ALC269_FUJITSU] = {
45bdd1c1 14570 .mixers = { alc269_fujitsu_mixer },
84898e87 14571 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 14572 .init_verbs = { alc269_init_verbs,
84898e87 14573 alc269_laptop_dmic_init_verbs },
26f5df26
TI
14574 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14575 .dac_nids = alc269_dac_nids,
14576 .hp_nid = 0x03,
14577 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14578 .channel_mode = alc269_modes,
84898e87
KY
14579 .unsol_event = alc269_laptop_unsol_event,
14580 .setup = alc269_laptop_dmic_setup,
14581 .init_hook = alc269_laptop_inithook,
26f5df26 14582 },
64154835
TV
14583 [ALC269_LIFEBOOK] = {
14584 .mixers = { alc269_lifebook_mixer },
14585 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14586 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14587 .dac_nids = alc269_dac_nids,
14588 .hp_nid = 0x03,
14589 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14590 .channel_mode = alc269_modes,
14591 .input_mux = &alc269_capture_source,
14592 .unsol_event = alc269_lifebook_unsol_event,
14593 .init_hook = alc269_lifebook_init_hook,
14594 },
f6a92248
KY
14595};
14596
14597static int patch_alc269(struct hda_codec *codec)
14598{
14599 struct alc_spec *spec;
14600 int board_config;
14601 int err;
84898e87 14602 int is_alc269vb = 0;
f6a92248
KY
14603
14604 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14605 if (spec == NULL)
14606 return -ENOMEM;
14607
14608 codec->spec = spec;
14609
da00c244
KY
14610 alc_auto_parse_customize_define(codec);
14611
274693f3 14612 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
c027ddcd
KY
14613 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
14614 spec->cdefine.platform_type == 1)
14615 alc_codec_rename(codec, "ALC271X");
14616 else
14617 alc_codec_rename(codec, "ALC259");
84898e87 14618 is_alc269vb = 1;
c027ddcd
KY
14619 } else
14620 alc_fix_pll_init(codec, 0x20, 0x04, 15);
274693f3 14621
f6a92248
KY
14622 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14623 alc269_models,
14624 alc269_cfg_tbl);
14625
14626 if (board_config < 0) {
9a11f1aa
TI
14627 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14628 codec->chip_name);
f6a92248
KY
14629 board_config = ALC269_AUTO;
14630 }
14631
ff818c24
TI
14632 if (board_config == ALC269_AUTO)
14633 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
14634
f6a92248
KY
14635 if (board_config == ALC269_AUTO) {
14636 /* automatic parse from the BIOS config */
14637 err = alc269_parse_auto_config(codec);
14638 if (err < 0) {
14639 alc_free(codec);
14640 return err;
14641 } else if (!err) {
14642 printk(KERN_INFO
14643 "hda_codec: Cannot set up configuration "
14644 "from BIOS. Using base mode...\n");
14645 board_config = ALC269_BASIC;
14646 }
14647 }
14648
dc1eae25 14649 if (has_cdefine_beep(codec)) {
8af2591d
TI
14650 err = snd_hda_attach_beep_device(codec, 0x1);
14651 if (err < 0) {
14652 alc_free(codec);
14653 return err;
14654 }
680cd536
KK
14655 }
14656
f6a92248 14657 if (board_config != ALC269_AUTO)
e9c364c0 14658 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 14659
84898e87 14660 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
14661 /* Due to a hardware problem on Lenovo Ideadpad, we need to
14662 * fix the sample rate of analog I/O to 44.1kHz
14663 */
14664 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
14665 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
14666 } else if (spec->dual_adc_switch) {
14667 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14668 /* switch ADC dynamically */
14669 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
14670 } else {
14671 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14672 spec->stream_analog_capture = &alc269_pcm_analog_capture;
14673 }
f6a92248
KY
14674 spec->stream_digital_playback = &alc269_pcm_digital_playback;
14675 spec->stream_digital_capture = &alc269_pcm_digital_capture;
14676
6694635d
TI
14677 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
14678 if (!is_alc269vb) {
14679 spec->adc_nids = alc269_adc_nids;
14680 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
14681 spec->capsrc_nids = alc269_capsrc_nids;
14682 } else {
14683 spec->adc_nids = alc269vb_adc_nids;
14684 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
14685 spec->capsrc_nids = alc269vb_capsrc_nids;
14686 }
84898e87
KY
14687 }
14688
f9e336f6 14689 if (!spec->cap_mixer)
b59bdf3b 14690 set_capture_mixer(codec);
dc1eae25 14691 if (has_cdefine_beep(codec))
da00c244 14692 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 14693
ff818c24
TI
14694 if (board_config == ALC269_AUTO)
14695 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
14696
100d5eb3
TI
14697 spec->vmaster_nid = 0x02;
14698
f6a92248
KY
14699 codec->patch_ops = alc_patch_ops;
14700 if (board_config == ALC269_AUTO)
14701 spec->init_hook = alc269_auto_init;
14702#ifdef CONFIG_SND_HDA_POWER_SAVE
14703 if (!spec->loopback.amplist)
14704 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
14705 if (alc269_mic2_for_mute_led(codec))
14706 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
14707#endif
14708
14709 return 0;
14710}
14711
df694daa
KY
14712/*
14713 * ALC861 channel source setting (2/6 channel selection for 3-stack)
14714 */
14715
14716/*
14717 * set the path ways for 2 channel output
14718 * need to set the codec line out and mic 1 pin widgets to inputs
14719 */
14720static struct hda_verb alc861_threestack_ch2_init[] = {
14721 /* set pin widget 1Ah (line in) for input */
14722 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14723 /* set pin widget 18h (mic1/2) for input, for mic also enable
14724 * the vref
14725 */
df694daa
KY
14726 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14727
9c7f852e
TI
14728 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14729#if 0
14730 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14731 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14732#endif
df694daa
KY
14733 { } /* end */
14734};
14735/*
14736 * 6ch mode
14737 * need to set the codec line out and mic 1 pin widgets to outputs
14738 */
14739static struct hda_verb alc861_threestack_ch6_init[] = {
14740 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14741 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14742 /* set pin widget 18h (mic1) for output (CLFE)*/
14743 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14744
14745 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 14746 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 14747
9c7f852e
TI
14748 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14749#if 0
14750 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14751 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14752#endif
df694daa
KY
14753 { } /* end */
14754};
14755
14756static struct hda_channel_mode alc861_threestack_modes[2] = {
14757 { 2, alc861_threestack_ch2_init },
14758 { 6, alc861_threestack_ch6_init },
14759};
22309c3e
TI
14760/* Set mic1 as input and unmute the mixer */
14761static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
14762 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14763 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14764 { } /* end */
14765};
14766/* Set mic1 as output and mute mixer */
14767static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
14768 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14769 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14770 { } /* end */
14771};
14772
14773static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
14774 { 2, alc861_uniwill_m31_ch2_init },
14775 { 4, alc861_uniwill_m31_ch4_init },
14776};
df694daa 14777
7cdbff94
MD
14778/* Set mic1 and line-in as input and unmute the mixer */
14779static struct hda_verb alc861_asus_ch2_init[] = {
14780 /* set pin widget 1Ah (line in) for input */
14781 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14782 /* set pin widget 18h (mic1/2) for input, for mic also enable
14783 * the vref
14784 */
7cdbff94
MD
14785 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14786
14787 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14788#if 0
14789 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14790 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14791#endif
14792 { } /* end */
14793};
14794/* Set mic1 nad line-in as output and mute mixer */
14795static struct hda_verb alc861_asus_ch6_init[] = {
14796 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14797 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14798 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14799 /* set pin widget 18h (mic1) for output (CLFE)*/
14800 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14801 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14802 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14803 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14804
14805 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14806#if 0
14807 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14808 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14809#endif
14810 { } /* end */
14811};
14812
14813static struct hda_channel_mode alc861_asus_modes[2] = {
14814 { 2, alc861_asus_ch2_init },
14815 { 6, alc861_asus_ch6_init },
14816};
14817
df694daa
KY
14818/* patch-ALC861 */
14819
14820static struct snd_kcontrol_new alc861_base_mixer[] = {
14821 /* output mixer control */
14822 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14823 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14824 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14825 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14826 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14827
14828 /*Input mixer control */
14829 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14830 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14831 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14832 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14833 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14834 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14835 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14836 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14837 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14838 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14839
df694daa
KY
14840 { } /* end */
14841};
14842
14843static struct snd_kcontrol_new alc861_3ST_mixer[] = {
14844 /* output mixer control */
14845 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14846 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14847 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14848 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14849 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14850
14851 /* Input mixer control */
14852 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14853 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14854 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14855 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14856 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14857 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14858 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14859 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14860 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14861 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14862
df694daa
KY
14863 {
14864 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14865 .name = "Channel Mode",
14866 .info = alc_ch_mode_info,
14867 .get = alc_ch_mode_get,
14868 .put = alc_ch_mode_put,
14869 .private_value = ARRAY_SIZE(alc861_threestack_modes),
14870 },
14871 { } /* end */
a53d1aec
TD
14872};
14873
d1d985f0 14874static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
14875 /* output mixer control */
14876 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14877 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14878 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 14879
a53d1aec 14880 { } /* end */
f12ab1e0 14881};
a53d1aec 14882
22309c3e
TI
14883static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
14884 /* output mixer control */
14885 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14886 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14887 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14888 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14889 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14890
14891 /* Input mixer control */
14892 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14893 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14894 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14895 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14896 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14897 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14899 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14900 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14901 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14902
22309c3e
TI
14903 {
14904 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14905 .name = "Channel Mode",
14906 .info = alc_ch_mode_info,
14907 .get = alc_ch_mode_get,
14908 .put = alc_ch_mode_put,
14909 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
14910 },
14911 { } /* end */
f12ab1e0 14912};
7cdbff94
MD
14913
14914static struct snd_kcontrol_new alc861_asus_mixer[] = {
14915 /* output mixer control */
14916 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14917 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14918 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14919 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14920 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14921
14922 /* Input mixer control */
14923 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14924 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14925 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14926 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14927 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14928 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14929 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14930 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14931 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
14932 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
14933
7cdbff94
MD
14934 {
14935 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14936 .name = "Channel Mode",
14937 .info = alc_ch_mode_info,
14938 .get = alc_ch_mode_get,
14939 .put = alc_ch_mode_put,
14940 .private_value = ARRAY_SIZE(alc861_asus_modes),
14941 },
14942 { }
56bb0cab
TI
14943};
14944
14945/* additional mixer */
d1d985f0 14946static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
14947 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14948 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
14949 { }
14950};
7cdbff94 14951
df694daa
KY
14952/*
14953 * generic initialization of ADC, input mixers and output mixers
14954 */
14955static struct hda_verb alc861_base_init_verbs[] = {
14956 /*
14957 * Unmute ADC0 and set the default input to mic-in
14958 */
14959 /* port-A for surround (rear panel) */
14960 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14961 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
14962 /* port-B for mic-in (rear panel) with vref */
14963 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14964 /* port-C for line-in (rear panel) */
14965 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14966 /* port-D for Front */
14967 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14968 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14969 /* port-E for HP out (front panel) */
14970 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
14971 /* route front PCM to HP */
9dece1d7 14972 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
14973 /* port-F for mic-in (front panel) with vref */
14974 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14975 /* port-G for CLFE (rear panel) */
14976 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14977 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14978 /* port-H for side (rear panel) */
14979 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14980 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
14981 /* CD-in */
14982 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14983 /* route front mic to ADC1*/
14984 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14985 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 14986
df694daa
KY
14987 /* Unmute DAC0~3 & spdif out*/
14988 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14989 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14990 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14991 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14992 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 14993
df694daa
KY
14994 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14995 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14996 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14997 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14998 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14999
df694daa
KY
15000 /* Unmute Stereo Mixer 15 */
15001 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15002 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15003 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15004 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15005
15006 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15007 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15008 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15009 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15010 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15011 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15012 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15013 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15014 /* hp used DAC 3 (Front) */
15015 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15016 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15017
15018 { }
15019};
15020
15021static struct hda_verb alc861_threestack_init_verbs[] = {
15022 /*
15023 * Unmute ADC0 and set the default input to mic-in
15024 */
15025 /* port-A for surround (rear panel) */
15026 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15027 /* port-B for mic-in (rear panel) with vref */
15028 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15029 /* port-C for line-in (rear panel) */
15030 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15031 /* port-D for Front */
15032 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15033 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15034 /* port-E for HP out (front panel) */
15035 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15036 /* route front PCM to HP */
9dece1d7 15037 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15038 /* port-F for mic-in (front panel) with vref */
15039 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15040 /* port-G for CLFE (rear panel) */
15041 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15042 /* port-H for side (rear panel) */
15043 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15044 /* CD-in */
15045 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15046 /* route front mic to ADC1*/
15047 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15048 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15049 /* Unmute DAC0~3 & spdif out*/
15050 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15051 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15052 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15053 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15054 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15055
df694daa
KY
15056 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15057 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15058 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15059 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15060 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15061
df694daa
KY
15062 /* Unmute Stereo Mixer 15 */
15063 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15064 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15065 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15066 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15067
15068 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15069 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15070 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15071 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15072 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15073 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15074 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15075 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15076 /* hp used DAC 3 (Front) */
15077 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15078 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15079 { }
15080};
22309c3e
TI
15081
15082static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15083 /*
15084 * Unmute ADC0 and set the default input to mic-in
15085 */
15086 /* port-A for surround (rear panel) */
15087 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15088 /* port-B for mic-in (rear panel) with vref */
15089 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15090 /* port-C for line-in (rear panel) */
15091 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15092 /* port-D for Front */
15093 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15094 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15095 /* port-E for HP out (front panel) */
f12ab1e0
TI
15096 /* this has to be set to VREF80 */
15097 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15098 /* route front PCM to HP */
9dece1d7 15099 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15100 /* port-F for mic-in (front panel) with vref */
15101 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15102 /* port-G for CLFE (rear panel) */
15103 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15104 /* port-H for side (rear panel) */
15105 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15106 /* CD-in */
15107 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15108 /* route front mic to ADC1*/
15109 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15110 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15111 /* Unmute DAC0~3 & spdif out*/
15112 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15113 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15114 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15115 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15116 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15117
22309c3e
TI
15118 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15119 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15120 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15121 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15122 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15123
22309c3e
TI
15124 /* Unmute Stereo Mixer 15 */
15125 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15126 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15127 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15128 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15129
15130 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15131 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15132 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15133 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15134 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15135 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15136 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15137 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15138 /* hp used DAC 3 (Front) */
15139 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15140 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15141 { }
15142};
15143
7cdbff94
MD
15144static struct hda_verb alc861_asus_init_verbs[] = {
15145 /*
15146 * Unmute ADC0 and set the default input to mic-in
15147 */
f12ab1e0
TI
15148 /* port-A for surround (rear panel)
15149 * according to codec#0 this is the HP jack
15150 */
7cdbff94
MD
15151 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15152 /* route front PCM to HP */
15153 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15154 /* port-B for mic-in (rear panel) with vref */
15155 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15156 /* port-C for line-in (rear panel) */
15157 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15158 /* port-D for Front */
15159 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15160 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15161 /* port-E for HP out (front panel) */
f12ab1e0
TI
15162 /* this has to be set to VREF80 */
15163 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15164 /* route front PCM to HP */
9dece1d7 15165 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15166 /* port-F for mic-in (front panel) with vref */
15167 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15168 /* port-G for CLFE (rear panel) */
15169 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15170 /* port-H for side (rear panel) */
15171 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15172 /* CD-in */
15173 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15174 /* route front mic to ADC1*/
15175 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15176 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15177 /* Unmute DAC0~3 & spdif out*/
15178 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15179 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15180 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15181 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15182 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15183 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15184 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15185 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15186 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15187 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15188
7cdbff94
MD
15189 /* Unmute Stereo Mixer 15 */
15190 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15191 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15192 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15193 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15194
15195 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15196 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15197 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15198 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15199 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15200 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15201 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15202 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15203 /* hp used DAC 3 (Front) */
15204 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15205 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15206 { }
15207};
15208
56bb0cab
TI
15209/* additional init verbs for ASUS laptops */
15210static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15211 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15212 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15213 { }
15214};
7cdbff94 15215
df694daa
KY
15216/*
15217 * generic initialization of ADC, input mixers and output mixers
15218 */
15219static struct hda_verb alc861_auto_init_verbs[] = {
15220 /*
15221 * Unmute ADC0 and set the default input to mic-in
15222 */
f12ab1e0 15223 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15224 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15225
df694daa
KY
15226 /* Unmute DAC0~3 & spdif out*/
15227 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15228 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15229 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15230 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15231 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15232
df694daa
KY
15233 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15234 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15235 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15236 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15237 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15238
df694daa
KY
15239 /* Unmute Stereo Mixer 15 */
15240 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15241 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15242 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15243 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15244
1c20930a
TI
15245 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15246 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15247 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15248 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15249 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15250 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15251 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15252 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15253
15254 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15255 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15256 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15257 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15258 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15259 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15260 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15261 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15262
f12ab1e0 15263 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15264
15265 { }
15266};
15267
a53d1aec
TD
15268static struct hda_verb alc861_toshiba_init_verbs[] = {
15269 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15270
a53d1aec
TD
15271 { }
15272};
15273
15274/* toggle speaker-output according to the hp-jack state */
15275static void alc861_toshiba_automute(struct hda_codec *codec)
15276{
864f92be 15277 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15278
47fd830a
TI
15279 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15280 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15281 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15282 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15283}
15284
15285static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15286 unsigned int res)
15287{
a53d1aec
TD
15288 if ((res >> 26) == ALC880_HP_EVENT)
15289 alc861_toshiba_automute(codec);
15290}
15291
def319f9 15292/* pcm configuration: identical with ALC880 */
df694daa
KY
15293#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15294#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15295#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15296#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15297
15298
15299#define ALC861_DIGOUT_NID 0x07
15300
15301static struct hda_channel_mode alc861_8ch_modes[1] = {
15302 { 8, NULL }
15303};
15304
15305static hda_nid_t alc861_dac_nids[4] = {
15306 /* front, surround, clfe, side */
15307 0x03, 0x06, 0x05, 0x04
15308};
15309
9c7f852e
TI
15310static hda_nid_t alc660_dac_nids[3] = {
15311 /* front, clfe, surround */
15312 0x03, 0x05, 0x06
15313};
15314
df694daa
KY
15315static hda_nid_t alc861_adc_nids[1] = {
15316 /* ADC0-2 */
15317 0x08,
15318};
15319
15320static struct hda_input_mux alc861_capture_source = {
15321 .num_items = 5,
15322 .items = {
15323 { "Mic", 0x0 },
15324 { "Front Mic", 0x3 },
15325 { "Line", 0x1 },
15326 { "CD", 0x4 },
15327 { "Mixer", 0x5 },
15328 },
15329};
15330
1c20930a
TI
15331static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15332{
15333 struct alc_spec *spec = codec->spec;
15334 hda_nid_t mix, srcs[5];
15335 int i, j, num;
15336
15337 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15338 return 0;
15339 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15340 if (num < 0)
15341 return 0;
15342 for (i = 0; i < num; i++) {
15343 unsigned int type;
a22d543a 15344 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15345 if (type != AC_WID_AUD_OUT)
15346 continue;
15347 for (j = 0; j < spec->multiout.num_dacs; j++)
15348 if (spec->multiout.dac_nids[j] == srcs[i])
15349 break;
15350 if (j >= spec->multiout.num_dacs)
15351 return srcs[i];
15352 }
15353 return 0;
15354}
15355
df694daa 15356/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15357static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15358 const struct auto_pin_cfg *cfg)
df694daa 15359{
1c20930a 15360 struct alc_spec *spec = codec->spec;
df694daa 15361 int i;
1c20930a 15362 hda_nid_t nid, dac;
df694daa
KY
15363
15364 spec->multiout.dac_nids = spec->private_dac_nids;
15365 for (i = 0; i < cfg->line_outs; i++) {
15366 nid = cfg->line_out_pins[i];
1c20930a
TI
15367 dac = alc861_look_for_dac(codec, nid);
15368 if (!dac)
15369 continue;
15370 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15371 }
df694daa
KY
15372 return 0;
15373}
15374
1c20930a
TI
15375static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15376 hda_nid_t nid, unsigned int chs)
15377{
0afe5f89 15378 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
1c20930a
TI
15379 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15380}
15381
df694daa 15382/* add playback controls from the parsed DAC table */
1c20930a 15383static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15384 const struct auto_pin_cfg *cfg)
15385{
1c20930a 15386 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
15387 static const char *chname[4] = {
15388 "Front", "Surround", NULL /*CLFE*/, "Side"
15389 };
df694daa 15390 hda_nid_t nid;
1c20930a
TI
15391 int i, err;
15392
15393 if (cfg->line_outs == 1) {
15394 const char *pfx = NULL;
15395 if (!cfg->hp_outs)
15396 pfx = "Master";
15397 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15398 pfx = "Speaker";
15399 if (pfx) {
15400 nid = spec->multiout.dac_nids[0];
15401 return alc861_create_out_sw(codec, pfx, nid, 3);
15402 }
15403 }
df694daa
KY
15404
15405 for (i = 0; i < cfg->line_outs; i++) {
15406 nid = spec->multiout.dac_nids[i];
f12ab1e0 15407 if (!nid)
df694daa 15408 continue;
1c20930a 15409 if (i == 2) {
df694daa 15410 /* Center/LFE */
1c20930a 15411 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15412 if (err < 0)
df694daa 15413 return err;
1c20930a 15414 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15415 if (err < 0)
df694daa
KY
15416 return err;
15417 } else {
1c20930a 15418 err = alc861_create_out_sw(codec, chname[i], nid, 3);
f12ab1e0 15419 if (err < 0)
df694daa
KY
15420 return err;
15421 }
15422 }
15423 return 0;
15424}
15425
1c20930a 15426static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 15427{
1c20930a 15428 struct alc_spec *spec = codec->spec;
df694daa
KY
15429 int err;
15430 hda_nid_t nid;
15431
f12ab1e0 15432 if (!pin)
df694daa
KY
15433 return 0;
15434
15435 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
15436 nid = alc861_look_for_dac(codec, pin);
15437 if (nid) {
15438 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15439 if (err < 0)
15440 return err;
15441 spec->multiout.hp_nid = nid;
15442 }
df694daa
KY
15443 }
15444 return 0;
15445}
15446
15447/* create playback/capture controls for input pins */
05f5f477 15448static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 15449 const struct auto_pin_cfg *cfg)
df694daa 15450{
05f5f477 15451 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
15452}
15453
f12ab1e0
TI
15454static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15455 hda_nid_t nid,
1c20930a 15456 int pin_type, hda_nid_t dac)
df694daa 15457{
1c20930a
TI
15458 hda_nid_t mix, srcs[5];
15459 int i, num;
15460
564c5bea
JL
15461 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15462 pin_type);
1c20930a 15463 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 15464 AMP_OUT_UNMUTE);
1c20930a
TI
15465 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15466 return;
15467 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15468 if (num < 0)
15469 return;
15470 for (i = 0; i < num; i++) {
15471 unsigned int mute;
15472 if (srcs[i] == dac || srcs[i] == 0x15)
15473 mute = AMP_IN_UNMUTE(i);
15474 else
15475 mute = AMP_IN_MUTE(i);
15476 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15477 mute);
15478 }
df694daa
KY
15479}
15480
15481static void alc861_auto_init_multi_out(struct hda_codec *codec)
15482{
15483 struct alc_spec *spec = codec->spec;
15484 int i;
15485
15486 for (i = 0; i < spec->autocfg.line_outs; i++) {
15487 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 15488 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 15489 if (nid)
baba8ee9 15490 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 15491 spec->multiout.dac_nids[i]);
df694daa
KY
15492 }
15493}
15494
15495static void alc861_auto_init_hp_out(struct hda_codec *codec)
15496{
15497 struct alc_spec *spec = codec->spec;
df694daa 15498
15870f05
TI
15499 if (spec->autocfg.hp_outs)
15500 alc861_auto_set_output_and_unmute(codec,
15501 spec->autocfg.hp_pins[0],
15502 PIN_HP,
1c20930a 15503 spec->multiout.hp_nid);
15870f05
TI
15504 if (spec->autocfg.speaker_outs)
15505 alc861_auto_set_output_and_unmute(codec,
15506 spec->autocfg.speaker_pins[0],
15507 PIN_OUT,
1c20930a 15508 spec->multiout.dac_nids[0]);
df694daa
KY
15509}
15510
15511static void alc861_auto_init_analog_input(struct hda_codec *codec)
15512{
15513 struct alc_spec *spec = codec->spec;
15514 int i;
15515
15516 for (i = 0; i < AUTO_PIN_LAST; i++) {
15517 hda_nid_t nid = spec->autocfg.input_pins[i];
23f0c048
TI
15518 if (nid >= 0x0c && nid <= 0x11)
15519 alc_set_input_pin(codec, nid, i);
df694daa
KY
15520 }
15521}
15522
15523/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
15524/* return 1 if successful, 0 if the proper config is not found,
15525 * or a negative error code
15526 */
df694daa
KY
15527static int alc861_parse_auto_config(struct hda_codec *codec)
15528{
15529 struct alc_spec *spec = codec->spec;
15530 int err;
15531 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
15532
f12ab1e0
TI
15533 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15534 alc861_ignore);
15535 if (err < 0)
df694daa 15536 return err;
f12ab1e0 15537 if (!spec->autocfg.line_outs)
df694daa
KY
15538 return 0; /* can't find valid BIOS pin config */
15539
1c20930a 15540 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
15541 if (err < 0)
15542 return err;
1c20930a 15543 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
15544 if (err < 0)
15545 return err;
1c20930a 15546 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
15547 if (err < 0)
15548 return err;
05f5f477 15549 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 15550 if (err < 0)
df694daa
KY
15551 return err;
15552
15553 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15554
757899ac 15555 alc_auto_parse_digital(codec);
df694daa 15556
603c4019 15557 if (spec->kctls.list)
d88897ea 15558 add_mixer(spec, spec->kctls.list);
df694daa 15559
d88897ea 15560 add_verb(spec, alc861_auto_init_verbs);
df694daa 15561
a1e8d2da 15562 spec->num_mux_defs = 1;
61b9b9b1 15563 spec->input_mux = &spec->private_imux[0];
df694daa
KY
15564
15565 spec->adc_nids = alc861_adc_nids;
15566 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 15567 set_capture_mixer(codec);
df694daa 15568
6227cdce 15569 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 15570
df694daa
KY
15571 return 1;
15572}
15573
ae6b813a
TI
15574/* additional initialization for auto-configuration model */
15575static void alc861_auto_init(struct hda_codec *codec)
df694daa 15576{
f6c7e546 15577 struct alc_spec *spec = codec->spec;
df694daa
KY
15578 alc861_auto_init_multi_out(codec);
15579 alc861_auto_init_hp_out(codec);
15580 alc861_auto_init_analog_input(codec);
757899ac 15581 alc_auto_init_digital(codec);
f6c7e546 15582 if (spec->unsol_event)
7fb0d78f 15583 alc_inithook(codec);
df694daa
KY
15584}
15585
cb53c626
TI
15586#ifdef CONFIG_SND_HDA_POWER_SAVE
15587static struct hda_amp_list alc861_loopbacks[] = {
15588 { 0x15, HDA_INPUT, 0 },
15589 { 0x15, HDA_INPUT, 1 },
15590 { 0x15, HDA_INPUT, 2 },
15591 { 0x15, HDA_INPUT, 3 },
15592 { } /* end */
15593};
15594#endif
15595
df694daa
KY
15596
15597/*
15598 * configuration and preset
15599 */
f5fcc13c
TI
15600static const char *alc861_models[ALC861_MODEL_LAST] = {
15601 [ALC861_3ST] = "3stack",
15602 [ALC660_3ST] = "3stack-660",
15603 [ALC861_3ST_DIG] = "3stack-dig",
15604 [ALC861_6ST_DIG] = "6stack-dig",
15605 [ALC861_UNIWILL_M31] = "uniwill-m31",
15606 [ALC861_TOSHIBA] = "toshiba",
15607 [ALC861_ASUS] = "asus",
15608 [ALC861_ASUS_LAPTOP] = "asus-laptop",
15609 [ALC861_AUTO] = "auto",
15610};
15611
15612static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 15613 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
15614 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15615 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15616 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 15617 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 15618 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 15619 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
15620 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
15621 * Any other models that need this preset?
15622 */
15623 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
15624 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
15625 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 15626 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
15627 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
15628 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
15629 /* FIXME: the below seems conflict */
15630 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 15631 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 15632 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
15633 {}
15634};
15635
15636static struct alc_config_preset alc861_presets[] = {
15637 [ALC861_3ST] = {
15638 .mixers = { alc861_3ST_mixer },
15639 .init_verbs = { alc861_threestack_init_verbs },
15640 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15641 .dac_nids = alc861_dac_nids,
15642 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15643 .channel_mode = alc861_threestack_modes,
4e195a7b 15644 .need_dac_fix = 1,
df694daa
KY
15645 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15646 .adc_nids = alc861_adc_nids,
15647 .input_mux = &alc861_capture_source,
15648 },
15649 [ALC861_3ST_DIG] = {
15650 .mixers = { alc861_base_mixer },
15651 .init_verbs = { alc861_threestack_init_verbs },
15652 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15653 .dac_nids = alc861_dac_nids,
15654 .dig_out_nid = ALC861_DIGOUT_NID,
15655 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15656 .channel_mode = alc861_threestack_modes,
4e195a7b 15657 .need_dac_fix = 1,
df694daa
KY
15658 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15659 .adc_nids = alc861_adc_nids,
15660 .input_mux = &alc861_capture_source,
15661 },
15662 [ALC861_6ST_DIG] = {
15663 .mixers = { alc861_base_mixer },
15664 .init_verbs = { alc861_base_init_verbs },
15665 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15666 .dac_nids = alc861_dac_nids,
15667 .dig_out_nid = ALC861_DIGOUT_NID,
15668 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
15669 .channel_mode = alc861_8ch_modes,
15670 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15671 .adc_nids = alc861_adc_nids,
15672 .input_mux = &alc861_capture_source,
15673 },
9c7f852e
TI
15674 [ALC660_3ST] = {
15675 .mixers = { alc861_3ST_mixer },
15676 .init_verbs = { alc861_threestack_init_verbs },
15677 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
15678 .dac_nids = alc660_dac_nids,
15679 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15680 .channel_mode = alc861_threestack_modes,
4e195a7b 15681 .need_dac_fix = 1,
9c7f852e
TI
15682 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15683 .adc_nids = alc861_adc_nids,
15684 .input_mux = &alc861_capture_source,
15685 },
22309c3e
TI
15686 [ALC861_UNIWILL_M31] = {
15687 .mixers = { alc861_uniwill_m31_mixer },
15688 .init_verbs = { alc861_uniwill_m31_init_verbs },
15689 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15690 .dac_nids = alc861_dac_nids,
15691 .dig_out_nid = ALC861_DIGOUT_NID,
15692 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
15693 .channel_mode = alc861_uniwill_m31_modes,
15694 .need_dac_fix = 1,
15695 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15696 .adc_nids = alc861_adc_nids,
15697 .input_mux = &alc861_capture_source,
15698 },
a53d1aec
TD
15699 [ALC861_TOSHIBA] = {
15700 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
15701 .init_verbs = { alc861_base_init_verbs,
15702 alc861_toshiba_init_verbs },
a53d1aec
TD
15703 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15704 .dac_nids = alc861_dac_nids,
15705 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15706 .channel_mode = alc883_3ST_2ch_modes,
15707 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15708 .adc_nids = alc861_adc_nids,
15709 .input_mux = &alc861_capture_source,
15710 .unsol_event = alc861_toshiba_unsol_event,
15711 .init_hook = alc861_toshiba_automute,
15712 },
7cdbff94
MD
15713 [ALC861_ASUS] = {
15714 .mixers = { alc861_asus_mixer },
15715 .init_verbs = { alc861_asus_init_verbs },
15716 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15717 .dac_nids = alc861_dac_nids,
15718 .dig_out_nid = ALC861_DIGOUT_NID,
15719 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
15720 .channel_mode = alc861_asus_modes,
15721 .need_dac_fix = 1,
15722 .hp_nid = 0x06,
15723 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15724 .adc_nids = alc861_adc_nids,
15725 .input_mux = &alc861_capture_source,
15726 },
56bb0cab
TI
15727 [ALC861_ASUS_LAPTOP] = {
15728 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
15729 .init_verbs = { alc861_asus_init_verbs,
15730 alc861_asus_laptop_init_verbs },
15731 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15732 .dac_nids = alc861_dac_nids,
15733 .dig_out_nid = ALC861_DIGOUT_NID,
15734 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15735 .channel_mode = alc883_3ST_2ch_modes,
15736 .need_dac_fix = 1,
15737 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15738 .adc_nids = alc861_adc_nids,
15739 .input_mux = &alc861_capture_source,
15740 },
15741};
df694daa 15742
cfc9b06f
TI
15743/* Pin config fixes */
15744enum {
15745 PINFIX_FSC_AMILO_PI1505,
15746};
15747
15748static struct alc_pincfg alc861_fsc_amilo_pi1505_pinfix[] = {
15749 { 0x0b, 0x0221101f }, /* HP */
15750 { 0x0f, 0x90170310 }, /* speaker */
15751 { }
15752};
15753
15754static const struct alc_fixup alc861_fixups[] = {
15755 [PINFIX_FSC_AMILO_PI1505] = {
15756 .pins = alc861_fsc_amilo_pi1505_pinfix
15757 },
15758};
15759
15760static struct snd_pci_quirk alc861_fixup_tbl[] = {
15761 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
15762 {}
15763};
df694daa
KY
15764
15765static int patch_alc861(struct hda_codec *codec)
15766{
15767 struct alc_spec *spec;
15768 int board_config;
15769 int err;
15770
dc041e0b 15771 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
15772 if (spec == NULL)
15773 return -ENOMEM;
15774
f12ab1e0 15775 codec->spec = spec;
df694daa 15776
f5fcc13c
TI
15777 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
15778 alc861_models,
15779 alc861_cfg_tbl);
9c7f852e 15780
f5fcc13c 15781 if (board_config < 0) {
9a11f1aa
TI
15782 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15783 codec->chip_name);
df694daa
KY
15784 board_config = ALC861_AUTO;
15785 }
15786
7fa90e87
TI
15787 if (board_config == ALC861_AUTO)
15788 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
cfc9b06f 15789
df694daa
KY
15790 if (board_config == ALC861_AUTO) {
15791 /* automatic parse from the BIOS config */
15792 err = alc861_parse_auto_config(codec);
15793 if (err < 0) {
15794 alc_free(codec);
15795 return err;
f12ab1e0 15796 } else if (!err) {
9c7f852e
TI
15797 printk(KERN_INFO
15798 "hda_codec: Cannot set up configuration "
15799 "from BIOS. Using base mode...\n");
df694daa
KY
15800 board_config = ALC861_3ST_DIG;
15801 }
15802 }
15803
680cd536
KK
15804 err = snd_hda_attach_beep_device(codec, 0x23);
15805 if (err < 0) {
15806 alc_free(codec);
15807 return err;
15808 }
15809
df694daa 15810 if (board_config != ALC861_AUTO)
e9c364c0 15811 setup_preset(codec, &alc861_presets[board_config]);
df694daa 15812
df694daa
KY
15813 spec->stream_analog_playback = &alc861_pcm_analog_playback;
15814 spec->stream_analog_capture = &alc861_pcm_analog_capture;
15815
df694daa
KY
15816 spec->stream_digital_playback = &alc861_pcm_digital_playback;
15817 spec->stream_digital_capture = &alc861_pcm_digital_capture;
15818
c7a8eb10
TI
15819 if (!spec->cap_mixer)
15820 set_capture_mixer(codec);
45bdd1c1
TI
15821 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
15822
2134ea4f
TI
15823 spec->vmaster_nid = 0x03;
15824
7fa90e87
TI
15825 if (board_config == ALC861_AUTO)
15826 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
15827
df694daa 15828 codec->patch_ops = alc_patch_ops;
c97259df 15829 if (board_config == ALC861_AUTO) {
ae6b813a 15830 spec->init_hook = alc861_auto_init;
c97259df
DC
15831#ifdef CONFIG_SND_HDA_POWER_SAVE
15832 spec->power_hook = alc_power_eapd;
15833#endif
15834 }
cb53c626
TI
15835#ifdef CONFIG_SND_HDA_POWER_SAVE
15836 if (!spec->loopback.amplist)
15837 spec->loopback.amplist = alc861_loopbacks;
15838#endif
ea1fb29a 15839
1da177e4
LT
15840 return 0;
15841}
15842
f32610ed
JS
15843/*
15844 * ALC861-VD support
15845 *
15846 * Based on ALC882
15847 *
15848 * In addition, an independent DAC
15849 */
15850#define ALC861VD_DIGOUT_NID 0x06
15851
15852static hda_nid_t alc861vd_dac_nids[4] = {
15853 /* front, surr, clfe, side surr */
15854 0x02, 0x03, 0x04, 0x05
15855};
15856
15857/* dac_nids for ALC660vd are in a different order - according to
15858 * Realtek's driver.
def319f9 15859 * This should probably result in a different mixer for 6stack models
f32610ed
JS
15860 * of ALC660vd codecs, but for now there is only 3stack mixer
15861 * - and it is the same as in 861vd.
15862 * adc_nids in ALC660vd are (is) the same as in 861vd
15863 */
15864static hda_nid_t alc660vd_dac_nids[3] = {
15865 /* front, rear, clfe, rear_surr */
15866 0x02, 0x04, 0x03
15867};
15868
15869static hda_nid_t alc861vd_adc_nids[1] = {
15870 /* ADC0 */
15871 0x09,
15872};
15873
e1406348
TI
15874static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
15875
f32610ed
JS
15876/* input MUX */
15877/* FIXME: should be a matrix-type input source selection */
15878static struct hda_input_mux alc861vd_capture_source = {
15879 .num_items = 4,
15880 .items = {
15881 { "Mic", 0x0 },
15882 { "Front Mic", 0x1 },
15883 { "Line", 0x2 },
15884 { "CD", 0x4 },
15885 },
15886};
15887
272a527c 15888static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 15889 .num_items = 2,
272a527c 15890 .items = {
b419f346
TD
15891 { "Ext Mic", 0x0 },
15892 { "Int Mic", 0x1 },
272a527c
KY
15893 },
15894};
15895
d1a991a6
KY
15896static struct hda_input_mux alc861vd_hp_capture_source = {
15897 .num_items = 2,
15898 .items = {
15899 { "Front Mic", 0x0 },
15900 { "ATAPI Mic", 0x1 },
15901 },
15902};
15903
f32610ed
JS
15904/*
15905 * 2ch mode
15906 */
15907static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
15908 { 2, NULL }
15909};
15910
15911/*
15912 * 6ch mode
15913 */
15914static struct hda_verb alc861vd_6stack_ch6_init[] = {
15915 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15916 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15917 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15918 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15919 { } /* end */
15920};
15921
15922/*
15923 * 8ch mode
15924 */
15925static struct hda_verb alc861vd_6stack_ch8_init[] = {
15926 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15927 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15928 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15929 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15930 { } /* end */
15931};
15932
15933static struct hda_channel_mode alc861vd_6stack_modes[2] = {
15934 { 6, alc861vd_6stack_ch6_init },
15935 { 8, alc861vd_6stack_ch8_init },
15936};
15937
15938static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
15939 {
15940 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15941 .name = "Channel Mode",
15942 .info = alc_ch_mode_info,
15943 .get = alc_ch_mode_get,
15944 .put = alc_ch_mode_put,
15945 },
15946 { } /* end */
15947};
15948
f32610ed
JS
15949/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15950 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15951 */
15952static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
15953 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15954 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15955
15956 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15957 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
15958
15959 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
15960 HDA_OUTPUT),
15961 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
15962 HDA_OUTPUT),
15963 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
15964 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
15965
15966 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
15967 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
15968
15969 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15970
15971 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15972 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15973 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15974
15975 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15976 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15977 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15978
15979 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15980 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15981
15982 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15983 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15984
f32610ed
JS
15985 { } /* end */
15986};
15987
15988static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
15989 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15990 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15991
15992 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15993
15994 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15997
15998 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15999 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16000 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16001
16002 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16003 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16004
16005 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16006 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16007
f32610ed
JS
16008 { } /* end */
16009};
16010
bdd148a3
KY
16011static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16012 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16013 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16014 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16015
16016 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16017
16018 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
16019 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16020 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16021
16022 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
16023 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16024 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16025
16026 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16027 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16028
16029 { } /* end */
16030};
16031
b419f346
TD
16032/* Pin assignment: Speaker=0x14, HP = 0x15,
16033 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
16034 */
16035static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16036 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16037 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16038 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16039 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
16040 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16041 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16042 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16043 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16044 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16045 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16046 { } /* end */
16047};
16048
d1a991a6
KY
16049/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16050 * Front Mic=0x18, ATAPI Mic = 0x19,
16051 */
16052static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16053 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16054 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16055 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16056 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16057 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16058 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16059 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16060 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16061
d1a991a6
KY
16062 { } /* end */
16063};
16064
f32610ed
JS
16065/*
16066 * generic initialization of ADC, input mixers and output mixers
16067 */
16068static struct hda_verb alc861vd_volume_init_verbs[] = {
16069 /*
16070 * Unmute ADC0 and set the default input to mic-in
16071 */
16072 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16073 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16074
16075 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16076 * the analog-loopback mixer widget
16077 */
16078 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16079 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16080 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16081 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16082 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16083 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16084
16085 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16087 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16088 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16089 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16090
16091 /*
16092 * Set up output mixers (0x02 - 0x05)
16093 */
16094 /* set vol=0 to output mixers */
16095 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16096 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16097 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16098 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16099
16100 /* set up input amps for analog loopback */
16101 /* Amp Indices: DAC = 0, mixer = 1 */
16102 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16103 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16104 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16105 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16106 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16107 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16108 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16109 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16110
16111 { }
16112};
16113
16114/*
16115 * 3-stack pin configuration:
16116 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16117 */
16118static struct hda_verb alc861vd_3stack_init_verbs[] = {
16119 /*
16120 * Set pin mode and muting
16121 */
16122 /* set front pin widgets 0x14 for output */
16123 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16124 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16125 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16126
16127 /* Mic (rear) pin: input vref at 80% */
16128 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16129 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16130 /* Front Mic pin: input vref at 80% */
16131 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16132 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16133 /* Line In pin: input */
16134 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16135 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16136 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16137 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16138 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16139 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16140 /* CD pin widget for input */
16141 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16142
16143 { }
16144};
16145
16146/*
16147 * 6-stack pin configuration:
16148 */
16149static struct hda_verb alc861vd_6stack_init_verbs[] = {
16150 /*
16151 * Set pin mode and muting
16152 */
16153 /* set front pin widgets 0x14 for output */
16154 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16155 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16156 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16157
16158 /* Rear Pin: output 1 (0x0d) */
16159 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16160 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16161 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16162 /* CLFE Pin: output 2 (0x0e) */
16163 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16164 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16165 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16166 /* Side Pin: output 3 (0x0f) */
16167 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16168 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16169 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16170
16171 /* Mic (rear) pin: input vref at 80% */
16172 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16173 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16174 /* Front Mic pin: input vref at 80% */
16175 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16176 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16177 /* Line In pin: input */
16178 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16179 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16180 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16181 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16182 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16183 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16184 /* CD pin widget for input */
16185 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16186
16187 { }
16188};
16189
bdd148a3
KY
16190static struct hda_verb alc861vd_eapd_verbs[] = {
16191 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16192 { }
16193};
16194
f9423e7a
KY
16195static struct hda_verb alc660vd_eapd_verbs[] = {
16196 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16197 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16198 { }
16199};
16200
bdd148a3
KY
16201static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16202 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16203 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16204 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16205 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16206 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16207 {}
16208};
16209
bdd148a3
KY
16210static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
16211{
16212 unsigned int present;
16213 unsigned char bits;
16214
864f92be 16215 present = snd_hda_jack_detect(codec, 0x18);
47fd830a 16216 bits = present ? HDA_AMP_MUTE : 0;
864f92be 16217
47fd830a
TI
16218 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
16219 HDA_AMP_MUTE, bits);
bdd148a3
KY
16220}
16221
4f5d1706 16222static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16223{
a9fd4f3f 16224 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16225 spec->autocfg.hp_pins[0] = 0x1b;
16226 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
16227}
16228
16229static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16230{
a9fd4f3f 16231 alc_automute_amp(codec);
bdd148a3
KY
16232 alc861vd_lenovo_mic_automute(codec);
16233}
16234
16235static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16236 unsigned int res)
16237{
16238 switch (res >> 26) {
bdd148a3
KY
16239 case ALC880_MIC_EVENT:
16240 alc861vd_lenovo_mic_automute(codec);
16241 break;
a9fd4f3f
TI
16242 default:
16243 alc_automute_amp_unsol_event(codec, res);
16244 break;
bdd148a3
KY
16245 }
16246}
16247
272a527c
KY
16248static struct hda_verb alc861vd_dallas_verbs[] = {
16249 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16250 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16251 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16252 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16253
16254 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16255 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16256 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16257 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16258 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16259 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16260 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16261 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16262
272a527c
KY
16263 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16264 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16265 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16266 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16267 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16268 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16269 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16270 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16271
16272 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16273 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16274 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16275 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16276 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16277 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16278 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16279 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16280
16281 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16282 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16283 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16284 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16285
16286 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16287 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16288 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16289
16290 { } /* end */
16291};
16292
16293/* toggle speaker-output according to the hp-jack state */
4f5d1706 16294static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16295{
a9fd4f3f 16296 struct alc_spec *spec = codec->spec;
272a527c 16297
a9fd4f3f
TI
16298 spec->autocfg.hp_pins[0] = 0x15;
16299 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
16300}
16301
cb53c626
TI
16302#ifdef CONFIG_SND_HDA_POWER_SAVE
16303#define alc861vd_loopbacks alc880_loopbacks
16304#endif
16305
def319f9 16306/* pcm configuration: identical with ALC880 */
f32610ed
JS
16307#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16308#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16309#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16310#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16311
16312/*
16313 * configuration and preset
16314 */
16315static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
16316 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16317 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16318 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16319 [ALC861VD_3ST] = "3stack",
16320 [ALC861VD_3ST_DIG] = "3stack-digout",
16321 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16322 [ALC861VD_LENOVO] = "lenovo",
272a527c 16323 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16324 [ALC861VD_HP] = "hp",
f32610ed
JS
16325 [ALC861VD_AUTO] = "auto",
16326};
16327
16328static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16329 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16330 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16331 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16332 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16333 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16334 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16335 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16336 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16337 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16338 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16339 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16340 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16341 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16342 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16343 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16344 {}
16345};
16346
16347static struct alc_config_preset alc861vd_presets[] = {
16348 [ALC660VD_3ST] = {
16349 .mixers = { alc861vd_3st_mixer },
16350 .init_verbs = { alc861vd_volume_init_verbs,
16351 alc861vd_3stack_init_verbs },
16352 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16353 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16354 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16355 .channel_mode = alc861vd_3stack_2ch_modes,
16356 .input_mux = &alc861vd_capture_source,
16357 },
6963f84c
MC
16358 [ALC660VD_3ST_DIG] = {
16359 .mixers = { alc861vd_3st_mixer },
16360 .init_verbs = { alc861vd_volume_init_verbs,
16361 alc861vd_3stack_init_verbs },
16362 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16363 .dac_nids = alc660vd_dac_nids,
16364 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16365 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16366 .channel_mode = alc861vd_3stack_2ch_modes,
16367 .input_mux = &alc861vd_capture_source,
16368 },
f32610ed
JS
16369 [ALC861VD_3ST] = {
16370 .mixers = { alc861vd_3st_mixer },
16371 .init_verbs = { alc861vd_volume_init_verbs,
16372 alc861vd_3stack_init_verbs },
16373 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16374 .dac_nids = alc861vd_dac_nids,
16375 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16376 .channel_mode = alc861vd_3stack_2ch_modes,
16377 .input_mux = &alc861vd_capture_source,
16378 },
16379 [ALC861VD_3ST_DIG] = {
16380 .mixers = { alc861vd_3st_mixer },
16381 .init_verbs = { alc861vd_volume_init_verbs,
16382 alc861vd_3stack_init_verbs },
16383 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16384 .dac_nids = alc861vd_dac_nids,
16385 .dig_out_nid = ALC861VD_DIGOUT_NID,
16386 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16387 .channel_mode = alc861vd_3stack_2ch_modes,
16388 .input_mux = &alc861vd_capture_source,
16389 },
16390 [ALC861VD_6ST_DIG] = {
16391 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16392 .init_verbs = { alc861vd_volume_init_verbs,
16393 alc861vd_6stack_init_verbs },
16394 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16395 .dac_nids = alc861vd_dac_nids,
16396 .dig_out_nid = ALC861VD_DIGOUT_NID,
16397 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16398 .channel_mode = alc861vd_6stack_modes,
16399 .input_mux = &alc861vd_capture_source,
16400 },
bdd148a3
KY
16401 [ALC861VD_LENOVO] = {
16402 .mixers = { alc861vd_lenovo_mixer },
16403 .init_verbs = { alc861vd_volume_init_verbs,
16404 alc861vd_3stack_init_verbs,
16405 alc861vd_eapd_verbs,
16406 alc861vd_lenovo_unsol_verbs },
16407 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16408 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16409 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16410 .channel_mode = alc861vd_3stack_2ch_modes,
16411 .input_mux = &alc861vd_capture_source,
16412 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16413 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16414 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16415 },
272a527c
KY
16416 [ALC861VD_DALLAS] = {
16417 .mixers = { alc861vd_dallas_mixer },
16418 .init_verbs = { alc861vd_dallas_verbs },
16419 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16420 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16421 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16422 .channel_mode = alc861vd_3stack_2ch_modes,
16423 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 16424 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16425 .setup = alc861vd_dallas_setup,
16426 .init_hook = alc_automute_amp,
d1a991a6
KY
16427 },
16428 [ALC861VD_HP] = {
16429 .mixers = { alc861vd_hp_mixer },
16430 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16431 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16432 .dac_nids = alc861vd_dac_nids,
d1a991a6 16433 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
16434 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16435 .channel_mode = alc861vd_3stack_2ch_modes,
16436 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 16437 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16438 .setup = alc861vd_dallas_setup,
16439 .init_hook = alc_automute_amp,
ea1fb29a 16440 },
13c94744
TI
16441 [ALC660VD_ASUS_V1S] = {
16442 .mixers = { alc861vd_lenovo_mixer },
16443 .init_verbs = { alc861vd_volume_init_verbs,
16444 alc861vd_3stack_init_verbs,
16445 alc861vd_eapd_verbs,
16446 alc861vd_lenovo_unsol_verbs },
16447 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16448 .dac_nids = alc660vd_dac_nids,
16449 .dig_out_nid = ALC861VD_DIGOUT_NID,
16450 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16451 .channel_mode = alc861vd_3stack_2ch_modes,
16452 .input_mux = &alc861vd_capture_source,
16453 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16454 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16455 .init_hook = alc861vd_lenovo_init_hook,
13c94744 16456 },
f32610ed
JS
16457};
16458
16459/*
16460 * BIOS auto configuration
16461 */
05f5f477
TI
16462static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16463 const struct auto_pin_cfg *cfg)
16464{
6227cdce 16465 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
05f5f477
TI
16466}
16467
16468
f32610ed
JS
16469static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
16470 hda_nid_t nid, int pin_type, int dac_idx)
16471{
f6c7e546 16472 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
16473}
16474
16475static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
16476{
16477 struct alc_spec *spec = codec->spec;
16478 int i;
16479
16480 for (i = 0; i <= HDA_SIDE; i++) {
16481 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16482 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
16483 if (nid)
16484 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 16485 pin_type, i);
f32610ed
JS
16486 }
16487}
16488
16489
16490static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
16491{
16492 struct alc_spec *spec = codec->spec;
16493 hda_nid_t pin;
16494
16495 pin = spec->autocfg.hp_pins[0];
def319f9 16496 if (pin) /* connect to front and use dac 0 */
f32610ed 16497 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
16498 pin = spec->autocfg.speaker_pins[0];
16499 if (pin)
16500 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
16501}
16502
f32610ed
JS
16503#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
16504
16505static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
16506{
16507 struct alc_spec *spec = codec->spec;
16508 int i;
16509
16510 for (i = 0; i < AUTO_PIN_LAST; i++) {
16511 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 16512 if (alc_is_input_pin(codec, nid)) {
23f0c048 16513 alc_set_input_pin(codec, nid, i);
e82c025b
TI
16514 if (nid != ALC861VD_PIN_CD_NID &&
16515 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
16516 snd_hda_codec_write(codec, nid, 0,
16517 AC_VERB_SET_AMP_GAIN_MUTE,
16518 AMP_OUT_MUTE);
16519 }
16520 }
16521}
16522
f511b01c
TI
16523#define alc861vd_auto_init_input_src alc882_auto_init_input_src
16524
f32610ed
JS
16525#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16526#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16527
16528/* add playback controls from the parsed DAC table */
16529/* Based on ALC880 version. But ALC861VD has separate,
16530 * different NIDs for mute/unmute switch and volume control */
16531static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16532 const struct auto_pin_cfg *cfg)
16533{
f32610ed
JS
16534 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
16535 hda_nid_t nid_v, nid_s;
16536 int i, err;
16537
16538 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 16539 if (!spec->multiout.dac_nids[i])
f32610ed
JS
16540 continue;
16541 nid_v = alc861vd_idx_to_mixer_vol(
16542 alc880_dac_to_idx(
16543 spec->multiout.dac_nids[i]));
16544 nid_s = alc861vd_idx_to_mixer_switch(
16545 alc880_dac_to_idx(
16546 spec->multiout.dac_nids[i]));
16547
16548 if (i == 2) {
16549 /* Center/LFE */
0afe5f89
TI
16550 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16551 "Center",
f12ab1e0
TI
16552 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16553 HDA_OUTPUT));
16554 if (err < 0)
f32610ed 16555 return err;
0afe5f89
TI
16556 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16557 "LFE",
f12ab1e0
TI
16558 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16559 HDA_OUTPUT));
16560 if (err < 0)
f32610ed 16561 return err;
0afe5f89
TI
16562 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16563 "Center",
f12ab1e0
TI
16564 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
16565 HDA_INPUT));
16566 if (err < 0)
f32610ed 16567 return err;
0afe5f89
TI
16568 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16569 "LFE",
f12ab1e0
TI
16570 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
16571 HDA_INPUT));
16572 if (err < 0)
f32610ed
JS
16573 return err;
16574 } else {
a4fcd491
TI
16575 const char *pfx;
16576 if (cfg->line_outs == 1 &&
16577 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
16578 if (!cfg->hp_pins)
16579 pfx = "Speaker";
16580 else
16581 pfx = "PCM";
16582 } else
16583 pfx = chname[i];
0afe5f89 16584 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16585 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16586 HDA_OUTPUT));
16587 if (err < 0)
f32610ed 16588 return err;
a4fcd491
TI
16589 if (cfg->line_outs == 1 &&
16590 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
16591 pfx = "Speaker";
0afe5f89 16592 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
bdd148a3 16593 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
16594 HDA_INPUT));
16595 if (err < 0)
f32610ed
JS
16596 return err;
16597 }
16598 }
16599 return 0;
16600}
16601
16602/* add playback controls for speaker and HP outputs */
16603/* Based on ALC880 version. But ALC861VD has separate,
16604 * different NIDs for mute/unmute switch and volume control */
16605static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16606 hda_nid_t pin, const char *pfx)
16607{
16608 hda_nid_t nid_v, nid_s;
16609 int err;
f32610ed 16610
f12ab1e0 16611 if (!pin)
f32610ed
JS
16612 return 0;
16613
16614 if (alc880_is_fixed_pin(pin)) {
16615 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16616 /* specify the DAC as the extra output */
f12ab1e0 16617 if (!spec->multiout.hp_nid)
f32610ed
JS
16618 spec->multiout.hp_nid = nid_v;
16619 else
16620 spec->multiout.extra_out_nid[0] = nid_v;
16621 /* control HP volume/switch on the output mixer amp */
16622 nid_v = alc861vd_idx_to_mixer_vol(
16623 alc880_fixed_pin_idx(pin));
16624 nid_s = alc861vd_idx_to_mixer_switch(
16625 alc880_fixed_pin_idx(pin));
16626
0afe5f89 16627 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16628 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
16629 if (err < 0)
f32610ed 16630 return err;
0afe5f89 16631 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
16632 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
16633 if (err < 0)
f32610ed
JS
16634 return err;
16635 } else if (alc880_is_multi_pin(pin)) {
16636 /* set manual connection */
16637 /* we have only a switch on HP-out PIN */
0afe5f89 16638 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
16639 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16640 if (err < 0)
f32610ed
JS
16641 return err;
16642 }
16643 return 0;
16644}
16645
16646/* parse the BIOS configuration and set up the alc_spec
16647 * return 1 if successful, 0 if the proper config is not found,
16648 * or a negative error code
16649 * Based on ALC880 version - had to change it to override
16650 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
16651static int alc861vd_parse_auto_config(struct hda_codec *codec)
16652{
16653 struct alc_spec *spec = codec->spec;
16654 int err;
16655 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
16656
f12ab1e0
TI
16657 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16658 alc861vd_ignore);
16659 if (err < 0)
f32610ed 16660 return err;
f12ab1e0 16661 if (!spec->autocfg.line_outs)
f32610ed
JS
16662 return 0; /* can't find valid BIOS pin config */
16663
f12ab1e0
TI
16664 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16665 if (err < 0)
16666 return err;
16667 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
16668 if (err < 0)
16669 return err;
16670 err = alc861vd_auto_create_extra_out(spec,
16671 spec->autocfg.speaker_pins[0],
16672 "Speaker");
16673 if (err < 0)
16674 return err;
16675 err = alc861vd_auto_create_extra_out(spec,
16676 spec->autocfg.hp_pins[0],
16677 "Headphone");
16678 if (err < 0)
16679 return err;
05f5f477 16680 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16681 if (err < 0)
f32610ed
JS
16682 return err;
16683
16684 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16685
757899ac 16686 alc_auto_parse_digital(codec);
f32610ed 16687
603c4019 16688 if (spec->kctls.list)
d88897ea 16689 add_mixer(spec, spec->kctls.list);
f32610ed 16690
d88897ea 16691 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
16692
16693 spec->num_mux_defs = 1;
61b9b9b1 16694 spec->input_mux = &spec->private_imux[0];
f32610ed 16695
776e184e
TI
16696 err = alc_auto_add_mic_boost(codec);
16697 if (err < 0)
16698 return err;
16699
6227cdce 16700 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 16701
f32610ed
JS
16702 return 1;
16703}
16704
16705/* additional initialization for auto-configuration model */
16706static void alc861vd_auto_init(struct hda_codec *codec)
16707{
f6c7e546 16708 struct alc_spec *spec = codec->spec;
f32610ed
JS
16709 alc861vd_auto_init_multi_out(codec);
16710 alc861vd_auto_init_hp_out(codec);
16711 alc861vd_auto_init_analog_input(codec);
f511b01c 16712 alc861vd_auto_init_input_src(codec);
757899ac 16713 alc_auto_init_digital(codec);
f6c7e546 16714 if (spec->unsol_event)
7fb0d78f 16715 alc_inithook(codec);
f32610ed
JS
16716}
16717
f8f25ba3
TI
16718enum {
16719 ALC660VD_FIX_ASUS_GPIO1
16720};
16721
16722/* reset GPIO1 */
16723static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
16724 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
16725 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
16726 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
16727 { }
16728};
16729
16730static const struct alc_fixup alc861vd_fixups[] = {
16731 [ALC660VD_FIX_ASUS_GPIO1] = {
16732 .verbs = alc660vd_fix_asus_gpio1_verbs,
16733 },
16734};
16735
16736static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
16737 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
16738 {}
16739};
16740
f32610ed
JS
16741static int patch_alc861vd(struct hda_codec *codec)
16742{
16743 struct alc_spec *spec;
16744 int err, board_config;
16745
16746 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16747 if (spec == NULL)
16748 return -ENOMEM;
16749
16750 codec->spec = spec;
16751
16752 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
16753 alc861vd_models,
16754 alc861vd_cfg_tbl);
16755
16756 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
16757 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16758 codec->chip_name);
f32610ed
JS
16759 board_config = ALC861VD_AUTO;
16760 }
16761
7fa90e87
TI
16762 if (board_config == ALC861VD_AUTO)
16763 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
f8f25ba3 16764
f32610ed
JS
16765 if (board_config == ALC861VD_AUTO) {
16766 /* automatic parse from the BIOS config */
16767 err = alc861vd_parse_auto_config(codec);
16768 if (err < 0) {
16769 alc_free(codec);
16770 return err;
f12ab1e0 16771 } else if (!err) {
f32610ed
JS
16772 printk(KERN_INFO
16773 "hda_codec: Cannot set up configuration "
16774 "from BIOS. Using base mode...\n");
16775 board_config = ALC861VD_3ST;
16776 }
16777 }
16778
680cd536
KK
16779 err = snd_hda_attach_beep_device(codec, 0x23);
16780 if (err < 0) {
16781 alc_free(codec);
16782 return err;
16783 }
16784
f32610ed 16785 if (board_config != ALC861VD_AUTO)
e9c364c0 16786 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 16787
2f893286 16788 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 16789 /* always turn on EAPD */
d88897ea 16790 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
16791 }
16792
f32610ed
JS
16793 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
16794 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
16795
f32610ed
JS
16796 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
16797 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
16798
dd704698
TI
16799 if (!spec->adc_nids) {
16800 spec->adc_nids = alc861vd_adc_nids;
16801 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
16802 }
16803 if (!spec->capsrc_nids)
16804 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 16805
b59bdf3b 16806 set_capture_mixer(codec);
45bdd1c1 16807 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 16808
2134ea4f
TI
16809 spec->vmaster_nid = 0x02;
16810
7fa90e87
TI
16811 if (board_config == ALC861VD_AUTO)
16812 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
16813
f32610ed
JS
16814 codec->patch_ops = alc_patch_ops;
16815
16816 if (board_config == ALC861VD_AUTO)
16817 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
16818#ifdef CONFIG_SND_HDA_POWER_SAVE
16819 if (!spec->loopback.amplist)
16820 spec->loopback.amplist = alc861vd_loopbacks;
16821#endif
f32610ed
JS
16822
16823 return 0;
16824}
16825
bc9f98a9
KY
16826/*
16827 * ALC662 support
16828 *
16829 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
16830 * configuration. Each pin widget can choose any input DACs and a mixer.
16831 * Each ADC is connected from a mixer of all inputs. This makes possible
16832 * 6-channel independent captures.
16833 *
16834 * In addition, an independent DAC for the multi-playback (not used in this
16835 * driver yet).
16836 */
16837#define ALC662_DIGOUT_NID 0x06
16838#define ALC662_DIGIN_NID 0x0a
16839
16840static hda_nid_t alc662_dac_nids[4] = {
16841 /* front, rear, clfe, rear_surr */
16842 0x02, 0x03, 0x04
16843};
16844
622e84cd
KY
16845static hda_nid_t alc272_dac_nids[2] = {
16846 0x02, 0x03
16847};
16848
b59bdf3b 16849static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 16850 /* ADC1-2 */
b59bdf3b 16851 0x09, 0x08
bc9f98a9 16852};
e1406348 16853
622e84cd
KY
16854static hda_nid_t alc272_adc_nids[1] = {
16855 /* ADC1-2 */
16856 0x08,
16857};
16858
b59bdf3b 16859static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
16860static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
16861
e1406348 16862
bc9f98a9
KY
16863/* input MUX */
16864/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
16865static struct hda_input_mux alc662_capture_source = {
16866 .num_items = 4,
16867 .items = {
16868 { "Mic", 0x0 },
16869 { "Front Mic", 0x1 },
16870 { "Line", 0x2 },
16871 { "CD", 0x4 },
16872 },
16873};
16874
16875static struct hda_input_mux alc662_lenovo_101e_capture_source = {
16876 .num_items = 2,
16877 .items = {
16878 { "Mic", 0x1 },
16879 { "Line", 0x2 },
16880 },
16881};
291702f0 16882
6dda9f4a
KY
16883static struct hda_input_mux alc663_capture_source = {
16884 .num_items = 3,
16885 .items = {
16886 { "Mic", 0x0 },
16887 { "Front Mic", 0x1 },
16888 { "Line", 0x2 },
16889 },
16890};
16891
4f5d1706 16892#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
16893static struct hda_input_mux alc272_nc10_capture_source = {
16894 .num_items = 16,
16895 .items = {
16896 { "Autoselect Mic", 0x0 },
16897 { "Internal Mic", 0x1 },
16898 { "In-0x02", 0x2 },
16899 { "In-0x03", 0x3 },
16900 { "In-0x04", 0x4 },
16901 { "In-0x05", 0x5 },
16902 { "In-0x06", 0x6 },
16903 { "In-0x07", 0x7 },
16904 { "In-0x08", 0x8 },
16905 { "In-0x09", 0x9 },
16906 { "In-0x0a", 0x0a },
16907 { "In-0x0b", 0x0b },
16908 { "In-0x0c", 0x0c },
16909 { "In-0x0d", 0x0d },
16910 { "In-0x0e", 0x0e },
16911 { "In-0x0f", 0x0f },
16912 },
16913};
16914#endif
16915
bc9f98a9
KY
16916/*
16917 * 2ch mode
16918 */
16919static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
16920 { 2, NULL }
16921};
16922
16923/*
16924 * 2ch mode
16925 */
16926static struct hda_verb alc662_3ST_ch2_init[] = {
16927 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
16928 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16929 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
16930 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16931 { } /* end */
16932};
16933
16934/*
16935 * 6ch mode
16936 */
16937static struct hda_verb alc662_3ST_ch6_init[] = {
16938 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16939 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16940 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
16941 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16942 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16943 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
16944 { } /* end */
16945};
16946
16947static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
16948 { 2, alc662_3ST_ch2_init },
16949 { 6, alc662_3ST_ch6_init },
16950};
16951
16952/*
16953 * 2ch mode
16954 */
16955static struct hda_verb alc662_sixstack_ch6_init[] = {
16956 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16957 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16958 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16959 { } /* end */
16960};
16961
16962/*
16963 * 6ch mode
16964 */
16965static struct hda_verb alc662_sixstack_ch8_init[] = {
16966 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16967 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16968 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16969 { } /* end */
16970};
16971
16972static struct hda_channel_mode alc662_5stack_modes[2] = {
16973 { 2, alc662_sixstack_ch6_init },
16974 { 6, alc662_sixstack_ch8_init },
16975};
16976
16977/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16978 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16979 */
16980
16981static struct snd_kcontrol_new alc662_base_mixer[] = {
16982 /* output mixer control */
16983 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 16984 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 16985 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 16986 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
16987 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16988 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
16989 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16990 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
16991 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16992
16993 /*Input mixer control */
16994 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
16995 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
16996 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
16997 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
16998 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
16999 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17000 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17001 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17002 { } /* end */
17003};
17004
17005static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17006 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17007 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17008 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17009 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17010 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17011 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17012 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17013 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17014 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17015 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17016 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17017 { } /* end */
17018};
17019
17020static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17021 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17022 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17023 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17024 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17025 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17026 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17027 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17028 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17029 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17030 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17031 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17032 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17033 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17034 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17035 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17036 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17037 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17038 { } /* end */
17039};
17040
17041static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17042 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17043 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17044 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17045 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17046 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17047 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17048 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17049 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17050 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17051 { } /* end */
17052};
17053
291702f0 17054static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17055 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17056 ALC262_HIPPO_MASTER_SWITCH,
291702f0
KY
17057
17058 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
17059 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17060 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17061
17062 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
17063 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17064 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17065 { } /* end */
17066};
17067
8c427226 17068static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17069 ALC262_HIPPO_MASTER_SWITCH,
17070 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17071 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17072 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17073 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17074 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17075 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17076 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17077 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17078 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17079 { } /* end */
17080};
17081
f1d4e28b
KY
17082static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17083 .ops = &snd_hda_bind_vol,
17084 .values = {
17085 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17086 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17087 0
17088 },
17089};
17090
17091static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17092 .ops = &snd_hda_bind_sw,
17093 .values = {
17094 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17095 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17096 0
17097 },
17098};
17099
6dda9f4a 17100static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17101 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17102 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17103 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17104 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17105 { } /* end */
17106};
17107
17108static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17109 .ops = &snd_hda_bind_sw,
17110 .values = {
17111 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17112 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17113 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17114 0
17115 },
17116};
17117
17118static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17119 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17120 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17121 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17122 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17123 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17124 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17125
17126 { } /* end */
17127};
17128
17129static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17130 .ops = &snd_hda_bind_sw,
17131 .values = {
17132 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17133 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17134 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17135 0
17136 },
17137};
17138
17139static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17140 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17141 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17142 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17143 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17144 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17145 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17146 { } /* end */
17147};
17148
17149static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17150 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17151 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17152 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17153 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17154 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17155 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17156 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17157 { } /* end */
17158};
17159
17160static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17161 .ops = &snd_hda_bind_vol,
17162 .values = {
17163 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17164 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17165 0
17166 },
17167};
17168
17169static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17170 .ops = &snd_hda_bind_sw,
17171 .values = {
17172 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17173 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17174 0
17175 },
17176};
17177
17178static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17179 HDA_BIND_VOL("Master Playback Volume",
17180 &alc663_asus_two_bind_master_vol),
17181 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17182 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17183 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17184 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17185 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17186 { } /* end */
17187};
17188
17189static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17190 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17191 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17192 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17193 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17194 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17195 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17196 { } /* end */
17197};
17198
17199static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17200 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17201 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17202 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17203 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17204 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17205
17206 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17207 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17208 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17209 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17210 { } /* end */
17211};
17212
17213static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17214 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17215 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17216 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17217
17218 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17219 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17220 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17221 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17222 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17223 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17224 { } /* end */
17225};
17226
ebb83eeb
KY
17227static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17228 .ops = &snd_hda_bind_sw,
17229 .values = {
17230 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17231 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17232 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17233 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17234 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17235 0
17236 },
17237};
17238
17239static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17240 .ops = &snd_hda_bind_sw,
17241 .values = {
17242 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17243 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17244 0
17245 },
17246};
17247
17248static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17249 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17250 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17251 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17252 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17253 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17254 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17255 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17256 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17257 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17258 { } /* end */
17259};
17260
17261static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17262 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17263 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17264 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17265 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17266 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17267 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17268 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17269 { } /* end */
17270};
17271
17272
bc9f98a9
KY
17273static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17274 {
17275 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17276 .name = "Channel Mode",
17277 .info = alc_ch_mode_info,
17278 .get = alc_ch_mode_get,
17279 .put = alc_ch_mode_put,
17280 },
17281 { } /* end */
17282};
17283
17284static struct hda_verb alc662_init_verbs[] = {
17285 /* ADC: mute amp left and right */
17286 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17287 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17288
b60dd394
KY
17289 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17290 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17291 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17292 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17293 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17294 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17295
17296 /* Front Pin: output 0 (0x0c) */
17297 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17298 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17299
17300 /* Rear Pin: output 1 (0x0d) */
17301 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17302 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17303
17304 /* CLFE Pin: output 2 (0x0e) */
17305 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17306 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17307
17308 /* Mic (rear) pin: input vref at 80% */
17309 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17310 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17311 /* Front Mic pin: input vref at 80% */
17312 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17313 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17314 /* Line In pin: input */
17315 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17316 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17317 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17318 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17319 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17320 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17321 /* CD pin widget for input */
17322 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17323
17324 /* FIXME: use matrix-type input source selection */
17325 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17326 /* Input mixer */
17327 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17328 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
17329
17330 /* always trun on EAPD */
17331 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17332 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17333
bc9f98a9
KY
17334 { }
17335};
17336
cec27c89
KY
17337static struct hda_verb alc663_init_verbs[] = {
17338 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17339 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17340 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17341 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17342 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17343 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17344 { }
17345};
17346
17347static struct hda_verb alc272_init_verbs[] = {
17348 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17349 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17350 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17351 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17352 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17353 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17354 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17355 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17356 { }
17357};
17358
bc9f98a9
KY
17359static struct hda_verb alc662_sue_init_verbs[] = {
17360 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17361 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17362 {}
17363};
17364
17365static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17366 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17367 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17368 {}
bc9f98a9
KY
17369};
17370
8c427226
KY
17371/* Set Unsolicited Event*/
17372static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17373 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17374 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17375 {}
17376};
17377
6dda9f4a 17378static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17379 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17380 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17381 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17382 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17383 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17384 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17385 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17386 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17387 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17388 {}
17389};
17390
17391static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17392 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17393 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17394 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17395 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17396 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17397 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17398 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17399 {}
17400};
17401
17402static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17403 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17404 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17405 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17406 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17407 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17408 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17409 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17410 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17411 {}
17412};
6dda9f4a 17413
f1d4e28b
KY
17414static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17415 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17416 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17417 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17418 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17419 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17420 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17421 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17422 {}
17423};
6dda9f4a 17424
f1d4e28b
KY
17425static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17426 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17427 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17428 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17429 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17430 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17431 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17432 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17433 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17434 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
17435 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17436 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
17437 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17438 {}
17439};
17440
17441static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17442 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17443 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17444 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17445 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17446 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17447 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17448 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17449 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17450 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17451 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17452 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17453 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
17454 {}
17455};
17456
17457static struct hda_verb alc663_g71v_init_verbs[] = {
17458 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17459 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17460 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17461
17462 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17463 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17464 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17465
17466 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17467 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17468 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17469 {}
17470};
17471
17472static struct hda_verb alc663_g50v_init_verbs[] = {
17473 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17474 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17475 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17476
17477 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17478 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17479 {}
17480};
17481
f1d4e28b
KY
17482static struct hda_verb alc662_ecs_init_verbs[] = {
17483 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17484 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17485 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17486 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17487 {}
17488};
17489
622e84cd
KY
17490static struct hda_verb alc272_dell_zm1_init_verbs[] = {
17491 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17492 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17493 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17494 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17495 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17496 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17497 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17498 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17499 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17500 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17501 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17502 {}
17503};
17504
17505static struct hda_verb alc272_dell_init_verbs[] = {
17506 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17507 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17508 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17509 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17510 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17511 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17512 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17513 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17514 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17515 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17516 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17517 {}
17518};
17519
ebb83eeb
KY
17520static struct hda_verb alc663_mode7_init_verbs[] = {
17521 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17522 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17523 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17524 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17525 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17526 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17527 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17528 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17529 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17530 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17531 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17533 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17534 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17535 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17536 {}
17537};
17538
17539static struct hda_verb alc663_mode8_init_verbs[] = {
17540 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17541 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17542 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17543 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17544 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17545 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17546 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17547 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17548 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17549 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17550 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17551 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17552 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17553 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17554 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17555 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17556 {}
17557};
17558
f1d4e28b
KY
17559static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17560 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17561 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17562 { } /* end */
17563};
17564
622e84cd
KY
17565static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17566 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17567 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17568 { } /* end */
17569};
17570
bc9f98a9
KY
17571static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
17572{
17573 unsigned int present;
f12ab1e0 17574 unsigned char bits;
bc9f98a9 17575
864f92be 17576 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 17577 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17578
47fd830a
TI
17579 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17580 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17581}
17582
17583static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
17584{
17585 unsigned int present;
f12ab1e0 17586 unsigned char bits;
bc9f98a9 17587
864f92be 17588 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 17589 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17590
47fd830a
TI
17591 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17592 HDA_AMP_MUTE, bits);
17593 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17594 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17595}
17596
17597static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
17598 unsigned int res)
17599{
17600 if ((res >> 26) == ALC880_HP_EVENT)
17601 alc662_lenovo_101e_all_automute(codec);
17602 if ((res >> 26) == ALC880_FRONT_EVENT)
17603 alc662_lenovo_101e_ispeaker_automute(codec);
17604}
17605
291702f0
KY
17606/* unsolicited event for HP jack sensing */
17607static void alc662_eeepc_unsol_event(struct hda_codec *codec,
17608 unsigned int res)
17609{
291702f0 17610 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 17611 alc_mic_automute(codec);
42171c17
TI
17612 else
17613 alc262_hippo_unsol_event(codec, res);
291702f0
KY
17614}
17615
4f5d1706
TI
17616static void alc662_eeepc_setup(struct hda_codec *codec)
17617{
17618 struct alc_spec *spec = codec->spec;
17619
17620 alc262_hippo1_setup(codec);
17621 spec->ext_mic.pin = 0x18;
17622 spec->ext_mic.mux_idx = 0;
17623 spec->int_mic.pin = 0x19;
17624 spec->int_mic.mux_idx = 1;
17625 spec->auto_mic = 1;
17626}
17627
291702f0
KY
17628static void alc662_eeepc_inithook(struct hda_codec *codec)
17629{
4f5d1706
TI
17630 alc262_hippo_automute(codec);
17631 alc_mic_automute(codec);
291702f0
KY
17632}
17633
4f5d1706 17634static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 17635{
42171c17
TI
17636 struct alc_spec *spec = codec->spec;
17637
17638 spec->autocfg.hp_pins[0] = 0x14;
17639 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
17640}
17641
4f5d1706
TI
17642#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
17643
6dda9f4a
KY
17644static void alc663_m51va_speaker_automute(struct hda_codec *codec)
17645{
17646 unsigned int present;
17647 unsigned char bits;
17648
864f92be 17649 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 17650 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 17651 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17652 HDA_AMP_MUTE, bits);
f1d4e28b 17653 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17654 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17655}
17656
17657static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
17658{
17659 unsigned int present;
17660 unsigned char bits;
17661
864f92be 17662 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
17663 bits = present ? HDA_AMP_MUTE : 0;
17664 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17665 HDA_AMP_MUTE, bits);
f1d4e28b 17666 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17667 HDA_AMP_MUTE, bits);
f1d4e28b 17668 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 17669 HDA_AMP_MUTE, bits);
f1d4e28b 17670 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 17671 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17672}
17673
17674static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
17675{
17676 unsigned int present;
17677 unsigned char bits;
17678
864f92be 17679 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17680 bits = present ? HDA_AMP_MUTE : 0;
17681 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17682 HDA_AMP_MUTE, bits);
f1d4e28b 17683 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17684 HDA_AMP_MUTE, bits);
f1d4e28b 17685 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 17686 HDA_AMP_MUTE, bits);
f1d4e28b 17687 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 17688 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17689}
17690
17691static void alc662_f5z_speaker_automute(struct hda_codec *codec)
17692{
17693 unsigned int present;
17694 unsigned char bits;
17695
864f92be 17696 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
17697 bits = present ? 0 : PIN_OUT;
17698 snd_hda_codec_write(codec, 0x14, 0,
17699 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
17700}
17701
17702static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
17703{
17704 unsigned int present1, present2;
17705
864f92be
WF
17706 present1 = snd_hda_jack_detect(codec, 0x21);
17707 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17708
17709 if (present1 || present2) {
17710 snd_hda_codec_write_cache(codec, 0x14, 0,
17711 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17712 } else {
17713 snd_hda_codec_write_cache(codec, 0x14, 0,
17714 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17715 }
17716}
17717
17718static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
17719{
17720 unsigned int present1, present2;
17721
864f92be
WF
17722 present1 = snd_hda_jack_detect(codec, 0x1b);
17723 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17724
17725 if (present1 || present2) {
17726 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17727 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 17728 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17729 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
17730 } else {
17731 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17732 HDA_AMP_MUTE, 0);
f1d4e28b 17733 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17734 HDA_AMP_MUTE, 0);
f1d4e28b 17735 }
6dda9f4a
KY
17736}
17737
ebb83eeb
KY
17738static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
17739{
17740 unsigned int present1, present2;
17741
17742 present1 = snd_hda_codec_read(codec, 0x1b, 0,
17743 AC_VERB_GET_PIN_SENSE, 0)
17744 & AC_PINSENSE_PRESENCE;
17745 present2 = snd_hda_codec_read(codec, 0x21, 0,
17746 AC_VERB_GET_PIN_SENSE, 0)
17747 & AC_PINSENSE_PRESENCE;
17748
17749 if (present1 || present2) {
17750 snd_hda_codec_write_cache(codec, 0x14, 0,
17751 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17752 snd_hda_codec_write_cache(codec, 0x17, 0,
17753 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17754 } else {
17755 snd_hda_codec_write_cache(codec, 0x14, 0,
17756 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17757 snd_hda_codec_write_cache(codec, 0x17, 0,
17758 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17759 }
17760}
17761
17762static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
17763{
17764 unsigned int present1, present2;
17765
17766 present1 = snd_hda_codec_read(codec, 0x21, 0,
17767 AC_VERB_GET_PIN_SENSE, 0)
17768 & AC_PINSENSE_PRESENCE;
17769 present2 = snd_hda_codec_read(codec, 0x15, 0,
17770 AC_VERB_GET_PIN_SENSE, 0)
17771 & AC_PINSENSE_PRESENCE;
17772
17773 if (present1 || present2) {
17774 snd_hda_codec_write_cache(codec, 0x14, 0,
17775 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17776 snd_hda_codec_write_cache(codec, 0x17, 0,
17777 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17778 } else {
17779 snd_hda_codec_write_cache(codec, 0x14, 0,
17780 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17781 snd_hda_codec_write_cache(codec, 0x17, 0,
17782 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17783 }
17784}
17785
6dda9f4a
KY
17786static void alc663_m51va_unsol_event(struct hda_codec *codec,
17787 unsigned int res)
17788{
17789 switch (res >> 26) {
17790 case ALC880_HP_EVENT:
17791 alc663_m51va_speaker_automute(codec);
17792 break;
17793 case ALC880_MIC_EVENT:
4f5d1706 17794 alc_mic_automute(codec);
6dda9f4a
KY
17795 break;
17796 }
17797}
17798
4f5d1706
TI
17799static void alc663_m51va_setup(struct hda_codec *codec)
17800{
17801 struct alc_spec *spec = codec->spec;
17802 spec->ext_mic.pin = 0x18;
17803 spec->ext_mic.mux_idx = 0;
17804 spec->int_mic.pin = 0x12;
ebb83eeb 17805 spec->int_mic.mux_idx = 9;
4f5d1706
TI
17806 spec->auto_mic = 1;
17807}
17808
6dda9f4a
KY
17809static void alc663_m51va_inithook(struct hda_codec *codec)
17810{
17811 alc663_m51va_speaker_automute(codec);
4f5d1706 17812 alc_mic_automute(codec);
6dda9f4a
KY
17813}
17814
f1d4e28b 17815/* ***************** Mode1 ******************************/
4f5d1706 17816#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
17817
17818static void alc663_mode1_setup(struct hda_codec *codec)
17819{
17820 struct alc_spec *spec = codec->spec;
17821 spec->ext_mic.pin = 0x18;
17822 spec->ext_mic.mux_idx = 0;
17823 spec->int_mic.pin = 0x19;
17824 spec->int_mic.mux_idx = 1;
17825 spec->auto_mic = 1;
17826}
17827
4f5d1706 17828#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 17829
f1d4e28b
KY
17830/* ***************** Mode2 ******************************/
17831static void alc662_mode2_unsol_event(struct hda_codec *codec,
17832 unsigned int res)
17833{
17834 switch (res >> 26) {
17835 case ALC880_HP_EVENT:
17836 alc662_f5z_speaker_automute(codec);
17837 break;
17838 case ALC880_MIC_EVENT:
4f5d1706 17839 alc_mic_automute(codec);
f1d4e28b
KY
17840 break;
17841 }
17842}
17843
ebb83eeb 17844#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 17845
f1d4e28b
KY
17846static void alc662_mode2_inithook(struct hda_codec *codec)
17847{
17848 alc662_f5z_speaker_automute(codec);
4f5d1706 17849 alc_mic_automute(codec);
f1d4e28b
KY
17850}
17851/* ***************** Mode3 ******************************/
17852static void alc663_mode3_unsol_event(struct hda_codec *codec,
17853 unsigned int res)
17854{
17855 switch (res >> 26) {
17856 case ALC880_HP_EVENT:
17857 alc663_two_hp_m1_speaker_automute(codec);
17858 break;
17859 case ALC880_MIC_EVENT:
4f5d1706 17860 alc_mic_automute(codec);
f1d4e28b
KY
17861 break;
17862 }
17863}
17864
ebb83eeb 17865#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 17866
f1d4e28b
KY
17867static void alc663_mode3_inithook(struct hda_codec *codec)
17868{
17869 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 17870 alc_mic_automute(codec);
f1d4e28b
KY
17871}
17872/* ***************** Mode4 ******************************/
17873static void alc663_mode4_unsol_event(struct hda_codec *codec,
17874 unsigned int res)
17875{
17876 switch (res >> 26) {
17877 case ALC880_HP_EVENT:
17878 alc663_21jd_two_speaker_automute(codec);
17879 break;
17880 case ALC880_MIC_EVENT:
4f5d1706 17881 alc_mic_automute(codec);
f1d4e28b
KY
17882 break;
17883 }
17884}
17885
ebb83eeb 17886#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 17887
f1d4e28b
KY
17888static void alc663_mode4_inithook(struct hda_codec *codec)
17889{
17890 alc663_21jd_two_speaker_automute(codec);
4f5d1706 17891 alc_mic_automute(codec);
f1d4e28b
KY
17892}
17893/* ***************** Mode5 ******************************/
17894static void alc663_mode5_unsol_event(struct hda_codec *codec,
17895 unsigned int res)
17896{
17897 switch (res >> 26) {
17898 case ALC880_HP_EVENT:
17899 alc663_15jd_two_speaker_automute(codec);
17900 break;
17901 case ALC880_MIC_EVENT:
4f5d1706 17902 alc_mic_automute(codec);
f1d4e28b
KY
17903 break;
17904 }
17905}
17906
ebb83eeb 17907#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 17908
f1d4e28b
KY
17909static void alc663_mode5_inithook(struct hda_codec *codec)
17910{
17911 alc663_15jd_two_speaker_automute(codec);
4f5d1706 17912 alc_mic_automute(codec);
f1d4e28b
KY
17913}
17914/* ***************** Mode6 ******************************/
17915static void alc663_mode6_unsol_event(struct hda_codec *codec,
17916 unsigned int res)
17917{
17918 switch (res >> 26) {
17919 case ALC880_HP_EVENT:
17920 alc663_two_hp_m2_speaker_automute(codec);
17921 break;
17922 case ALC880_MIC_EVENT:
4f5d1706 17923 alc_mic_automute(codec);
f1d4e28b
KY
17924 break;
17925 }
17926}
17927
ebb83eeb 17928#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 17929
f1d4e28b
KY
17930static void alc663_mode6_inithook(struct hda_codec *codec)
17931{
17932 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 17933 alc_mic_automute(codec);
f1d4e28b
KY
17934}
17935
ebb83eeb
KY
17936/* ***************** Mode7 ******************************/
17937static void alc663_mode7_unsol_event(struct hda_codec *codec,
17938 unsigned int res)
17939{
17940 switch (res >> 26) {
17941 case ALC880_HP_EVENT:
17942 alc663_two_hp_m7_speaker_automute(codec);
17943 break;
17944 case ALC880_MIC_EVENT:
17945 alc_mic_automute(codec);
17946 break;
17947 }
17948}
17949
17950#define alc663_mode7_setup alc663_mode1_setup
17951
17952static void alc663_mode7_inithook(struct hda_codec *codec)
17953{
17954 alc663_two_hp_m7_speaker_automute(codec);
17955 alc_mic_automute(codec);
17956}
17957
17958/* ***************** Mode8 ******************************/
17959static void alc663_mode8_unsol_event(struct hda_codec *codec,
17960 unsigned int res)
17961{
17962 switch (res >> 26) {
17963 case ALC880_HP_EVENT:
17964 alc663_two_hp_m8_speaker_automute(codec);
17965 break;
17966 case ALC880_MIC_EVENT:
17967 alc_mic_automute(codec);
17968 break;
17969 }
17970}
17971
17972#define alc663_mode8_setup alc663_m51va_setup
17973
17974static void alc663_mode8_inithook(struct hda_codec *codec)
17975{
17976 alc663_two_hp_m8_speaker_automute(codec);
17977 alc_mic_automute(codec);
17978}
17979
6dda9f4a
KY
17980static void alc663_g71v_hp_automute(struct hda_codec *codec)
17981{
17982 unsigned int present;
17983 unsigned char bits;
17984
864f92be 17985 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
17986 bits = present ? HDA_AMP_MUTE : 0;
17987 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17988 HDA_AMP_MUTE, bits);
17989 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17990 HDA_AMP_MUTE, bits);
17991}
17992
17993static void alc663_g71v_front_automute(struct hda_codec *codec)
17994{
17995 unsigned int present;
17996 unsigned char bits;
17997
864f92be 17998 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
17999 bits = present ? HDA_AMP_MUTE : 0;
18000 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18001 HDA_AMP_MUTE, bits);
18002}
18003
18004static void alc663_g71v_unsol_event(struct hda_codec *codec,
18005 unsigned int res)
18006{
18007 switch (res >> 26) {
18008 case ALC880_HP_EVENT:
18009 alc663_g71v_hp_automute(codec);
18010 break;
18011 case ALC880_FRONT_EVENT:
18012 alc663_g71v_front_automute(codec);
18013 break;
18014 case ALC880_MIC_EVENT:
4f5d1706 18015 alc_mic_automute(codec);
6dda9f4a
KY
18016 break;
18017 }
18018}
18019
4f5d1706
TI
18020#define alc663_g71v_setup alc663_m51va_setup
18021
6dda9f4a
KY
18022static void alc663_g71v_inithook(struct hda_codec *codec)
18023{
18024 alc663_g71v_front_automute(codec);
18025 alc663_g71v_hp_automute(codec);
4f5d1706 18026 alc_mic_automute(codec);
6dda9f4a
KY
18027}
18028
18029static void alc663_g50v_unsol_event(struct hda_codec *codec,
18030 unsigned int res)
18031{
18032 switch (res >> 26) {
18033 case ALC880_HP_EVENT:
18034 alc663_m51va_speaker_automute(codec);
18035 break;
18036 case ALC880_MIC_EVENT:
4f5d1706 18037 alc_mic_automute(codec);
6dda9f4a
KY
18038 break;
18039 }
18040}
18041
4f5d1706
TI
18042#define alc663_g50v_setup alc663_m51va_setup
18043
6dda9f4a
KY
18044static void alc663_g50v_inithook(struct hda_codec *codec)
18045{
18046 alc663_m51va_speaker_automute(codec);
4f5d1706 18047 alc_mic_automute(codec);
6dda9f4a
KY
18048}
18049
f1d4e28b
KY
18050static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18051 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18052 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b
KY
18053
18054 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
18055 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18056 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18057
18058 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
18059 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18060 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18061 { } /* end */
18062};
18063
9541ba1d
CP
18064static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18065 /* Master Playback automatically created from Speaker and Headphone */
18066 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18067 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18068 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18069 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18070
18071 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18072 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18073 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
18074
18075 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18076 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18077 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
18078 { } /* end */
18079};
18080
cb53c626
TI
18081#ifdef CONFIG_SND_HDA_POWER_SAVE
18082#define alc662_loopbacks alc880_loopbacks
18083#endif
18084
bc9f98a9 18085
def319f9 18086/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18087#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18088#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18089#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18090#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18091
18092/*
18093 * configuration and preset
18094 */
18095static const char *alc662_models[ALC662_MODEL_LAST] = {
18096 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18097 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18098 [ALC662_3ST_6ch] = "3stack-6ch",
18099 [ALC662_5ST_DIG] = "6stack-dig",
18100 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18101 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18102 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18103 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18104 [ALC663_ASUS_M51VA] = "m51va",
18105 [ALC663_ASUS_G71V] = "g71v",
18106 [ALC663_ASUS_H13] = "h13",
18107 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18108 [ALC663_ASUS_MODE1] = "asus-mode1",
18109 [ALC662_ASUS_MODE2] = "asus-mode2",
18110 [ALC663_ASUS_MODE3] = "asus-mode3",
18111 [ALC663_ASUS_MODE4] = "asus-mode4",
18112 [ALC663_ASUS_MODE5] = "asus-mode5",
18113 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18114 [ALC663_ASUS_MODE7] = "asus-mode7",
18115 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18116 [ALC272_DELL] = "dell",
18117 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18118 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18119 [ALC662_AUTO] = "auto",
18120};
18121
18122static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18123 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18124 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18125 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18126 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18127 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18128 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18129 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18130 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18131 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18132 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18133 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18134 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18135 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18136 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18137 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18138 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18139 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18140 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18141 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18142 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18143 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18144 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18145 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18146 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18147 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18148 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18149 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18150 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18151 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18152 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18153 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18154 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18155 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18156 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18157 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18158 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18159 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18160 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18161 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18162 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18163 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18164 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18165 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18166 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18167 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18168 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18169 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18170 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18171 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18172 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18173 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18174 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18175 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18176 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18177 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18178 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18179 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18180 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18181 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18182 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18183 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18184 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18185 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18186 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18187 ALC662_3ST_6ch_DIG),
4dee8baa 18188 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18189 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
18190 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18191 ALC662_3ST_6ch_DIG),
6227cdce 18192 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18193 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18194 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18195 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18196 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18197 ALC662_3ST_6ch_DIG),
dea0a509
TI
18198 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18199 ALC663_ASUS_H13),
bc9f98a9
KY
18200 {}
18201};
18202
18203static struct alc_config_preset alc662_presets[] = {
18204 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18205 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
18206 .init_verbs = { alc662_init_verbs },
18207 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18208 .dac_nids = alc662_dac_nids,
18209 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18210 .dig_in_nid = ALC662_DIGIN_NID,
18211 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18212 .channel_mode = alc662_3ST_2ch_modes,
18213 .input_mux = &alc662_capture_source,
18214 },
18215 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18216 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18217 .init_verbs = { alc662_init_verbs },
18218 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18219 .dac_nids = alc662_dac_nids,
18220 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18221 .dig_in_nid = ALC662_DIGIN_NID,
18222 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18223 .channel_mode = alc662_3ST_6ch_modes,
18224 .need_dac_fix = 1,
18225 .input_mux = &alc662_capture_source,
f12ab1e0 18226 },
bc9f98a9 18227 [ALC662_3ST_6ch] = {
f9e336f6 18228 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18229 .init_verbs = { alc662_init_verbs },
18230 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18231 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18232 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18233 .channel_mode = alc662_3ST_6ch_modes,
18234 .need_dac_fix = 1,
18235 .input_mux = &alc662_capture_source,
f12ab1e0 18236 },
bc9f98a9 18237 [ALC662_5ST_DIG] = {
f9e336f6 18238 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18239 .init_verbs = { alc662_init_verbs },
18240 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18241 .dac_nids = alc662_dac_nids,
18242 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18243 .dig_in_nid = ALC662_DIGIN_NID,
18244 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18245 .channel_mode = alc662_5stack_modes,
18246 .input_mux = &alc662_capture_source,
18247 },
18248 [ALC662_LENOVO_101E] = {
f9e336f6 18249 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
18250 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18251 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18252 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18253 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18254 .channel_mode = alc662_3ST_2ch_modes,
18255 .input_mux = &alc662_lenovo_101e_capture_source,
18256 .unsol_event = alc662_lenovo_101e_unsol_event,
18257 .init_hook = alc662_lenovo_101e_all_automute,
18258 },
291702f0 18259 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18260 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
18261 .init_verbs = { alc662_init_verbs,
18262 alc662_eeepc_sue_init_verbs },
18263 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18264 .dac_nids = alc662_dac_nids,
291702f0
KY
18265 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18266 .channel_mode = alc662_3ST_2ch_modes,
291702f0 18267 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18268 .setup = alc662_eeepc_setup,
291702f0
KY
18269 .init_hook = alc662_eeepc_inithook,
18270 },
8c427226 18271 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18272 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18273 alc662_chmode_mixer },
18274 .init_verbs = { alc662_init_verbs,
18275 alc662_eeepc_ep20_sue_init_verbs },
18276 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18277 .dac_nids = alc662_dac_nids,
8c427226
KY
18278 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18279 .channel_mode = alc662_3ST_6ch_modes,
18280 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 18281 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18282 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
18283 .init_hook = alc662_eeepc_ep20_inithook,
18284 },
f1d4e28b 18285 [ALC662_ECS] = {
f9e336f6 18286 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
18287 .init_verbs = { alc662_init_verbs,
18288 alc662_ecs_init_verbs },
18289 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18290 .dac_nids = alc662_dac_nids,
18291 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18292 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18293 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18294 .setup = alc662_eeepc_setup,
f1d4e28b
KY
18295 .init_hook = alc662_eeepc_inithook,
18296 },
6dda9f4a 18297 [ALC663_ASUS_M51VA] = {
f9e336f6 18298 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18299 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18300 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18301 .dac_nids = alc662_dac_nids,
18302 .dig_out_nid = ALC662_DIGOUT_NID,
18303 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18304 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18305 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18306 .setup = alc663_m51va_setup,
6dda9f4a
KY
18307 .init_hook = alc663_m51va_inithook,
18308 },
18309 [ALC663_ASUS_G71V] = {
f9e336f6 18310 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
18311 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18312 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18313 .dac_nids = alc662_dac_nids,
18314 .dig_out_nid = ALC662_DIGOUT_NID,
18315 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18316 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18317 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 18318 .setup = alc663_g71v_setup,
6dda9f4a
KY
18319 .init_hook = alc663_g71v_inithook,
18320 },
18321 [ALC663_ASUS_H13] = {
f9e336f6 18322 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18323 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18324 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18325 .dac_nids = alc662_dac_nids,
18326 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18327 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
18328 .unsol_event = alc663_m51va_unsol_event,
18329 .init_hook = alc663_m51va_inithook,
18330 },
18331 [ALC663_ASUS_G50V] = {
f9e336f6 18332 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
18333 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18334 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18335 .dac_nids = alc662_dac_nids,
18336 .dig_out_nid = ALC662_DIGOUT_NID,
18337 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18338 .channel_mode = alc662_3ST_6ch_modes,
18339 .input_mux = &alc663_capture_source,
18340 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 18341 .setup = alc663_g50v_setup,
6dda9f4a
KY
18342 .init_hook = alc663_g50v_inithook,
18343 },
f1d4e28b 18344 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18345 .mixers = { alc663_m51va_mixer },
18346 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18347 .init_verbs = { alc662_init_verbs,
18348 alc663_21jd_amic_init_verbs },
18349 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18350 .hp_nid = 0x03,
18351 .dac_nids = alc662_dac_nids,
18352 .dig_out_nid = ALC662_DIGOUT_NID,
18353 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18354 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18355 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18356 .setup = alc663_mode1_setup,
f1d4e28b
KY
18357 .init_hook = alc663_mode1_inithook,
18358 },
18359 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18360 .mixers = { alc662_1bjd_mixer },
18361 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18362 .init_verbs = { alc662_init_verbs,
18363 alc662_1bjd_amic_init_verbs },
18364 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18365 .dac_nids = alc662_dac_nids,
18366 .dig_out_nid = ALC662_DIGOUT_NID,
18367 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18368 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18369 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18370 .setup = alc662_mode2_setup,
f1d4e28b
KY
18371 .init_hook = alc662_mode2_inithook,
18372 },
18373 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18374 .mixers = { alc663_two_hp_m1_mixer },
18375 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18376 .init_verbs = { alc662_init_verbs,
18377 alc663_two_hp_amic_m1_init_verbs },
18378 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18379 .hp_nid = 0x03,
18380 .dac_nids = alc662_dac_nids,
18381 .dig_out_nid = ALC662_DIGOUT_NID,
18382 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18383 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18384 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 18385 .setup = alc663_mode3_setup,
f1d4e28b
KY
18386 .init_hook = alc663_mode3_inithook,
18387 },
18388 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18389 .mixers = { alc663_asus_21jd_clfe_mixer },
18390 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18391 .init_verbs = { alc662_init_verbs,
18392 alc663_21jd_amic_init_verbs},
18393 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18394 .hp_nid = 0x03,
18395 .dac_nids = alc662_dac_nids,
18396 .dig_out_nid = ALC662_DIGOUT_NID,
18397 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18398 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18399 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18400 .setup = alc663_mode4_setup,
f1d4e28b
KY
18401 .init_hook = alc663_mode4_inithook,
18402 },
18403 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18404 .mixers = { alc663_asus_15jd_clfe_mixer },
18405 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18406 .init_verbs = { alc662_init_verbs,
18407 alc663_15jd_amic_init_verbs },
18408 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18409 .hp_nid = 0x03,
18410 .dac_nids = alc662_dac_nids,
18411 .dig_out_nid = ALC662_DIGOUT_NID,
18412 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18413 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18414 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 18415 .setup = alc663_mode5_setup,
f1d4e28b
KY
18416 .init_hook = alc663_mode5_inithook,
18417 },
18418 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18419 .mixers = { alc663_two_hp_m2_mixer },
18420 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18421 .init_verbs = { alc662_init_verbs,
18422 alc663_two_hp_amic_m2_init_verbs },
18423 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18424 .hp_nid = 0x03,
18425 .dac_nids = alc662_dac_nids,
18426 .dig_out_nid = ALC662_DIGOUT_NID,
18427 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18428 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18429 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 18430 .setup = alc663_mode6_setup,
f1d4e28b
KY
18431 .init_hook = alc663_mode6_inithook,
18432 },
ebb83eeb
KY
18433 [ALC663_ASUS_MODE7] = {
18434 .mixers = { alc663_mode7_mixer },
18435 .cap_mixer = alc662_auto_capture_mixer,
18436 .init_verbs = { alc662_init_verbs,
18437 alc663_mode7_init_verbs },
18438 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18439 .hp_nid = 0x03,
18440 .dac_nids = alc662_dac_nids,
18441 .dig_out_nid = ALC662_DIGOUT_NID,
18442 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18443 .channel_mode = alc662_3ST_2ch_modes,
18444 .unsol_event = alc663_mode7_unsol_event,
18445 .setup = alc663_mode7_setup,
18446 .init_hook = alc663_mode7_inithook,
18447 },
18448 [ALC663_ASUS_MODE8] = {
18449 .mixers = { alc663_mode8_mixer },
18450 .cap_mixer = alc662_auto_capture_mixer,
18451 .init_verbs = { alc662_init_verbs,
18452 alc663_mode8_init_verbs },
18453 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18454 .hp_nid = 0x03,
18455 .dac_nids = alc662_dac_nids,
18456 .dig_out_nid = ALC662_DIGOUT_NID,
18457 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18458 .channel_mode = alc662_3ST_2ch_modes,
18459 .unsol_event = alc663_mode8_unsol_event,
18460 .setup = alc663_mode8_setup,
18461 .init_hook = alc663_mode8_inithook,
18462 },
622e84cd
KY
18463 [ALC272_DELL] = {
18464 .mixers = { alc663_m51va_mixer },
18465 .cap_mixer = alc272_auto_capture_mixer,
18466 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
18467 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18468 .dac_nids = alc662_dac_nids,
18469 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18470 .adc_nids = alc272_adc_nids,
18471 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18472 .capsrc_nids = alc272_capsrc_nids,
18473 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18474 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18475 .setup = alc663_m51va_setup,
622e84cd
KY
18476 .init_hook = alc663_m51va_inithook,
18477 },
18478 [ALC272_DELL_ZM1] = {
18479 .mixers = { alc663_m51va_mixer },
18480 .cap_mixer = alc662_auto_capture_mixer,
18481 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
18482 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18483 .dac_nids = alc662_dac_nids,
18484 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18485 .adc_nids = alc662_adc_nids,
b59bdf3b 18486 .num_adc_nids = 1,
622e84cd
KY
18487 .capsrc_nids = alc662_capsrc_nids,
18488 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18489 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18490 .setup = alc663_m51va_setup,
622e84cd
KY
18491 .init_hook = alc663_m51va_inithook,
18492 },
9541ba1d
CP
18493 [ALC272_SAMSUNG_NC10] = {
18494 .mixers = { alc272_nc10_mixer },
18495 .init_verbs = { alc662_init_verbs,
18496 alc663_21jd_amic_init_verbs },
18497 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18498 .dac_nids = alc272_dac_nids,
18499 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18500 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18501 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 18502 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18503 .setup = alc663_mode4_setup,
9541ba1d
CP
18504 .init_hook = alc663_mode4_inithook,
18505 },
bc9f98a9
KY
18506};
18507
18508
18509/*
18510 * BIOS auto configuration
18511 */
18512
7085ec12
TI
18513/* convert from MIX nid to DAC */
18514static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
18515{
18516 if (nid == 0x0f)
18517 return 0x02;
18518 else if (nid >= 0x0c && nid <= 0x0e)
18519 return nid - 0x0c + 0x02;
18520 else
18521 return 0;
18522}
18523
18524/* get MIX nid connected to the given pin targeted to DAC */
18525static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18526 hda_nid_t dac)
18527{
18528 hda_nid_t mix[4];
18529 int i, num;
18530
18531 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18532 for (i = 0; i < num; i++) {
18533 if (alc662_mix_to_dac(mix[i]) == dac)
18534 return mix[i];
18535 }
18536 return 0;
18537}
18538
18539/* look for an empty DAC slot */
18540static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18541{
18542 struct alc_spec *spec = codec->spec;
18543 hda_nid_t srcs[5];
18544 int i, j, num;
18545
18546 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18547 if (num < 0)
18548 return 0;
18549 for (i = 0; i < num; i++) {
18550 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
18551 if (!nid)
18552 continue;
18553 for (j = 0; j < spec->multiout.num_dacs; j++)
18554 if (spec->multiout.dac_nids[j] == nid)
18555 break;
18556 if (j >= spec->multiout.num_dacs)
18557 return nid;
18558 }
18559 return 0;
18560}
18561
18562/* fill in the dac_nids table from the parsed pin configuration */
18563static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18564 const struct auto_pin_cfg *cfg)
18565{
18566 struct alc_spec *spec = codec->spec;
18567 int i;
18568 hda_nid_t dac;
18569
18570 spec->multiout.dac_nids = spec->private_dac_nids;
18571 for (i = 0; i < cfg->line_outs; i++) {
18572 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
18573 if (!dac)
18574 continue;
18575 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
18576 }
18577 return 0;
18578}
18579
0afe5f89 18580static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18581 hda_nid_t nid, unsigned int chs)
18582{
0afe5f89 18583 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
7085ec12
TI
18584 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18585}
18586
0afe5f89 18587static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18588 hda_nid_t nid, unsigned int chs)
18589{
0afe5f89 18590 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12
TI
18591 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18592}
18593
18594#define alc662_add_stereo_vol(spec, pfx, nid) \
18595 alc662_add_vol_ctl(spec, pfx, nid, 3)
18596#define alc662_add_stereo_sw(spec, pfx, nid) \
18597 alc662_add_sw_ctl(spec, pfx, nid, 3)
18598
bc9f98a9 18599/* add playback controls from the parsed DAC table */
7085ec12 18600static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
18601 const struct auto_pin_cfg *cfg)
18602{
7085ec12 18603 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18604 static const char *chname[4] = {
18605 "Front", "Surround", NULL /*CLFE*/, "Side"
18606 };
7085ec12 18607 hda_nid_t nid, mix;
bc9f98a9
KY
18608 int i, err;
18609
18610 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
18611 nid = spec->multiout.dac_nids[i];
18612 if (!nid)
18613 continue;
18614 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
18615 if (!mix)
bc9f98a9 18616 continue;
bc9f98a9
KY
18617 if (i == 2) {
18618 /* Center/LFE */
7085ec12 18619 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
18620 if (err < 0)
18621 return err;
7085ec12 18622 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
18623 if (err < 0)
18624 return err;
7085ec12 18625 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
18626 if (err < 0)
18627 return err;
7085ec12 18628 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
18629 if (err < 0)
18630 return err;
18631 } else {
0d884cb9
TI
18632 const char *pfx;
18633 if (cfg->line_outs == 1 &&
18634 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
7085ec12 18635 if (cfg->hp_outs)
0d884cb9
TI
18636 pfx = "Speaker";
18637 else
18638 pfx = "PCM";
18639 } else
18640 pfx = chname[i];
7085ec12 18641 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
bc9f98a9
KY
18642 if (err < 0)
18643 return err;
0d884cb9
TI
18644 if (cfg->line_outs == 1 &&
18645 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
18646 pfx = "Speaker";
7085ec12 18647 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
bc9f98a9
KY
18648 if (err < 0)
18649 return err;
18650 }
18651 }
18652 return 0;
18653}
18654
18655/* add playback controls for speaker and HP outputs */
7085ec12
TI
18656/* return DAC nid if any new DAC is assigned */
18657static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
18658 const char *pfx)
18659{
7085ec12
TI
18660 struct alc_spec *spec = codec->spec;
18661 hda_nid_t nid, mix;
bc9f98a9 18662 int err;
bc9f98a9
KY
18663
18664 if (!pin)
18665 return 0;
7085ec12
TI
18666 nid = alc662_look_for_dac(codec, pin);
18667 if (!nid) {
7085ec12
TI
18668 /* the corresponding DAC is already occupied */
18669 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18670 return 0; /* no way */
18671 /* create a switch only */
0afe5f89 18672 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 18673 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
18674 }
18675
7085ec12
TI
18676 mix = alc662_dac_to_mix(codec, pin, nid);
18677 if (!mix)
18678 return 0;
18679 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
18680 if (err < 0)
18681 return err;
18682 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
18683 if (err < 0)
18684 return err;
18685 return nid;
bc9f98a9
KY
18686}
18687
18688/* create playback/capture controls for input pins */
05f5f477 18689#define alc662_auto_create_input_ctls \
4b7348a1 18690 alc882_auto_create_input_ctls
bc9f98a9
KY
18691
18692static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
18693 hda_nid_t nid, int pin_type,
7085ec12 18694 hda_nid_t dac)
bc9f98a9 18695{
7085ec12 18696 int i, num;
ce503f38 18697 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 18698
f6c7e546 18699 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 18700 /* need the manual connection? */
7085ec12
TI
18701 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
18702 if (num <= 1)
18703 return;
18704 for (i = 0; i < num; i++) {
18705 if (alc662_mix_to_dac(srcs[i]) != dac)
18706 continue;
18707 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
18708 return;
bc9f98a9
KY
18709 }
18710}
18711
18712static void alc662_auto_init_multi_out(struct hda_codec *codec)
18713{
18714 struct alc_spec *spec = codec->spec;
7085ec12 18715 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
18716 int i;
18717
18718 for (i = 0; i <= HDA_SIDE; i++) {
18719 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18720 if (nid)
baba8ee9 18721 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 18722 spec->multiout.dac_nids[i]);
bc9f98a9
KY
18723 }
18724}
18725
18726static void alc662_auto_init_hp_out(struct hda_codec *codec)
18727{
18728 struct alc_spec *spec = codec->spec;
18729 hda_nid_t pin;
18730
18731 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
18732 if (pin)
18733 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
18734 spec->multiout.hp_nid);
f6c7e546
TI
18735 pin = spec->autocfg.speaker_pins[0];
18736 if (pin)
7085ec12
TI
18737 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
18738 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
18739}
18740
bc9f98a9
KY
18741#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
18742
18743static void alc662_auto_init_analog_input(struct hda_codec *codec)
18744{
18745 struct alc_spec *spec = codec->spec;
18746 int i;
18747
18748 for (i = 0; i < AUTO_PIN_LAST; i++) {
18749 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 18750 if (alc_is_input_pin(codec, nid)) {
23f0c048 18751 alc_set_input_pin(codec, nid, i);
52ca15b7 18752 if (nid != ALC662_PIN_CD_NID &&
e82c025b 18753 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
18754 snd_hda_codec_write(codec, nid, 0,
18755 AC_VERB_SET_AMP_GAIN_MUTE,
18756 AMP_OUT_MUTE);
18757 }
18758 }
18759}
18760
f511b01c
TI
18761#define alc662_auto_init_input_src alc882_auto_init_input_src
18762
bc9f98a9
KY
18763static int alc662_parse_auto_config(struct hda_codec *codec)
18764{
18765 struct alc_spec *spec = codec->spec;
18766 int err;
18767 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
18768
18769 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
18770 alc662_ignore);
18771 if (err < 0)
18772 return err;
18773 if (!spec->autocfg.line_outs)
18774 return 0; /* can't find valid BIOS pin config */
18775
7085ec12 18776 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
18777 if (err < 0)
18778 return err;
7085ec12 18779 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
18780 if (err < 0)
18781 return err;
7085ec12 18782 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
18783 spec->autocfg.speaker_pins[0],
18784 "Speaker");
18785 if (err < 0)
18786 return err;
7085ec12
TI
18787 if (err)
18788 spec->multiout.extra_out_nid[0] = err;
18789 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
18790 "Headphone");
18791 if (err < 0)
18792 return err;
7085ec12
TI
18793 if (err)
18794 spec->multiout.hp_nid = err;
05f5f477 18795 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 18796 if (err < 0)
bc9f98a9
KY
18797 return err;
18798
18799 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
18800
757899ac 18801 alc_auto_parse_digital(codec);
bc9f98a9 18802
603c4019 18803 if (spec->kctls.list)
d88897ea 18804 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
18805
18806 spec->num_mux_defs = 1;
61b9b9b1 18807 spec->input_mux = &spec->private_imux[0];
ea1fb29a 18808
cec27c89
KY
18809 add_verb(spec, alc662_init_verbs);
18810 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
d1eb57f4 18811 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
cec27c89
KY
18812 add_verb(spec, alc663_init_verbs);
18813
18814 if (codec->vendor_id == 0x10ec0272)
18815 add_verb(spec, alc272_init_verbs);
ee979a14
TI
18816
18817 err = alc_auto_add_mic_boost(codec);
18818 if (err < 0)
18819 return err;
18820
6227cdce
KY
18821 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18822 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18823 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18824 else
18825 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 18826
8c87286f 18827 return 1;
bc9f98a9
KY
18828}
18829
18830/* additional initialization for auto-configuration model */
18831static void alc662_auto_init(struct hda_codec *codec)
18832{
f6c7e546 18833 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18834 alc662_auto_init_multi_out(codec);
18835 alc662_auto_init_hp_out(codec);
18836 alc662_auto_init_analog_input(codec);
f511b01c 18837 alc662_auto_init_input_src(codec);
757899ac 18838 alc_auto_init_digital(codec);
f6c7e546 18839 if (spec->unsol_event)
7fb0d78f 18840 alc_inithook(codec);
bc9f98a9
KY
18841}
18842
18843static int patch_alc662(struct hda_codec *codec)
18844{
18845 struct alc_spec *spec;
18846 int err, board_config;
18847
18848 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
18849 if (!spec)
18850 return -ENOMEM;
18851
18852 codec->spec = spec;
18853
da00c244
KY
18854 alc_auto_parse_customize_define(codec);
18855
2c3bf9ab
TI
18856 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18857
c027ddcd
KY
18858 if (alc_read_coef_idx(codec, 0) == 0x8020)
18859 alc_codec_rename(codec, "ALC661");
18860 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) &&
18861 codec->bus->pci->subsystem_vendor == 0x1025 &&
18862 spec->cdefine.platform_type == 1)
18863 alc_codec_rename(codec, "ALC272X");
274693f3 18864
bc9f98a9
KY
18865 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
18866 alc662_models,
18867 alc662_cfg_tbl);
18868 if (board_config < 0) {
9a11f1aa
TI
18869 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
18870 codec->chip_name);
bc9f98a9
KY
18871 board_config = ALC662_AUTO;
18872 }
18873
18874 if (board_config == ALC662_AUTO) {
18875 /* automatic parse from the BIOS config */
18876 err = alc662_parse_auto_config(codec);
18877 if (err < 0) {
18878 alc_free(codec);
18879 return err;
8c87286f 18880 } else if (!err) {
bc9f98a9
KY
18881 printk(KERN_INFO
18882 "hda_codec: Cannot set up configuration "
18883 "from BIOS. Using base mode...\n");
18884 board_config = ALC662_3ST_2ch_DIG;
18885 }
18886 }
18887
dc1eae25 18888 if (has_cdefine_beep(codec)) {
8af2591d
TI
18889 err = snd_hda_attach_beep_device(codec, 0x1);
18890 if (err < 0) {
18891 alc_free(codec);
18892 return err;
18893 }
680cd536
KK
18894 }
18895
bc9f98a9 18896 if (board_config != ALC662_AUTO)
e9c364c0 18897 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 18898
bc9f98a9
KY
18899 spec->stream_analog_playback = &alc662_pcm_analog_playback;
18900 spec->stream_analog_capture = &alc662_pcm_analog_capture;
18901
bc9f98a9
KY
18902 spec->stream_digital_playback = &alc662_pcm_digital_playback;
18903 spec->stream_digital_capture = &alc662_pcm_digital_capture;
18904
dd704698
TI
18905 if (!spec->adc_nids) {
18906 spec->adc_nids = alc662_adc_nids;
18907 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
18908 }
18909 if (!spec->capsrc_nids)
18910 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 18911
f9e336f6 18912 if (!spec->cap_mixer)
b59bdf3b 18913 set_capture_mixer(codec);
cec27c89 18914
dc1eae25 18915 if (has_cdefine_beep(codec)) {
da00c244
KY
18916 switch (codec->vendor_id) {
18917 case 0x10ec0662:
18918 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18919 break;
18920 case 0x10ec0272:
18921 case 0x10ec0663:
18922 case 0x10ec0665:
18923 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18924 break;
18925 case 0x10ec0273:
18926 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18927 break;
18928 }
cec27c89 18929 }
2134ea4f
TI
18930 spec->vmaster_nid = 0x02;
18931
bc9f98a9
KY
18932 codec->patch_ops = alc_patch_ops;
18933 if (board_config == ALC662_AUTO)
18934 spec->init_hook = alc662_auto_init;
cb53c626
TI
18935#ifdef CONFIG_SND_HDA_POWER_SAVE
18936 if (!spec->loopback.amplist)
18937 spec->loopback.amplist = alc662_loopbacks;
18938#endif
bc9f98a9
KY
18939
18940 return 0;
18941}
18942
274693f3
KY
18943static int patch_alc888(struct hda_codec *codec)
18944{
18945 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
18946 kfree(codec->chip_name);
18947 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
18948 if (!codec->chip_name) {
18949 alc_free(codec);
274693f3 18950 return -ENOMEM;
ac2c92e0
TI
18951 }
18952 return patch_alc662(codec);
274693f3 18953 }
ac2c92e0 18954 return patch_alc882(codec);
274693f3
KY
18955}
18956
d1eb57f4
KY
18957/*
18958 * ALC680 support
18959 */
18960#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
18961#define alc680_modes alc260_modes
18962
18963static hda_nid_t alc680_dac_nids[3] = {
18964 /* Lout1, Lout2, hp */
18965 0x02, 0x03, 0x04
18966};
18967
18968static hda_nid_t alc680_adc_nids[3] = {
18969 /* ADC0-2 */
18970 /* DMIC, MIC, Line-in*/
18971 0x07, 0x08, 0x09
18972};
18973
18974static struct snd_kcontrol_new alc680_base_mixer[] = {
18975 /* output mixer control */
18976 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
18977 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18978 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
18979 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
18980 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
18981 { }
18982};
18983
18984static struct snd_kcontrol_new alc680_capture_mixer[] = {
18985 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
18986 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
18987 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
18988 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
18989 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
18990 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
18991 { } /* end */
18992};
18993
18994/*
18995 * generic initialization of ADC, input mixers and output mixers
18996 */
18997static struct hda_verb alc680_init_verbs[] = {
18998 /* Unmute DAC0-1 and set vol = 0 */
18999 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
19000 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
19001 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
19002
19003 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
19004 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
19005 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
19006 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
19007 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
19008
19009 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19010 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19011 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19012 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19013 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19014 { }
19015};
19016
19017/* create input playback/capture controls for the given pin */
19018static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19019 const char *ctlname, int idx)
19020{
19021 hda_nid_t dac;
19022 int err;
19023
19024 switch (nid) {
19025 case 0x14:
19026 dac = 0x02;
19027 break;
19028 case 0x15:
19029 dac = 0x03;
19030 break;
19031 case 0x16:
19032 dac = 0x04;
19033 break;
19034 default:
19035 return 0;
19036 }
19037 if (spec->multiout.dac_nids[0] != dac &&
19038 spec->multiout.dac_nids[1] != dac) {
19039 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19040 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19041 HDA_OUTPUT));
19042 if (err < 0)
19043 return err;
19044
19045 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19046 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19047
19048 if (err < 0)
19049 return err;
19050 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19051 }
19052
19053 return 0;
19054}
19055
19056/* add playback controls from the parsed DAC table */
19057static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19058 const struct auto_pin_cfg *cfg)
19059{
19060 hda_nid_t nid;
19061 int err;
19062
19063 spec->multiout.dac_nids = spec->private_dac_nids;
19064
19065 nid = cfg->line_out_pins[0];
19066 if (nid) {
19067 const char *name;
19068 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19069 name = "Speaker";
19070 else
19071 name = "Front";
19072 err = alc680_new_analog_output(spec, nid, name, 0);
19073 if (err < 0)
19074 return err;
19075 }
19076
19077 nid = cfg->speaker_pins[0];
19078 if (nid) {
19079 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19080 if (err < 0)
19081 return err;
19082 }
19083 nid = cfg->hp_pins[0];
19084 if (nid) {
19085 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19086 if (err < 0)
19087 return err;
19088 }
19089
19090 return 0;
19091}
19092
19093static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19094 hda_nid_t nid, int pin_type)
19095{
19096 alc_set_pin_output(codec, nid, pin_type);
19097}
19098
19099static void alc680_auto_init_multi_out(struct hda_codec *codec)
19100{
19101 struct alc_spec *spec = codec->spec;
19102 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19103 if (nid) {
19104 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19105 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19106 }
19107}
19108
19109static void alc680_auto_init_hp_out(struct hda_codec *codec)
19110{
19111 struct alc_spec *spec = codec->spec;
19112 hda_nid_t pin;
19113
19114 pin = spec->autocfg.hp_pins[0];
19115 if (pin)
19116 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19117 pin = spec->autocfg.speaker_pins[0];
19118 if (pin)
19119 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19120}
19121
19122/* pcm configuration: identical with ALC880 */
19123#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19124#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19125#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19126#define alc680_pcm_digital_playback alc880_pcm_digital_playback
19127
19128static struct hda_input_mux alc680_capture_source = {
19129 .num_items = 1,
19130 .items = {
19131 { "Mic", 0x0 },
19132 },
19133};
19134
19135/*
19136 * BIOS auto configuration
19137 */
19138static int alc680_parse_auto_config(struct hda_codec *codec)
19139{
19140 struct alc_spec *spec = codec->spec;
19141 int err;
19142 static hda_nid_t alc680_ignore[] = { 0 };
19143
19144 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19145 alc680_ignore);
19146 if (err < 0)
19147 return err;
19148 if (!spec->autocfg.line_outs) {
19149 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19150 spec->multiout.max_channels = 2;
19151 spec->no_analog = 1;
19152 goto dig_only;
19153 }
19154 return 0; /* can't find valid BIOS pin config */
19155 }
19156 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19157 if (err < 0)
19158 return err;
19159
19160 spec->multiout.max_channels = 2;
19161
19162 dig_only:
19163 /* digital only support output */
757899ac 19164 alc_auto_parse_digital(codec);
d1eb57f4
KY
19165 if (spec->kctls.list)
19166 add_mixer(spec, spec->kctls.list);
19167
19168 add_verb(spec, alc680_init_verbs);
19169 spec->num_mux_defs = 1;
19170 spec->input_mux = &alc680_capture_source;
19171
19172 err = alc_auto_add_mic_boost(codec);
19173 if (err < 0)
19174 return err;
19175
19176 return 1;
19177}
19178
19179#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19180
19181/* init callback for auto-configuration model -- overriding the default init */
19182static void alc680_auto_init(struct hda_codec *codec)
19183{
19184 struct alc_spec *spec = codec->spec;
19185 alc680_auto_init_multi_out(codec);
19186 alc680_auto_init_hp_out(codec);
19187 alc680_auto_init_analog_input(codec);
757899ac 19188 alc_auto_init_digital(codec);
d1eb57f4
KY
19189 if (spec->unsol_event)
19190 alc_inithook(codec);
19191}
19192
19193/*
19194 * configuration and preset
19195 */
19196static const char *alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19197 [ALC680_BASE] = "base",
19198 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19199};
19200
19201static struct snd_pci_quirk alc680_cfg_tbl[] = {
19202 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19203 {}
19204};
19205
19206static struct alc_config_preset alc680_presets[] = {
19207 [ALC680_BASE] = {
19208 .mixers = { alc680_base_mixer },
19209 .cap_mixer = alc680_capture_mixer,
19210 .init_verbs = { alc680_init_verbs },
19211 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19212 .dac_nids = alc680_dac_nids,
19213 .num_adc_nids = ARRAY_SIZE(alc680_adc_nids),
19214 .adc_nids = alc680_adc_nids,
19215 .hp_nid = 0x04,
19216 .dig_out_nid = ALC680_DIGOUT_NID,
19217 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19218 .channel_mode = alc680_modes,
19219 .input_mux = &alc680_capture_source,
19220 },
19221};
19222
19223static int patch_alc680(struct hda_codec *codec)
19224{
19225 struct alc_spec *spec;
19226 int board_config;
19227 int err;
19228
19229 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19230 if (spec == NULL)
19231 return -ENOMEM;
19232
19233 codec->spec = spec;
19234
19235 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19236 alc680_models,
19237 alc680_cfg_tbl);
19238
19239 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19240 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19241 codec->chip_name);
19242 board_config = ALC680_AUTO;
19243 }
19244
19245 if (board_config == ALC680_AUTO) {
19246 /* automatic parse from the BIOS config */
19247 err = alc680_parse_auto_config(codec);
19248 if (err < 0) {
19249 alc_free(codec);
19250 return err;
19251 } else if (!err) {
19252 printk(KERN_INFO
19253 "hda_codec: Cannot set up configuration "
19254 "from BIOS. Using base mode...\n");
19255 board_config = ALC680_BASE;
19256 }
19257 }
19258
19259 if (board_config != ALC680_AUTO)
19260 setup_preset(codec, &alc680_presets[board_config]);
19261
19262 spec->stream_analog_playback = &alc680_pcm_analog_playback;
19263 spec->stream_analog_capture = &alc680_pcm_analog_capture;
19264 spec->stream_analog_alt_capture = &alc680_pcm_analog_alt_capture;
19265 spec->stream_digital_playback = &alc680_pcm_digital_playback;
19266
19267 if (!spec->adc_nids) {
19268 spec->adc_nids = alc680_adc_nids;
19269 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19270 }
19271
19272 if (!spec->cap_mixer)
19273 set_capture_mixer(codec);
19274
19275 spec->vmaster_nid = 0x02;
19276
19277 codec->patch_ops = alc_patch_ops;
19278 if (board_config == ALC680_AUTO)
19279 spec->init_hook = alc680_auto_init;
19280
19281 return 0;
19282}
19283
1da177e4
LT
19284/*
19285 * patch entries
19286 */
1289e9e8 19287static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 19288 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 19289 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 19290 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 19291 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 19292 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 19293 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 19294 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 19295 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 19296 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 19297 .patch = patch_alc861 },
f32610ed
JS
19298 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19299 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19300 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 19301 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 19302 .patch = patch_alc882 },
bc9f98a9
KY
19303 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19304 .patch = patch_alc662 },
6dda9f4a 19305 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 19306 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 19307 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 19308 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 19309 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 19310 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 19311 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 19312 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 19313 .patch = patch_alc882 },
cb308f97 19314 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 19315 .patch = patch_alc882 },
df694daa 19316 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
4953550a 19317 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
4442608d 19318 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 19319 .patch = patch_alc882 },
274693f3 19320 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 19321 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 19322 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
19323 {} /* terminator */
19324};
1289e9e8
TI
19325
19326MODULE_ALIAS("snd-hda-codec-id:10ec*");
19327
19328MODULE_LICENSE("GPL");
19329MODULE_DESCRIPTION("Realtek HD-audio codec");
19330
19331static struct hda_codec_preset_list realtek_list = {
19332 .preset = snd_hda_preset_realtek,
19333 .owner = THIS_MODULE,
19334};
19335
19336static int __init patch_realtek_init(void)
19337{
19338 return snd_hda_add_codec_preset(&realtek_list);
19339}
19340
19341static void __exit patch_realtek_exit(void)
19342{
19343 snd_hda_delete_codec_preset(&realtek_list);
19344}
19345
19346module_init(patch_realtek_init)
19347module_exit(patch_realtek_exit)