]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Handle pin NID 0x1a on ALC259/269
[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),
5330 {}
5331};
5332
5333static inline int has_cdefine_beep(struct hda_codec *codec)
5334{
5335 struct alc_spec *spec = codec->spec;
5336 const struct snd_pci_quirk *q;
5337 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5338 if (q)
5339 return q->value;
5340 return spec->cdefine.enable_pcbeep;
5341}
67d634c0
TI
5342#else
5343#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5344#define has_cdefine_beep(codec) 0
67d634c0 5345#endif
45bdd1c1
TI
5346
5347/*
5348 * OK, here we have finally the patch for ALC880
5349 */
5350
1da177e4
LT
5351static int patch_alc880(struct hda_codec *codec)
5352{
5353 struct alc_spec *spec;
5354 int board_config;
df694daa 5355 int err;
1da177e4 5356
e560d8d8 5357 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5358 if (spec == NULL)
5359 return -ENOMEM;
5360
5361 codec->spec = spec;
5362
f5fcc13c
TI
5363 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5364 alc880_models,
5365 alc880_cfg_tbl);
5366 if (board_config < 0) {
9a11f1aa
TI
5367 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5368 codec->chip_name);
e9edcee0 5369 board_config = ALC880_AUTO;
1da177e4 5370 }
1da177e4 5371
e9edcee0
TI
5372 if (board_config == ALC880_AUTO) {
5373 /* automatic parse from the BIOS config */
5374 err = alc880_parse_auto_config(codec);
5375 if (err < 0) {
5376 alc_free(codec);
5377 return err;
f12ab1e0 5378 } else if (!err) {
9c7f852e
TI
5379 printk(KERN_INFO
5380 "hda_codec: Cannot set up configuration "
5381 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5382 board_config = ALC880_3ST;
5383 }
1da177e4
LT
5384 }
5385
680cd536
KK
5386 err = snd_hda_attach_beep_device(codec, 0x1);
5387 if (err < 0) {
5388 alc_free(codec);
5389 return err;
5390 }
5391
df694daa 5392 if (board_config != ALC880_AUTO)
e9c364c0 5393 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5394
1da177e4
LT
5395 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5396 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5397 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5398
1da177e4
LT
5399 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5400 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5401
f12ab1e0 5402 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5403 /* check whether NID 0x07 is valid */
54d17403 5404 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5405 /* get type */
a22d543a 5406 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5407 if (wcap != AC_WID_AUD_IN) {
5408 spec->adc_nids = alc880_adc_nids_alt;
5409 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5410 } else {
5411 spec->adc_nids = alc880_adc_nids;
5412 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5413 }
5414 }
b59bdf3b 5415 set_capture_mixer(codec);
45bdd1c1 5416 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5417
2134ea4f
TI
5418 spec->vmaster_nid = 0x0c;
5419
1da177e4 5420 codec->patch_ops = alc_patch_ops;
e9edcee0 5421 if (board_config == ALC880_AUTO)
ae6b813a 5422 spec->init_hook = alc880_auto_init;
cb53c626
TI
5423#ifdef CONFIG_SND_HDA_POWER_SAVE
5424 if (!spec->loopback.amplist)
5425 spec->loopback.amplist = alc880_loopbacks;
5426#endif
1da177e4
LT
5427
5428 return 0;
5429}
5430
e9edcee0 5431
1da177e4
LT
5432/*
5433 * ALC260 support
5434 */
5435
e9edcee0
TI
5436static hda_nid_t alc260_dac_nids[1] = {
5437 /* front */
5438 0x02,
5439};
5440
5441static hda_nid_t alc260_adc_nids[1] = {
5442 /* ADC0 */
5443 0x04,
5444};
5445
df694daa 5446static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5447 /* ADC1 */
5448 0x05,
5449};
5450
d57fdac0
JW
5451/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5452 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5453 */
5454static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5455 /* ADC0, ADC1 */
5456 0x04, 0x05
5457};
5458
e9edcee0
TI
5459#define ALC260_DIGOUT_NID 0x03
5460#define ALC260_DIGIN_NID 0x06
5461
5462static struct hda_input_mux alc260_capture_source = {
5463 .num_items = 4,
5464 .items = {
5465 { "Mic", 0x0 },
5466 { "Front Mic", 0x1 },
5467 { "Line", 0x2 },
5468 { "CD", 0x4 },
5469 },
5470};
5471
17e7aec6 5472/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5473 * headphone jack and the internal CD lines since these are the only pins at
5474 * which audio can appear. For flexibility, also allow the option of
5475 * recording the mixer output on the second ADC (ADC0 doesn't have a
5476 * connection to the mixer output).
a9430dd8 5477 */
a1e8d2da
JW
5478static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5479 {
5480 .num_items = 3,
5481 .items = {
5482 { "Mic/Line", 0x0 },
5483 { "CD", 0x4 },
5484 { "Headphone", 0x2 },
5485 },
a9430dd8 5486 },
a1e8d2da
JW
5487 {
5488 .num_items = 4,
5489 .items = {
5490 { "Mic/Line", 0x0 },
5491 { "CD", 0x4 },
5492 { "Headphone", 0x2 },
5493 { "Mixer", 0x5 },
5494 },
5495 },
5496
a9430dd8
JW
5497};
5498
a1e8d2da
JW
5499/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5500 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5501 */
a1e8d2da
JW
5502static struct hda_input_mux alc260_acer_capture_sources[2] = {
5503 {
5504 .num_items = 4,
5505 .items = {
5506 { "Mic", 0x0 },
5507 { "Line", 0x2 },
5508 { "CD", 0x4 },
5509 { "Headphone", 0x5 },
5510 },
5511 },
5512 {
5513 .num_items = 5,
5514 .items = {
5515 { "Mic", 0x0 },
5516 { "Line", 0x2 },
5517 { "CD", 0x4 },
5518 { "Headphone", 0x6 },
5519 { "Mixer", 0x5 },
5520 },
0bfc90e9
JW
5521 },
5522};
cc959489
MS
5523
5524/* Maxdata Favorit 100XS */
5525static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5526 {
5527 .num_items = 2,
5528 .items = {
5529 { "Line/Mic", 0x0 },
5530 { "CD", 0x4 },
5531 },
5532 },
5533 {
5534 .num_items = 3,
5535 .items = {
5536 { "Line/Mic", 0x0 },
5537 { "CD", 0x4 },
5538 { "Mixer", 0x5 },
5539 },
5540 },
5541};
5542
1da177e4
LT
5543/*
5544 * This is just place-holder, so there's something for alc_build_pcms to look
5545 * at when it calculates the maximum number of channels. ALC260 has no mixer
5546 * element which allows changing the channel mode, so the verb list is
5547 * never used.
5548 */
d2a6d7dc 5549static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5550 { 2, NULL },
5551};
5552
df694daa
KY
5553
5554/* Mixer combinations
5555 *
5556 * basic: base_output + input + pc_beep + capture
5557 * HP: base_output + input + capture_alt
5558 * HP_3013: hp_3013 + input + capture
5559 * fujitsu: fujitsu + capture
0bfc90e9 5560 * acer: acer + capture
df694daa
KY
5561 */
5562
5563static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5564 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5565 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5566 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5567 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5568 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5569 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5570 { } /* end */
f12ab1e0 5571};
1da177e4 5572
df694daa 5573static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5574 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5575 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5576 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5577 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5578 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5579 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5580 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5581 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5582 { } /* end */
5583};
5584
bec15c3a
TI
5585/* update HP, line and mono out pins according to the master switch */
5586static void alc260_hp_master_update(struct hda_codec *codec,
5587 hda_nid_t hp, hda_nid_t line,
5588 hda_nid_t mono)
5589{
5590 struct alc_spec *spec = codec->spec;
5591 unsigned int val = spec->master_sw ? PIN_HP : 0;
5592 /* change HP and line-out pins */
30cde0aa 5593 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5594 val);
30cde0aa 5595 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5596 val);
5597 /* mono (speaker) depending on the HP jack sense */
5598 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5599 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5600 val);
5601}
5602
5603static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5604 struct snd_ctl_elem_value *ucontrol)
5605{
5606 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5607 struct alc_spec *spec = codec->spec;
5608 *ucontrol->value.integer.value = spec->master_sw;
5609 return 0;
5610}
5611
5612static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5613 struct snd_ctl_elem_value *ucontrol)
5614{
5615 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5616 struct alc_spec *spec = codec->spec;
5617 int val = !!*ucontrol->value.integer.value;
5618 hda_nid_t hp, line, mono;
5619
5620 if (val == spec->master_sw)
5621 return 0;
5622 spec->master_sw = val;
5623 hp = (kcontrol->private_value >> 16) & 0xff;
5624 line = (kcontrol->private_value >> 8) & 0xff;
5625 mono = kcontrol->private_value & 0xff;
5626 alc260_hp_master_update(codec, hp, line, mono);
5627 return 1;
5628}
5629
5630static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5631 {
5632 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5633 .name = "Master Playback Switch",
5b0cb1d8 5634 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5635 .info = snd_ctl_boolean_mono_info,
5636 .get = alc260_hp_master_sw_get,
5637 .put = alc260_hp_master_sw_put,
5638 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5639 },
5640 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5641 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5642 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5643 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5644 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5645 HDA_OUTPUT),
5646 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5647 { } /* end */
5648};
5649
5650static struct hda_verb alc260_hp_unsol_verbs[] = {
5651 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5652 {},
5653};
5654
5655static void alc260_hp_automute(struct hda_codec *codec)
5656{
5657 struct alc_spec *spec = codec->spec;
bec15c3a 5658
864f92be 5659 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5660 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5661}
5662
5663static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5664{
5665 if ((res >> 26) == ALC880_HP_EVENT)
5666 alc260_hp_automute(codec);
5667}
5668
df694daa 5669static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5670 {
5671 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5672 .name = "Master Playback Switch",
5b0cb1d8 5673 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5674 .info = snd_ctl_boolean_mono_info,
5675 .get = alc260_hp_master_sw_get,
5676 .put = alc260_hp_master_sw_put,
30cde0aa 5677 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5678 },
df694daa
KY
5679 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5680 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5681 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5682 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5683 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5684 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
5685 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5686 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
5687 { } /* end */
5688};
5689
3f878308
KY
5690static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5691 .ops = &snd_hda_bind_vol,
5692 .values = {
5693 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5694 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5695 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5696 0
5697 },
5698};
5699
5700static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5701 .ops = &snd_hda_bind_sw,
5702 .values = {
5703 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5704 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5705 0
5706 },
5707};
5708
5709static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5710 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5711 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5712 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5713 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5714 { } /* end */
5715};
5716
bec15c3a
TI
5717static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5718 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5719 {},
5720};
5721
5722static void alc260_hp_3013_automute(struct hda_codec *codec)
5723{
5724 struct alc_spec *spec = codec->spec;
bec15c3a 5725
864f92be 5726 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 5727 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
5728}
5729
5730static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5731 unsigned int res)
5732{
5733 if ((res >> 26) == ALC880_HP_EVENT)
5734 alc260_hp_3013_automute(codec);
5735}
5736
3f878308
KY
5737static void alc260_hp_3012_automute(struct hda_codec *codec)
5738{
864f92be 5739 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 5740
3f878308
KY
5741 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5742 bits);
5743 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5744 bits);
5745 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5746 bits);
5747}
5748
5749static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5750 unsigned int res)
5751{
5752 if ((res >> 26) == ALC880_HP_EVENT)
5753 alc260_hp_3012_automute(codec);
5754}
5755
5756/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
5757 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5758 */
c8b6bf9b 5759static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 5760 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5761 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 5762 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
5763 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5764 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5765 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5766 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 5767 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
5768 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5769 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
5770 { } /* end */
5771};
5772
a1e8d2da
JW
5773/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5774 * versions of the ALC260 don't act on requests to enable mic bias from NID
5775 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5776 * datasheet doesn't mention this restriction. At this stage it's not clear
5777 * whether this behaviour is intentional or is a hardware bug in chip
5778 * revisions available in early 2006. Therefore for now allow the
5779 * "Headphone Jack Mode" control to span all choices, but if it turns out
5780 * that the lack of mic bias for this NID is intentional we could change the
5781 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5782 *
5783 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5784 * don't appear to make the mic bias available from the "line" jack, even
5785 * though the NID used for this jack (0x14) can supply it. The theory is
5786 * that perhaps Acer have included blocking capacitors between the ALC260
5787 * and the output jack. If this turns out to be the case for all such
5788 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5789 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
5790 *
5791 * The C20x Tablet series have a mono internal speaker which is controlled
5792 * via the chip's Mono sum widget and pin complex, so include the necessary
5793 * controls for such models. On models without a "mono speaker" the control
5794 * won't do anything.
a1e8d2da 5795 */
0bfc90e9
JW
5796static struct snd_kcontrol_new alc260_acer_mixer[] = {
5797 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5798 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 5799 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 5800 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 5801 HDA_OUTPUT),
31bffaa9 5802 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 5803 HDA_INPUT),
0bfc90e9
JW
5804 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5805 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5806 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5807 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5808 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5809 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5810 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5811 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
5812 { } /* end */
5813};
5814
cc959489
MS
5815/* Maxdata Favorit 100XS: one output and one input (0x12) jack
5816 */
5817static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5818 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5819 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5820 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5821 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5822 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5823 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5824 { } /* end */
5825};
5826
bc9f98a9
KY
5827/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5828 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5829 */
5830static struct snd_kcontrol_new alc260_will_mixer[] = {
5831 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5832 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5833 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5834 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5835 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5836 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5837 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5838 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5839 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5840 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
5841 { } /* end */
5842};
5843
5844/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5845 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5846 */
5847static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5848 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5849 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5850 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5851 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5852 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5853 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5854 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5855 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5856 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5857 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5858 { } /* end */
5859};
5860
df694daa
KY
5861/*
5862 * initialization verbs
5863 */
1da177e4
LT
5864static struct hda_verb alc260_init_verbs[] = {
5865 /* Line In pin widget for input */
05acb863 5866 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5867 /* CD pin widget for input */
05acb863 5868 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5869 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 5870 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5871 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 5872 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5873 /* LINE-2 is used for line-out in rear */
05acb863 5874 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5875 /* select line-out */
fd56f2db 5876 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5877 /* LINE-OUT pin */
05acb863 5878 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5879 /* enable HP */
05acb863 5880 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 5881 /* enable Mono */
05acb863
TI
5882 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5883 /* mute capture amp left and right */
16ded525 5884 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
5885 /* set connection select to line in (default select for this ADC) */
5886 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
5887 /* mute capture amp left and right */
5888 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5889 /* set connection select to line in (default select for this ADC) */
5890 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
5891 /* set vol=0 Line-Out mixer amp left and right */
5892 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5893 /* unmute pin widget amp left and right (no gain on this amp) */
5894 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5895 /* set vol=0 HP mixer amp left and right */
5896 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5897 /* unmute pin widget amp left and right (no gain on this amp) */
5898 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5899 /* set vol=0 Mono mixer amp left and right */
5900 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5901 /* unmute pin widget amp left and right (no gain on this amp) */
5902 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5903 /* unmute LINE-2 out pin */
5904 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
5905 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5906 * Line In 2 = 0x03
5907 */
cb53c626
TI
5908 /* mute analog inputs */
5909 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5910 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5911 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5912 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5913 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5914 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
5915 /* mute Front out path */
5916 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5917 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5918 /* mute Headphone out path */
5919 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5920 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5921 /* mute Mono out path */
5922 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5923 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
5924 { }
5925};
5926
474167d6 5927#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
5928static struct hda_verb alc260_hp_init_verbs[] = {
5929 /* Headphone and output */
5930 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5931 /* mono output */
5932 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5933 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5934 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5935 /* Mic2 (front panel) pin widget for input and vref at 80% */
5936 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5937 /* Line In pin widget for input */
5938 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5939 /* Line-2 pin widget for output */
5940 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5941 /* CD pin widget for input */
5942 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5943 /* unmute amp left and right */
5944 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5945 /* set connection select to line in (default select for this ADC) */
5946 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5947 /* unmute Line-Out mixer amp left and right (volume = 0) */
5948 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5949 /* mute pin widget amp left and right (no gain on this amp) */
5950 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5951 /* unmute HP mixer amp left and right (volume = 0) */
5952 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5953 /* mute pin widget amp left and right (no gain on this amp) */
5954 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5955 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5956 * Line In 2 = 0x03
5957 */
cb53c626
TI
5958 /* mute analog inputs */
5959 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5960 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5961 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5962 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5963 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5964 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5965 /* Unmute Front out path */
5966 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5967 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5968 /* Unmute Headphone out path */
5969 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5970 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5971 /* Unmute Mono out path */
5972 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5973 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5974 { }
5975};
474167d6 5976#endif
df694daa
KY
5977
5978static struct hda_verb alc260_hp_3013_init_verbs[] = {
5979 /* Line out and output */
5980 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5981 /* mono output */
5982 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5983 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5984 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5985 /* Mic2 (front panel) pin widget for input and vref at 80% */
5986 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5987 /* Line In pin widget for input */
5988 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5989 /* Headphone pin widget for output */
5990 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5991 /* CD pin widget for input */
5992 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5993 /* unmute amp left and right */
5994 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5995 /* set connection select to line in (default select for this ADC) */
5996 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5997 /* unmute Line-Out mixer amp left and right (volume = 0) */
5998 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5999 /* mute pin widget amp left and right (no gain on this amp) */
6000 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6001 /* unmute HP mixer amp left and right (volume = 0) */
6002 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6003 /* mute pin widget amp left and right (no gain on this amp) */
6004 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6005 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6006 * Line In 2 = 0x03
6007 */
cb53c626
TI
6008 /* mute analog inputs */
6009 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6010 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6011 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6012 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6013 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6014 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6015 /* Unmute Front out path */
6016 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6017 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6018 /* Unmute Headphone out path */
6019 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6020 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6021 /* Unmute Mono out path */
6022 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6023 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6024 { }
6025};
6026
a9430dd8 6027/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6028 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6029 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
6030 */
6031static struct hda_verb alc260_fujitsu_init_verbs[] = {
6032 /* Disable all GPIOs */
6033 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6034 /* Internal speaker is connected to headphone pin */
6035 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6036 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6037 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6038 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6039 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6040 /* Ensure all other unused pins are disabled and muted. */
6041 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6042 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6043 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6044 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6045 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6046 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6047 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6048 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6049
6050 /* Disable digital (SPDIF) pins */
6051 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6052 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6053
ea1fb29a 6054 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6055 * when acting as an output.
6056 */
6057 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6058
f7ace40d 6059 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6060 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6061 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6062 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6063 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6064 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6065 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6066 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6067 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6068 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6069
f7ace40d
JW
6070 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6071 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6072 /* Unmute Line1 pin widget output buffer since it starts as an output.
6073 * If the pin mode is changed by the user the pin mode control will
6074 * take care of enabling the pin's input/output buffers as needed.
6075 * Therefore there's no need to enable the input buffer at this
6076 * stage.
cdcd9268 6077 */
f7ace40d 6078 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6079 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6080 * mixer ctrl)
6081 */
f7ace40d
JW
6082 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6083
6084 /* Mute capture amp left and right */
6085 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6086 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6087 * in (on mic1 pin)
6088 */
6089 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6090
6091 /* Do the same for the second ADC: mute capture input amp and
6092 * set ADC connection to line in (on mic1 pin)
6093 */
6094 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6095 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6096
6097 /* Mute all inputs to mixer widget (even unconnected ones) */
6098 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6099 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6100 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6101 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6102 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6103 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6104 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6105 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6106
6107 { }
a9430dd8
JW
6108};
6109
0bfc90e9
JW
6110/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6111 * similar laptops (adapted from Fujitsu init verbs).
6112 */
6113static struct hda_verb alc260_acer_init_verbs[] = {
6114 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6115 * the headphone jack. Turn this on and rely on the standard mute
6116 * methods whenever the user wants to turn these outputs off.
6117 */
6118 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6119 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6120 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6121 /* Internal speaker/Headphone jack is connected to Line-out pin */
6122 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6123 /* Internal microphone/Mic jack is connected to Mic1 pin */
6124 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6125 /* Line In jack is connected to Line1 pin */
6126 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6127 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6128 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6129 /* Ensure all other unused pins are disabled and muted. */
6130 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6131 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6132 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6133 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6134 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6135 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6136 /* Disable digital (SPDIF) pins */
6137 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6138 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6139
ea1fb29a 6140 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6141 * bus when acting as outputs.
6142 */
6143 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6144 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6145
6146 /* Start with output sum widgets muted and their output gains at min */
6147 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6148 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6149 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6150 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6151 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6152 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6153 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6154 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6155 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6156
f12ab1e0
TI
6157 /* Unmute Line-out pin widget amp left and right
6158 * (no equiv mixer ctrl)
6159 */
0bfc90e9 6160 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6161 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6162 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6163 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6164 * inputs. If the pin mode is changed by the user the pin mode control
6165 * will take care of enabling the pin's input/output buffers as needed.
6166 * Therefore there's no need to enable the input buffer at this
6167 * stage.
6168 */
6169 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6170 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6171
6172 /* Mute capture amp left and right */
6173 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6174 /* Set ADC connection select to match default mixer setting - mic
6175 * (on mic1 pin)
6176 */
6177 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6178
6179 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6180 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6181 */
6182 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6183 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6184
6185 /* Mute all inputs to mixer widget (even unconnected ones) */
6186 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6187 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6188 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6189 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6190 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6191 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6192 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6193 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6194
6195 { }
6196};
6197
cc959489
MS
6198/* Initialisation sequence for Maxdata Favorit 100XS
6199 * (adapted from Acer init verbs).
6200 */
6201static struct hda_verb alc260_favorit100_init_verbs[] = {
6202 /* GPIO 0 enables the output jack.
6203 * Turn this on and rely on the standard mute
6204 * methods whenever the user wants to turn these outputs off.
6205 */
6206 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6207 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6208 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6209 /* Line/Mic input jack is connected to Mic1 pin */
6210 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6211 /* Ensure all other unused pins are disabled and muted. */
6212 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6213 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6214 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6215 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6216 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6217 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6218 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6219 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6220 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6221 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6222 /* Disable digital (SPDIF) pins */
6223 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6224 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6225
6226 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6227 * bus when acting as outputs.
6228 */
6229 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6230 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6231
6232 /* Start with output sum widgets muted and their output gains at min */
6233 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6234 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6235 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6236 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6237 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6238 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6239 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6240 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6241 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6242
6243 /* Unmute Line-out pin widget amp left and right
6244 * (no equiv mixer ctrl)
6245 */
6246 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6247 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6248 * inputs. If the pin mode is changed by the user the pin mode control
6249 * will take care of enabling the pin's input/output buffers as needed.
6250 * Therefore there's no need to enable the input buffer at this
6251 * stage.
6252 */
6253 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6254
6255 /* Mute capture amp left and right */
6256 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6257 /* Set ADC connection select to match default mixer setting - mic
6258 * (on mic1 pin)
6259 */
6260 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6261
6262 /* Do similar with the second ADC: mute capture input amp and
6263 * set ADC connection to mic to match ALSA's default state.
6264 */
6265 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6266 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6267
6268 /* Mute all inputs to mixer widget (even unconnected ones) */
6269 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6270 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6271 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6272 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6273 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6274 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6275 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6276 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6277
6278 { }
6279};
6280
bc9f98a9
KY
6281static struct hda_verb alc260_will_verbs[] = {
6282 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6283 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6284 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6285 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6286 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6287 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6288 {}
6289};
6290
6291static struct hda_verb alc260_replacer_672v_verbs[] = {
6292 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6293 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6294 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6295
6296 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6297 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6298 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6299
6300 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6301 {}
6302};
6303
6304/* toggle speaker-output according to the hp-jack state */
6305static void alc260_replacer_672v_automute(struct hda_codec *codec)
6306{
6307 unsigned int present;
6308
6309 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6310 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6311 if (present) {
82beb8fd
TI
6312 snd_hda_codec_write_cache(codec, 0x01, 0,
6313 AC_VERB_SET_GPIO_DATA, 1);
6314 snd_hda_codec_write_cache(codec, 0x0f, 0,
6315 AC_VERB_SET_PIN_WIDGET_CONTROL,
6316 PIN_HP);
bc9f98a9 6317 } else {
82beb8fd
TI
6318 snd_hda_codec_write_cache(codec, 0x01, 0,
6319 AC_VERB_SET_GPIO_DATA, 0);
6320 snd_hda_codec_write_cache(codec, 0x0f, 0,
6321 AC_VERB_SET_PIN_WIDGET_CONTROL,
6322 PIN_OUT);
bc9f98a9
KY
6323 }
6324}
6325
6326static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6327 unsigned int res)
6328{
6329 if ((res >> 26) == ALC880_HP_EVENT)
6330 alc260_replacer_672v_automute(codec);
6331}
6332
3f878308
KY
6333static struct hda_verb alc260_hp_dc7600_verbs[] = {
6334 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6335 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6336 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6337 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6338 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6339 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6340 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6341 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6342 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6343 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6344 {}
6345};
6346
7cf51e48
JW
6347/* Test configuration for debugging, modelled after the ALC880 test
6348 * configuration.
6349 */
6350#ifdef CONFIG_SND_DEBUG
6351static hda_nid_t alc260_test_dac_nids[1] = {
6352 0x02,
6353};
6354static hda_nid_t alc260_test_adc_nids[2] = {
6355 0x04, 0x05,
6356};
a1e8d2da 6357/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6358 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6359 * is NID 0x04.
17e7aec6 6360 */
a1e8d2da
JW
6361static struct hda_input_mux alc260_test_capture_sources[2] = {
6362 {
6363 .num_items = 7,
6364 .items = {
6365 { "MIC1 pin", 0x0 },
6366 { "MIC2 pin", 0x1 },
6367 { "LINE1 pin", 0x2 },
6368 { "LINE2 pin", 0x3 },
6369 { "CD pin", 0x4 },
6370 { "LINE-OUT pin", 0x5 },
6371 { "HP-OUT pin", 0x6 },
6372 },
6373 },
6374 {
6375 .num_items = 8,
6376 .items = {
6377 { "MIC1 pin", 0x0 },
6378 { "MIC2 pin", 0x1 },
6379 { "LINE1 pin", 0x2 },
6380 { "LINE2 pin", 0x3 },
6381 { "CD pin", 0x4 },
6382 { "Mixer", 0x5 },
6383 { "LINE-OUT pin", 0x6 },
6384 { "HP-OUT pin", 0x7 },
6385 },
7cf51e48
JW
6386 },
6387};
6388static struct snd_kcontrol_new alc260_test_mixer[] = {
6389 /* Output driver widgets */
6390 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6391 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6392 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6393 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6394 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6395 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6396
a1e8d2da
JW
6397 /* Modes for retasking pin widgets
6398 * Note: the ALC260 doesn't seem to act on requests to enable mic
6399 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6400 * mention this restriction. At this stage it's not clear whether
6401 * this behaviour is intentional or is a hardware bug in chip
6402 * revisions available at least up until early 2006. Therefore for
6403 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6404 * choices, but if it turns out that the lack of mic bias for these
6405 * NIDs is intentional we could change their modes from
6406 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6407 */
7cf51e48
JW
6408 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6409 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6410 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6411 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6412 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6413 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6414
6415 /* Loopback mixer controls */
6416 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6417 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6418 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6419 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6420 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6421 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6422 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6423 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6424 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6425 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6426 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6427 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6428 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6429 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6430
6431 /* Controls for GPIO pins, assuming they are configured as outputs */
6432 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6433 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6434 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6435 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6436
92621f13
JW
6437 /* Switches to allow the digital IO pins to be enabled. The datasheet
6438 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6439 * make this output available should provide clarification.
92621f13
JW
6440 */
6441 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6442 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6443
f8225f6d
JW
6444 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6445 * this output to turn on an external amplifier.
6446 */
6447 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6448 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6449
7cf51e48
JW
6450 { } /* end */
6451};
6452static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6453 /* Enable all GPIOs as outputs with an initial value of 0 */
6454 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6455 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6456 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6457
7cf51e48
JW
6458 /* Enable retasking pins as output, initially without power amp */
6459 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6460 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6461 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6462 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6463 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6464 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6465
92621f13
JW
6466 /* Disable digital (SPDIF) pins initially, but users can enable
6467 * them via a mixer switch. In the case of SPDIF-out, this initverb
6468 * payload also sets the generation to 0, output to be in "consumer"
6469 * PCM format, copyright asserted, no pre-emphasis and no validity
6470 * control.
6471 */
7cf51e48
JW
6472 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6473 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6474
ea1fb29a 6475 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6476 * OUT1 sum bus when acting as an output.
6477 */
6478 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6479 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6480 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6481 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6482
6483 /* Start with output sum widgets muted and their output gains at min */
6484 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6485 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6486 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6487 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6488 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6489 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6490 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6491 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6492 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6493
cdcd9268
JW
6494 /* Unmute retasking pin widget output buffers since the default
6495 * state appears to be output. As the pin mode is changed by the
6496 * user the pin mode control will take care of enabling the pin's
6497 * input/output buffers as needed.
6498 */
7cf51e48
JW
6499 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6500 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6501 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6502 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6503 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6504 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6505 /* Also unmute the mono-out pin widget */
6506 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6507
7cf51e48
JW
6508 /* Mute capture amp left and right */
6509 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6510 /* Set ADC connection select to match default mixer setting (mic1
6511 * pin)
7cf51e48
JW
6512 */
6513 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6514
6515 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6516 * set ADC connection to mic1 pin
7cf51e48
JW
6517 */
6518 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6519 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6520
6521 /* Mute all inputs to mixer widget (even unconnected ones) */
6522 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6523 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6524 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6525 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6526 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6527 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6528 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6529 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6530
6531 { }
6532};
6533#endif
6534
6330079f
TI
6535#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6536#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6537
a3bcba38
TI
6538#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6539#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6540
df694daa
KY
6541/*
6542 * for BIOS auto-configuration
6543 */
16ded525 6544
df694daa 6545static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6546 const char *pfx, int *vol_bits)
df694daa
KY
6547{
6548 hda_nid_t nid_vol;
6549 unsigned long vol_val, sw_val;
df694daa
KY
6550 int err;
6551
6552 if (nid >= 0x0f && nid < 0x11) {
6553 nid_vol = nid - 0x7;
6554 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6555 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6556 } else if (nid == 0x11) {
6557 nid_vol = nid - 0x7;
6558 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6559 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6560 } else if (nid >= 0x12 && nid <= 0x15) {
6561 nid_vol = 0x08;
6562 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6563 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6564 } else
6565 return 0; /* N/A */
ea1fb29a 6566
863b4518
TI
6567 if (!(*vol_bits & (1 << nid_vol))) {
6568 /* first control for the volume widget */
0afe5f89 6569 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6570 if (err < 0)
6571 return err;
6572 *vol_bits |= (1 << nid_vol);
6573 }
0afe5f89 6574 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6575 if (err < 0)
df694daa
KY
6576 return err;
6577 return 1;
6578}
6579
6580/* add playback controls from the parsed DAC table */
6581static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6582 const struct auto_pin_cfg *cfg)
6583{
6584 hda_nid_t nid;
6585 int err;
863b4518 6586 int vols = 0;
df694daa
KY
6587
6588 spec->multiout.num_dacs = 1;
6589 spec->multiout.dac_nids = spec->private_dac_nids;
6590 spec->multiout.dac_nids[0] = 0x02;
6591
6592 nid = cfg->line_out_pins[0];
6593 if (nid) {
23112d6d
TI
6594 const char *pfx;
6595 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6596 pfx = "Master";
6597 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6598 pfx = "Speaker";
6599 else
6600 pfx = "Front";
6601 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6602 if (err < 0)
6603 return err;
6604 }
6605
82bc955f 6606 nid = cfg->speaker_pins[0];
df694daa 6607 if (nid) {
863b4518 6608 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6609 if (err < 0)
6610 return err;
6611 }
6612
eb06ed8f 6613 nid = cfg->hp_pins[0];
df694daa 6614 if (nid) {
863b4518
TI
6615 err = alc260_add_playback_controls(spec, nid, "Headphone",
6616 &vols);
df694daa
KY
6617 if (err < 0)
6618 return err;
6619 }
f12ab1e0 6620 return 0;
df694daa
KY
6621}
6622
6623/* create playback/capture controls for input pins */
05f5f477 6624static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6625 const struct auto_pin_cfg *cfg)
6626{
05f5f477 6627 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6628}
6629
6630static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6631 hda_nid_t nid, int pin_type,
6632 int sel_idx)
6633{
f6c7e546 6634 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6635 /* need the manual connection? */
6636 if (nid >= 0x12) {
6637 int idx = nid - 0x12;
6638 snd_hda_codec_write(codec, idx + 0x0b, 0,
6639 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6640 }
6641}
6642
6643static void alc260_auto_init_multi_out(struct hda_codec *codec)
6644{
6645 struct alc_spec *spec = codec->spec;
6646 hda_nid_t nid;
6647
f12ab1e0 6648 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6649 if (nid) {
6650 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6651 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6652 }
ea1fb29a 6653
82bc955f 6654 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6655 if (nid)
6656 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6657
eb06ed8f 6658 nid = spec->autocfg.hp_pins[0];
df694daa 6659 if (nid)
baba8ee9 6660 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6661}
df694daa
KY
6662
6663#define ALC260_PIN_CD_NID 0x16
6664static void alc260_auto_init_analog_input(struct hda_codec *codec)
6665{
6666 struct alc_spec *spec = codec->spec;
6667 int i;
6668
6669 for (i = 0; i < AUTO_PIN_LAST; i++) {
6670 hda_nid_t nid = spec->autocfg.input_pins[i];
6671 if (nid >= 0x12) {
23f0c048 6672 alc_set_input_pin(codec, nid, i);
e82c025b
TI
6673 if (nid != ALC260_PIN_CD_NID &&
6674 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6675 snd_hda_codec_write(codec, nid, 0,
6676 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6677 AMP_OUT_MUTE);
6678 }
6679 }
6680}
6681
7f311a46
TI
6682#define alc260_auto_init_input_src alc880_auto_init_input_src
6683
df694daa
KY
6684/*
6685 * generic initialization of ADC, input mixers and output mixers
6686 */
6687static struct hda_verb alc260_volume_init_verbs[] = {
6688 /*
6689 * Unmute ADC0-1 and set the default input to mic-in
6690 */
6691 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6692 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6693 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6694 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 6695
df694daa
KY
6696 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6697 * mixer widget
f12ab1e0
TI
6698 * Note: PASD motherboards uses the Line In 2 as the input for
6699 * front panel mic (mic 2)
df694daa
KY
6700 */
6701 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6702 /* mute analog inputs */
6703 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6704 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6705 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6706 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6707 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6708
6709 /*
6710 * Set up output mixers (0x08 - 0x0a)
6711 */
6712 /* set vol=0 to output mixers */
6713 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6714 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6715 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6716 /* set up input amps for analog loopback */
6717 /* Amp Indices: DAC = 0, mixer = 1 */
6718 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6719 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6720 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6721 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6722 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6723 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 6724
df694daa
KY
6725 { }
6726};
6727
6728static int alc260_parse_auto_config(struct hda_codec *codec)
6729{
6730 struct alc_spec *spec = codec->spec;
df694daa
KY
6731 int err;
6732 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6733
f12ab1e0
TI
6734 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6735 alc260_ignore);
6736 if (err < 0)
df694daa 6737 return err;
f12ab1e0
TI
6738 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6739 if (err < 0)
4a471b7d 6740 return err;
603c4019 6741 if (!spec->kctls.list)
df694daa 6742 return 0; /* can't find valid BIOS pin config */
05f5f477 6743 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 6744 if (err < 0)
df694daa
KY
6745 return err;
6746
6747 spec->multiout.max_channels = 2;
6748
0852d7a6 6749 if (spec->autocfg.dig_outs)
df694daa 6750 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 6751 if (spec->kctls.list)
d88897ea 6752 add_mixer(spec, spec->kctls.list);
df694daa 6753
d88897ea 6754 add_verb(spec, alc260_volume_init_verbs);
df694daa 6755
a1e8d2da 6756 spec->num_mux_defs = 1;
61b9b9b1 6757 spec->input_mux = &spec->private_imux[0];
df694daa 6758
6227cdce 6759 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 6760
df694daa
KY
6761 return 1;
6762}
6763
ae6b813a
TI
6764/* additional initialization for auto-configuration model */
6765static void alc260_auto_init(struct hda_codec *codec)
df694daa 6766{
f6c7e546 6767 struct alc_spec *spec = codec->spec;
df694daa
KY
6768 alc260_auto_init_multi_out(codec);
6769 alc260_auto_init_analog_input(codec);
7f311a46 6770 alc260_auto_init_input_src(codec);
757899ac 6771 alc_auto_init_digital(codec);
f6c7e546 6772 if (spec->unsol_event)
7fb0d78f 6773 alc_inithook(codec);
df694daa
KY
6774}
6775
cb53c626
TI
6776#ifdef CONFIG_SND_HDA_POWER_SAVE
6777static struct hda_amp_list alc260_loopbacks[] = {
6778 { 0x07, HDA_INPUT, 0 },
6779 { 0x07, HDA_INPUT, 1 },
6780 { 0x07, HDA_INPUT, 2 },
6781 { 0x07, HDA_INPUT, 3 },
6782 { 0x07, HDA_INPUT, 4 },
6783 { } /* end */
6784};
6785#endif
6786
df694daa
KY
6787/*
6788 * ALC260 configurations
6789 */
f5fcc13c
TI
6790static const char *alc260_models[ALC260_MODEL_LAST] = {
6791 [ALC260_BASIC] = "basic",
6792 [ALC260_HP] = "hp",
6793 [ALC260_HP_3013] = "hp-3013",
2922c9af 6794 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
6795 [ALC260_FUJITSU_S702X] = "fujitsu",
6796 [ALC260_ACER] = "acer",
bc9f98a9
KY
6797 [ALC260_WILL] = "will",
6798 [ALC260_REPLACER_672V] = "replacer",
cc959489 6799 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 6800#ifdef CONFIG_SND_DEBUG
f5fcc13c 6801 [ALC260_TEST] = "test",
7cf51e48 6802#endif
f5fcc13c
TI
6803 [ALC260_AUTO] = "auto",
6804};
6805
6806static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 6807 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 6808 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 6809 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 6810 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 6811 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 6812 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 6813 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 6814 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 6815 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
6816 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6817 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6818 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6819 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6820 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6821 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6822 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6823 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6824 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 6825 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 6826 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
6827 {}
6828};
6829
6830static struct alc_config_preset alc260_presets[] = {
6831 [ALC260_BASIC] = {
6832 .mixers = { alc260_base_output_mixer,
45bdd1c1 6833 alc260_input_mixer },
df694daa
KY
6834 .init_verbs = { alc260_init_verbs },
6835 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6836 .dac_nids = alc260_dac_nids,
f9e336f6 6837 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 6838 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
6839 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6840 .channel_mode = alc260_modes,
6841 .input_mux = &alc260_capture_source,
6842 },
6843 [ALC260_HP] = {
bec15c3a 6844 .mixers = { alc260_hp_output_mixer,
f9e336f6 6845 alc260_input_mixer },
bec15c3a
TI
6846 .init_verbs = { alc260_init_verbs,
6847 alc260_hp_unsol_verbs },
df694daa
KY
6848 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6849 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6850 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6851 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6852 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6853 .channel_mode = alc260_modes,
6854 .input_mux = &alc260_capture_source,
bec15c3a
TI
6855 .unsol_event = alc260_hp_unsol_event,
6856 .init_hook = alc260_hp_automute,
df694daa 6857 },
3f878308
KY
6858 [ALC260_HP_DC7600] = {
6859 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 6860 alc260_input_mixer },
3f878308
KY
6861 .init_verbs = { alc260_init_verbs,
6862 alc260_hp_dc7600_verbs },
6863 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6864 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6865 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6866 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
6867 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6868 .channel_mode = alc260_modes,
6869 .input_mux = &alc260_capture_source,
6870 .unsol_event = alc260_hp_3012_unsol_event,
6871 .init_hook = alc260_hp_3012_automute,
6872 },
df694daa
KY
6873 [ALC260_HP_3013] = {
6874 .mixers = { alc260_hp_3013_mixer,
f9e336f6 6875 alc260_input_mixer },
bec15c3a
TI
6876 .init_verbs = { alc260_hp_3013_init_verbs,
6877 alc260_hp_3013_unsol_verbs },
df694daa
KY
6878 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6879 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6880 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6881 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6882 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6883 .channel_mode = alc260_modes,
6884 .input_mux = &alc260_capture_source,
bec15c3a
TI
6885 .unsol_event = alc260_hp_3013_unsol_event,
6886 .init_hook = alc260_hp_3013_automute,
df694daa
KY
6887 },
6888 [ALC260_FUJITSU_S702X] = {
f9e336f6 6889 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
6890 .init_verbs = { alc260_fujitsu_init_verbs },
6891 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6892 .dac_nids = alc260_dac_nids,
d57fdac0
JW
6893 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6894 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
6895 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6896 .channel_mode = alc260_modes,
a1e8d2da
JW
6897 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6898 .input_mux = alc260_fujitsu_capture_sources,
df694daa 6899 },
0bfc90e9 6900 [ALC260_ACER] = {
f9e336f6 6901 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
6902 .init_verbs = { alc260_acer_init_verbs },
6903 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6904 .dac_nids = alc260_dac_nids,
6905 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6906 .adc_nids = alc260_dual_adc_nids,
6907 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6908 .channel_mode = alc260_modes,
a1e8d2da
JW
6909 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6910 .input_mux = alc260_acer_capture_sources,
0bfc90e9 6911 },
cc959489
MS
6912 [ALC260_FAVORIT100] = {
6913 .mixers = { alc260_favorit100_mixer },
6914 .init_verbs = { alc260_favorit100_init_verbs },
6915 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6916 .dac_nids = alc260_dac_nids,
6917 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6918 .adc_nids = alc260_dual_adc_nids,
6919 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6920 .channel_mode = alc260_modes,
6921 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6922 .input_mux = alc260_favorit100_capture_sources,
6923 },
bc9f98a9 6924 [ALC260_WILL] = {
f9e336f6 6925 .mixers = { alc260_will_mixer },
bc9f98a9
KY
6926 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6927 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6928 .dac_nids = alc260_dac_nids,
6929 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6930 .adc_nids = alc260_adc_nids,
6931 .dig_out_nid = ALC260_DIGOUT_NID,
6932 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6933 .channel_mode = alc260_modes,
6934 .input_mux = &alc260_capture_source,
6935 },
6936 [ALC260_REPLACER_672V] = {
f9e336f6 6937 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
6938 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6939 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6940 .dac_nids = alc260_dac_nids,
6941 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6942 .adc_nids = alc260_adc_nids,
6943 .dig_out_nid = ALC260_DIGOUT_NID,
6944 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6945 .channel_mode = alc260_modes,
6946 .input_mux = &alc260_capture_source,
6947 .unsol_event = alc260_replacer_672v_unsol_event,
6948 .init_hook = alc260_replacer_672v_automute,
6949 },
7cf51e48
JW
6950#ifdef CONFIG_SND_DEBUG
6951 [ALC260_TEST] = {
f9e336f6 6952 .mixers = { alc260_test_mixer },
7cf51e48
JW
6953 .init_verbs = { alc260_test_init_verbs },
6954 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6955 .dac_nids = alc260_test_dac_nids,
6956 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6957 .adc_nids = alc260_test_adc_nids,
6958 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6959 .channel_mode = alc260_modes,
a1e8d2da
JW
6960 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6961 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
6962 },
6963#endif
df694daa
KY
6964};
6965
6966static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
6967{
6968 struct alc_spec *spec;
df694daa 6969 int err, board_config;
1da177e4 6970
e560d8d8 6971 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
6972 if (spec == NULL)
6973 return -ENOMEM;
6974
6975 codec->spec = spec;
6976
f5fcc13c
TI
6977 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6978 alc260_models,
6979 alc260_cfg_tbl);
6980 if (board_config < 0) {
9a11f1aa 6981 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 6982 codec->chip_name);
df694daa 6983 board_config = ALC260_AUTO;
16ded525 6984 }
1da177e4 6985
df694daa
KY
6986 if (board_config == ALC260_AUTO) {
6987 /* automatic parse from the BIOS config */
6988 err = alc260_parse_auto_config(codec);
6989 if (err < 0) {
6990 alc_free(codec);
6991 return err;
f12ab1e0 6992 } else if (!err) {
9c7f852e
TI
6993 printk(KERN_INFO
6994 "hda_codec: Cannot set up configuration "
6995 "from BIOS. Using base mode...\n");
df694daa
KY
6996 board_config = ALC260_BASIC;
6997 }
a9430dd8 6998 }
e9edcee0 6999
680cd536
KK
7000 err = snd_hda_attach_beep_device(codec, 0x1);
7001 if (err < 0) {
7002 alc_free(codec);
7003 return err;
7004 }
7005
df694daa 7006 if (board_config != ALC260_AUTO)
e9c364c0 7007 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7008
1da177e4
LT
7009 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7010 spec->stream_analog_capture = &alc260_pcm_analog_capture;
7011
a3bcba38
TI
7012 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7013 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7014
4ef0ef19
TI
7015 if (!spec->adc_nids && spec->input_mux) {
7016 /* check whether NID 0x04 is valid */
7017 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7018 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7019 /* get type */
7020 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7021 spec->adc_nids = alc260_adc_nids_alt;
7022 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7023 } else {
7024 spec->adc_nids = alc260_adc_nids;
7025 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7026 }
7027 }
b59bdf3b 7028 set_capture_mixer(codec);
45bdd1c1 7029 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7030
2134ea4f
TI
7031 spec->vmaster_nid = 0x08;
7032
1da177e4 7033 codec->patch_ops = alc_patch_ops;
df694daa 7034 if (board_config == ALC260_AUTO)
ae6b813a 7035 spec->init_hook = alc260_auto_init;
cb53c626
TI
7036#ifdef CONFIG_SND_HDA_POWER_SAVE
7037 if (!spec->loopback.amplist)
7038 spec->loopback.amplist = alc260_loopbacks;
7039#endif
1da177e4
LT
7040
7041 return 0;
7042}
7043
e9edcee0 7044
1da177e4 7045/*
4953550a 7046 * ALC882/883/885/888/889 support
1da177e4
LT
7047 *
7048 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7049 * configuration. Each pin widget can choose any input DACs and a mixer.
7050 * Each ADC is connected from a mixer of all inputs. This makes possible
7051 * 6-channel independent captures.
7052 *
7053 * In addition, an independent DAC for the multi-playback (not used in this
7054 * driver yet).
7055 */
df694daa
KY
7056#define ALC882_DIGOUT_NID 0x06
7057#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7058#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7059#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7060#define ALC1200_DIGOUT_NID 0x10
7061
1da177e4 7062
d2a6d7dc 7063static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7064 { 8, NULL }
7065};
7066
4953550a 7067/* DACs */
1da177e4
LT
7068static hda_nid_t alc882_dac_nids[4] = {
7069 /* front, rear, clfe, rear_surr */
7070 0x02, 0x03, 0x04, 0x05
7071};
4953550a 7072#define alc883_dac_nids alc882_dac_nids
1da177e4 7073
4953550a 7074/* ADCs */
df694daa
KY
7075#define alc882_adc_nids alc880_adc_nids
7076#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
7077#define alc883_adc_nids alc882_adc_nids_alt
7078static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7079static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7080#define alc889_adc_nids alc880_adc_nids
1da177e4 7081
e1406348
TI
7082static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7083static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
7084#define alc883_capsrc_nids alc882_capsrc_nids_alt
7085static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7086#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7087
1da177e4
LT
7088/* input MUX */
7089/* FIXME: should be a matrix-type input source selection */
7090
7091static struct hda_input_mux alc882_capture_source = {
7092 .num_items = 4,
7093 .items = {
7094 { "Mic", 0x0 },
7095 { "Front Mic", 0x1 },
7096 { "Line", 0x2 },
7097 { "CD", 0x4 },
7098 },
7099};
41d5545d 7100
4953550a
TI
7101#define alc883_capture_source alc882_capture_source
7102
87a8c370
JK
7103static struct hda_input_mux alc889_capture_source = {
7104 .num_items = 3,
7105 .items = {
7106 { "Front Mic", 0x0 },
7107 { "Mic", 0x3 },
7108 { "Line", 0x2 },
7109 },
7110};
7111
41d5545d
KS
7112static struct hda_input_mux mb5_capture_source = {
7113 .num_items = 3,
7114 .items = {
7115 { "Mic", 0x1 },
b8f171e7 7116 { "Line", 0x7 },
41d5545d
KS
7117 { "CD", 0x4 },
7118 },
7119};
7120
e458b1fa
LY
7121static struct hda_input_mux macmini3_capture_source = {
7122 .num_items = 2,
7123 .items = {
7124 { "Line", 0x2 },
7125 { "CD", 0x4 },
7126 },
7127};
7128
4953550a
TI
7129static struct hda_input_mux alc883_3stack_6ch_intel = {
7130 .num_items = 4,
7131 .items = {
7132 { "Mic", 0x1 },
7133 { "Front Mic", 0x0 },
7134 { "Line", 0x2 },
7135 { "CD", 0x4 },
7136 },
7137};
7138
7139static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7140 .num_items = 2,
7141 .items = {
7142 { "Mic", 0x1 },
7143 { "Line", 0x2 },
7144 },
7145};
7146
7147static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7148 .num_items = 4,
7149 .items = {
7150 { "Mic", 0x0 },
150b432f 7151 { "Int Mic", 0x1 },
4953550a
TI
7152 { "Line", 0x2 },
7153 { "CD", 0x4 },
7154 },
7155};
7156
7157static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7158 .num_items = 2,
7159 .items = {
7160 { "Mic", 0x0 },
7161 { "Int Mic", 0x1 },
7162 },
7163};
7164
7165static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7166 .num_items = 3,
7167 .items = {
7168 { "Mic", 0x0 },
7169 { "Front Mic", 0x1 },
7170 { "Line", 0x4 },
7171 },
7172};
7173
7174static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7175 .num_items = 2,
7176 .items = {
7177 { "Mic", 0x0 },
7178 { "Line", 0x2 },
7179 },
7180};
7181
7182static struct hda_input_mux alc889A_mb31_capture_source = {
7183 .num_items = 2,
7184 .items = {
7185 { "Mic", 0x0 },
7186 /* Front Mic (0x01) unused */
7187 { "Line", 0x2 },
7188 /* Line 2 (0x03) unused */
af901ca1 7189 /* CD (0x04) unused? */
4953550a
TI
7190 },
7191};
7192
b7cccc52
JM
7193static struct hda_input_mux alc889A_imac91_capture_source = {
7194 .num_items = 2,
7195 .items = {
7196 { "Mic", 0x01 },
7197 { "Line", 0x2 }, /* Not sure! */
7198 },
7199};
7200
4953550a
TI
7201/*
7202 * 2ch mode
7203 */
7204static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7205 { 2, NULL }
7206};
7207
272a527c
KY
7208/*
7209 * 2ch mode
7210 */
7211static struct hda_verb alc882_3ST_ch2_init[] = {
7212 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7213 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7214 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7215 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7216 { } /* end */
7217};
7218
4953550a
TI
7219/*
7220 * 4ch mode
7221 */
7222static struct hda_verb alc882_3ST_ch4_init[] = {
7223 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7224 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7225 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7226 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7227 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7228 { } /* end */
7229};
7230
272a527c
KY
7231/*
7232 * 6ch mode
7233 */
7234static struct hda_verb alc882_3ST_ch6_init[] = {
7235 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7236 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7237 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7238 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7239 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7240 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7241 { } /* end */
7242};
7243
4953550a 7244static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7245 { 2, alc882_3ST_ch2_init },
4953550a 7246 { 4, alc882_3ST_ch4_init },
272a527c
KY
7247 { 6, alc882_3ST_ch6_init },
7248};
7249
4953550a
TI
7250#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7251
a65cc60f 7252/*
7253 * 2ch mode
7254 */
7255static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7256 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7257 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7258 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7259 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7260 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7261 { } /* end */
7262};
7263
7264/*
7265 * 4ch mode
7266 */
7267static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7268 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7269 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7270 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7271 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7272 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7273 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7274 { } /* end */
7275};
7276
7277/*
7278 * 6ch mode
7279 */
7280static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7281 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7282 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7283 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7284 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7285 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7286 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7287 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7288 { } /* end */
7289};
7290
7291static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7292 { 2, alc883_3ST_ch2_clevo_init },
7293 { 4, alc883_3ST_ch4_clevo_init },
7294 { 6, alc883_3ST_ch6_clevo_init },
7295};
7296
7297
df694daa
KY
7298/*
7299 * 6ch mode
7300 */
7301static struct hda_verb alc882_sixstack_ch6_init[] = {
7302 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7303 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7304 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7305 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7306 { } /* end */
7307};
7308
7309/*
7310 * 8ch mode
7311 */
7312static struct hda_verb alc882_sixstack_ch8_init[] = {
7313 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7314 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7315 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7316 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7317 { } /* end */
7318};
7319
7320static struct hda_channel_mode alc882_sixstack_modes[2] = {
7321 { 6, alc882_sixstack_ch6_init },
7322 { 8, alc882_sixstack_ch8_init },
7323};
7324
76e6f5a9
RH
7325
7326/* Macbook Air 2,1 */
7327
7328static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7329 { 2, NULL },
7330};
7331
87350ad0 7332/*
def319f9 7333 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7334 */
7335
7336/*
7337 * 2ch mode
7338 */
7339static struct hda_verb alc885_mbp_ch2_init[] = {
7340 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7341 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7342 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7343 { } /* end */
7344};
7345
7346/*
a3f730af 7347 * 4ch mode
87350ad0 7348 */
a3f730af 7349static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7350 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7351 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7352 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7353 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7354 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7355 { } /* end */
7356};
7357
a3f730af 7358static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7359 { 2, alc885_mbp_ch2_init },
a3f730af 7360 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7361};
7362
92b9de83
KS
7363/*
7364 * 2ch
7365 * Speakers/Woofer/HP = Front
7366 * LineIn = Input
7367 */
7368static struct hda_verb alc885_mb5_ch2_init[] = {
7369 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7370 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7371 { } /* end */
7372};
7373
7374/*
7375 * 6ch mode
7376 * Speakers/HP = Front
7377 * Woofer = LFE
7378 * LineIn = Surround
7379 */
7380static struct hda_verb alc885_mb5_ch6_init[] = {
7381 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7382 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7383 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7384 { } /* end */
7385};
7386
7387static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7388 { 2, alc885_mb5_ch2_init },
7389 { 6, alc885_mb5_ch6_init },
7390};
87350ad0 7391
d01aecdf 7392#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7393
7394/*
7395 * 2ch mode
7396 */
7397static struct hda_verb alc883_4ST_ch2_init[] = {
7398 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7399 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7400 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7401 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7402 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7403 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7404 { } /* end */
7405};
7406
7407/*
7408 * 4ch mode
7409 */
7410static struct hda_verb alc883_4ST_ch4_init[] = {
7411 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7412 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7413 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7414 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7415 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7416 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7417 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7418 { } /* end */
7419};
7420
7421/*
7422 * 6ch mode
7423 */
7424static struct hda_verb alc883_4ST_ch6_init[] = {
7425 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7426 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7427 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7428 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7429 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7430 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7431 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7432 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7433 { } /* end */
7434};
7435
7436/*
7437 * 8ch mode
7438 */
7439static struct hda_verb alc883_4ST_ch8_init[] = {
7440 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7441 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7442 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7443 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7444 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7445 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7446 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7447 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7448 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7449 { } /* end */
7450};
7451
7452static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7453 { 2, alc883_4ST_ch2_init },
7454 { 4, alc883_4ST_ch4_init },
7455 { 6, alc883_4ST_ch6_init },
7456 { 8, alc883_4ST_ch8_init },
7457};
7458
7459
7460/*
7461 * 2ch mode
7462 */
7463static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7464 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7465 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7466 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7467 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7468 { } /* end */
7469};
7470
7471/*
7472 * 4ch mode
7473 */
7474static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7475 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7476 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7477 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7478 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7479 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7480 { } /* end */
7481};
7482
7483/*
7484 * 6ch mode
7485 */
7486static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7487 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7488 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7489 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7490 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7491 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7492 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7493 { } /* end */
7494};
7495
7496static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7497 { 2, alc883_3ST_ch2_intel_init },
7498 { 4, alc883_3ST_ch4_intel_init },
7499 { 6, alc883_3ST_ch6_intel_init },
7500};
7501
dd7714c9
WF
7502/*
7503 * 2ch mode
7504 */
7505static struct hda_verb alc889_ch2_intel_init[] = {
7506 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7507 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7508 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7509 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7510 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7511 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7512 { } /* end */
7513};
7514
87a8c370
JK
7515/*
7516 * 6ch mode
7517 */
7518static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7519 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7520 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7521 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7522 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7523 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7524 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7525 { } /* end */
7526};
7527
7528/*
7529 * 8ch mode
7530 */
7531static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7532 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7533 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7534 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7535 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7536 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7537 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7538 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7539 { } /* end */
7540};
7541
dd7714c9
WF
7542static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7543 { 2, alc889_ch2_intel_init },
87a8c370
JK
7544 { 6, alc889_ch6_intel_init },
7545 { 8, alc889_ch8_intel_init },
7546};
7547
4953550a
TI
7548/*
7549 * 6ch mode
7550 */
7551static struct hda_verb alc883_sixstack_ch6_init[] = {
7552 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7553 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7554 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7555 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7556 { } /* end */
7557};
7558
7559/*
7560 * 8ch mode
7561 */
7562static struct hda_verb alc883_sixstack_ch8_init[] = {
7563 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7564 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7565 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7566 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7567 { } /* end */
7568};
7569
7570static struct hda_channel_mode alc883_sixstack_modes[2] = {
7571 { 6, alc883_sixstack_ch6_init },
7572 { 8, alc883_sixstack_ch8_init },
7573};
7574
7575
1da177e4
LT
7576/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7577 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7578 */
c8b6bf9b 7579static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7580 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7581 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7582 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7583 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7584 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7585 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7586 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7587 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7588 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7589 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7590 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7591 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7592 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7593 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7594 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7595 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7596 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
7597 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7598 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7599 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4 7600 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7601 { } /* end */
7602};
7603
76e6f5a9
RH
7604/* Macbook Air 2,1 same control for HP and internal Speaker */
7605
7606static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7607 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7608 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7609 { }
7610};
7611
7612
87350ad0 7613static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7614 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7615 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7616 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7617 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7618 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7619 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7620 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7621 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7622 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 7623 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
7624 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7625 { } /* end */
7626};
41d5545d
KS
7627
7628static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
7629 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7630 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7631 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7632 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7633 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7634 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
7635 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7636 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
7637 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7638 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
7639 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7640 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7641 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7642 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7643 { } /* end */
7644};
92b9de83 7645
e458b1fa
LY
7646static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7647 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7648 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7649 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7650 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7651 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7652 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7653 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7654 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7655 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7656 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7657 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7658 { } /* end */
7659};
7660
4b7e1803 7661static struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
7662 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7663 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
7664 { } /* end */
7665};
7666
7667
bdd148a3
KY
7668static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7669 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7670 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7671 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7672 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7673 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7674 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7675 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7676 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7677 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
7678 { } /* end */
7679};
7680
272a527c
KY
7681static struct snd_kcontrol_new alc882_targa_mixer[] = {
7682 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7683 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7684 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7685 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7686 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7687 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7688 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7689 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7690 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7691 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7692 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7693 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 7694 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
7695 { } /* end */
7696};
7697
7698/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7699 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7700 */
7701static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7702 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7703 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7704 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7705 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7706 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7707 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7708 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7709 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7710 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7711 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7712 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7713 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7714 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7715 { } /* end */
7716};
7717
914759b7
TI
7718static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7719 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7720 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7721 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7722 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7723 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7724 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7725 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7726 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7727 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7728 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
7729 { } /* end */
7730};
7731
df694daa
KY
7732static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7733 {
7734 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7735 .name = "Channel Mode",
7736 .info = alc_ch_mode_info,
7737 .get = alc_ch_mode_get,
7738 .put = alc_ch_mode_put,
7739 },
7740 { } /* end */
7741};
7742
4953550a 7743static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 7744 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
7745 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7746 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7747 /* Rear mixer */
05acb863
TI
7748 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7749 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7750 /* CLFE mixer */
05acb863
TI
7751 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7752 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7753 /* Side mixer */
05acb863
TI
7754 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7755 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7756
e9edcee0 7757 /* Front Pin: output 0 (0x0c) */
05acb863 7758 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7759 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7760 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 7761 /* Rear Pin: output 1 (0x0d) */
05acb863 7762 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7763 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7764 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 7765 /* CLFE Pin: output 2 (0x0e) */
05acb863 7766 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7767 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7768 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 7769 /* Side Pin: output 3 (0x0f) */
05acb863 7770 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7771 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7772 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 7773 /* Mic (rear) pin: input vref at 80% */
16ded525 7774 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7775 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7776 /* Front Mic pin: input vref at 80% */
16ded525 7777 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7778 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7779 /* Line In pin: input */
05acb863 7780 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
7781 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7782 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7783 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7784 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7785 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 7786 /* CD pin widget for input */
05acb863 7787 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
7788
7789 /* FIXME: use matrix-type input source selection */
7790 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 7791 /* Input mixer2 */
05acb863 7792 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 7793 /* Input mixer3 */
05acb863 7794 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
7795 /* ADC2: mute amp left and right */
7796 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7797 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
7798 /* ADC3: mute amp left and right */
7799 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7800 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
7801
7802 { }
7803};
7804
4953550a
TI
7805static struct hda_verb alc882_adc1_init_verbs[] = {
7806 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7807 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7808 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7809 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7810 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7811 /* ADC1: mute amp left and right */
7812 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7813 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7814 { }
7815};
7816
4b146cb0
TI
7817static struct hda_verb alc882_eapd_verbs[] = {
7818 /* change to EAPD mode */
7819 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 7820 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 7821 { }
4b146cb0
TI
7822};
7823
87a8c370
JK
7824static struct hda_verb alc889_eapd_verbs[] = {
7825 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7826 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7827 { }
7828};
7829
6732bd0d
WF
7830static struct hda_verb alc_hp15_unsol_verbs[] = {
7831 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7832 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7833 {}
7834};
87a8c370
JK
7835
7836static struct hda_verb alc885_init_verbs[] = {
7837 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
7838 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7839 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7840 /* Rear mixer */
88102f3f
KY
7841 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7842 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7843 /* CLFE mixer */
88102f3f
KY
7844 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7845 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7846 /* Side mixer */
88102f3f
KY
7847 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7848 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
7849
7850 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 7851 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
7852 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7853 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7854 /* Front Pin: output 0 (0x0c) */
7855 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7856 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7857 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7858 /* Rear Pin: output 1 (0x0d) */
7859 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7860 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7861 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
7862 /* CLFE Pin: output 2 (0x0e) */
7863 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7864 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7865 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7866 /* Side Pin: output 3 (0x0f) */
7867 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7868 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7869 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7870 /* Mic (rear) pin: input vref at 80% */
7871 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7872 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7873 /* Front Mic pin: input vref at 80% */
7874 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7875 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7876 /* Line In pin: input */
7877 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7878 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7879
7880 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7881 /* Input mixer1 */
88102f3f 7882 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
7883 /* Input mixer2 */
7884 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 7885 /* Input mixer3 */
88102f3f 7886 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
7887 /* ADC2: mute amp left and right */
7888 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7889 /* ADC3: mute amp left and right */
7890 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7891
7892 { }
7893};
7894
7895static struct hda_verb alc885_init_input_verbs[] = {
7896 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7897 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7898 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7899 { }
7900};
7901
7902
7903/* Unmute Selector 24h and set the default input to front mic */
7904static struct hda_verb alc889_init_input_verbs[] = {
7905 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7906 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7907 { }
7908};
7909
7910
4953550a
TI
7911#define alc883_init_verbs alc882_base_init_verbs
7912
9102cd1c
TD
7913/* Mac Pro test */
7914static struct snd_kcontrol_new alc882_macpro_mixer[] = {
7915 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7916 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7917 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
7918 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7919 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 7920 /* FIXME: this looks suspicious...
d355c82a
JK
7921 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
7922 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 7923 */
9102cd1c
TD
7924 { } /* end */
7925};
7926
7927static struct hda_verb alc882_macpro_init_verbs[] = {
7928 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7929 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7930 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7931 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7932 /* Front Pin: output 0 (0x0c) */
7933 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7934 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7935 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7936 /* Front Mic pin: input vref at 80% */
7937 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7938 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7939 /* Speaker: output */
7940 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7941 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7942 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
7943 /* Headphone output (output 0 - 0x0c) */
7944 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7945 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7946 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7947
7948 /* FIXME: use matrix-type input source selection */
7949 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7950 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7951 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7952 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7953 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7954 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7955 /* Input mixer2 */
7956 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7957 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7958 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7959 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7960 /* Input mixer3 */
7961 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7962 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7963 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7964 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7965 /* ADC1: mute amp left and right */
7966 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7967 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7968 /* ADC2: mute amp left and right */
7969 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7970 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7971 /* ADC3: mute amp left and right */
7972 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7973 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7974
7975 { }
7976};
f12ab1e0 7977
41d5545d
KS
7978/* Macbook 5,1 */
7979static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
7980 /* DACs */
7981 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7982 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7983 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7984 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 7985 /* Front mixer */
41d5545d
KS
7986 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7987 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7988 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
7989 /* Surround mixer */
7990 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7991 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7992 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7993 /* LFE mixer */
7994 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7995 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7996 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7997 /* HP mixer */
7998 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7999 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8000 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8001 /* Front Pin (0x0c) */
41d5545d
KS
8002 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8003 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8004 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8005 /* LFE Pin (0x0e) */
8006 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8007 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8008 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8009 /* HP Pin (0x0f) */
41d5545d
KS
8010 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8011 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8012 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8013 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8014 /* Front Mic pin: input vref at 80% */
8015 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8016 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8017 /* Line In pin */
8018 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8019 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8020
b8f171e7
AM
8021 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8022 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8023 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8024 { }
8025};
8026
e458b1fa
LY
8027/* Macmini 3,1 */
8028static struct hda_verb alc885_macmini3_init_verbs[] = {
8029 /* DACs */
8030 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8031 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8032 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8033 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8034 /* Front mixer */
8035 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8036 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8037 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8038 /* Surround mixer */
8039 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8040 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8041 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8042 /* LFE mixer */
8043 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8044 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8045 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8046 /* HP mixer */
8047 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8048 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8049 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8050 /* Front Pin (0x0c) */
8051 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8052 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8053 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8054 /* LFE Pin (0x0e) */
8055 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8056 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8057 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8058 /* HP Pin (0x0f) */
8059 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8060 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8061 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8062 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8063 /* Line In pin */
8064 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8065 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8066
8067 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8068 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8069 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8070 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8071 { }
8072};
8073
76e6f5a9
RH
8074
8075static struct hda_verb alc885_mba21_init_verbs[] = {
8076 /*Internal and HP Speaker Mixer*/
8077 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8078 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8079 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8080 /*Internal Speaker Pin (0x0c)*/
8081 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8082 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8083 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8084 /* HP Pin: output 0 (0x0e) */
8085 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8086 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8087 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8088 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8089 /* Line in (is hp when jack connected)*/
8090 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8091 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8092
8093 { }
8094 };
8095
8096
87350ad0
TI
8097/* Macbook Pro rev3 */
8098static struct hda_verb alc885_mbp3_init_verbs[] = {
8099 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8100 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8101 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8102 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8103 /* Rear mixer */
8104 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8105 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8106 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8107 /* HP mixer */
8108 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8109 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8110 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8111 /* Front Pin: output 0 (0x0c) */
8112 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8113 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8114 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8115 /* HP Pin: output 0 (0x0e) */
87350ad0 8116 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8117 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8118 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8119 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8120 /* Mic (rear) pin: input vref at 80% */
8121 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8122 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8123 /* Front Mic pin: input vref at 80% */
8124 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8125 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8126 /* Line In pin: use output 1 when in LineOut mode */
8127 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8128 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8129 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8130
8131 /* FIXME: use matrix-type input source selection */
8132 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8133 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8134 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8135 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8136 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8137 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8138 /* Input mixer2 */
8139 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8140 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8141 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8142 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8143 /* Input mixer3 */
8144 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8145 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8146 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8147 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8148 /* ADC1: mute amp left and right */
8149 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8150 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8151 /* ADC2: mute amp left and right */
8152 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8153 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8154 /* ADC3: mute amp left and right */
8155 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8156 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8157
8158 { }
8159};
8160
4b7e1803
JM
8161/* iMac 9,1 */
8162static struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8163 /* Internal Speaker Pin (0x0c) */
8164 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8165 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8166 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8167 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8168 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8169 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8170 /* HP Pin: Rear */
4b7e1803
JM
8171 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8172 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8173 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8174 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8175 /* Line in Rear */
8176 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8177 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8178 /* Front Mic pin: input vref at 80% */
8179 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8180 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8181 /* Rear mixer */
8182 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8183 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8184 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8185 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8186 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8187 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8188 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8189 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8190 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8191 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8192 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8193 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8194 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8195 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8196 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8197 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8198 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8199 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8200 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8201 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8202 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8203 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8204 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8205 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8206 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8207 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8208 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8209 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8210 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8211 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8212 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8213 { }
8214};
8215
c54728d8
NF
8216/* iMac 24 mixer. */
8217static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8218 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8219 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8220 { } /* end */
8221};
8222
8223/* iMac 24 init verbs. */
8224static struct hda_verb alc885_imac24_init_verbs[] = {
8225 /* Internal speakers: output 0 (0x0c) */
8226 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8227 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8228 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8229 /* Internal speakers: output 0 (0x0c) */
8230 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8231 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8232 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8233 /* Headphone: output 0 (0x0c) */
8234 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8235 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8236 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8237 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8238 /* Front Mic: input vref at 80% */
8239 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8240 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8241 { }
8242};
8243
8244/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8245static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8246{
a9fd4f3f 8247 struct alc_spec *spec = codec->spec;
c54728d8 8248
a9fd4f3f
TI
8249 spec->autocfg.hp_pins[0] = 0x14;
8250 spec->autocfg.speaker_pins[0] = 0x18;
8251 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8252}
8253
9d54f08b
TI
8254#define alc885_mb5_setup alc885_imac24_setup
8255#define alc885_macmini3_setup alc885_imac24_setup
8256
76e6f5a9
RH
8257/* Macbook Air 2,1 */
8258static void alc885_mba21_setup(struct hda_codec *codec)
8259{
8260 struct alc_spec *spec = codec->spec;
8261
8262 spec->autocfg.hp_pins[0] = 0x14;
8263 spec->autocfg.speaker_pins[0] = 0x18;
8264}
8265
8266
8267
4f5d1706 8268static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8269{
a9fd4f3f 8270 struct alc_spec *spec = codec->spec;
87350ad0 8271
a9fd4f3f
TI
8272 spec->autocfg.hp_pins[0] = 0x15;
8273 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8274}
8275
9d54f08b 8276static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8277{
9d54f08b 8278 struct alc_spec *spec = codec->spec;
4b7e1803 8279
9d54f08b 8280 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8281 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8282 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8283}
87350ad0 8284
272a527c
KY
8285static struct hda_verb alc882_targa_verbs[] = {
8286 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8287 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8288
8289 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8290 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8291
272a527c
KY
8292 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8293 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8294 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8295
8296 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8297 { } /* end */
8298};
8299
8300/* toggle speaker-output according to the hp-jack state */
8301static void alc882_targa_automute(struct hda_codec *codec)
8302{
a9fd4f3f
TI
8303 struct alc_spec *spec = codec->spec;
8304 alc_automute_amp(codec);
82beb8fd 8305 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8306 spec->jack_present ? 1 : 3);
8307}
8308
4f5d1706 8309static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8310{
8311 struct alc_spec *spec = codec->spec;
8312
8313 spec->autocfg.hp_pins[0] = 0x14;
8314 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8315}
8316
8317static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8318{
a9fd4f3f 8319 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8320 alc882_targa_automute(codec);
272a527c
KY
8321}
8322
8323static struct hda_verb alc882_asus_a7j_verbs[] = {
8324 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8325 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8326
8327 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8328 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8329 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8330
272a527c
KY
8331 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8332 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8333 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8334
8335 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8336 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8337 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8338 { } /* end */
8339};
8340
914759b7
TI
8341static struct hda_verb alc882_asus_a7m_verbs[] = {
8342 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8343 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8344
8345 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8346 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8347 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8348
914759b7
TI
8349 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8350 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8351 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8352
8353 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8354 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8355 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8356 { } /* end */
8357};
8358
9102cd1c
TD
8359static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8360{
8361 unsigned int gpiostate, gpiomask, gpiodir;
8362
8363 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8364 AC_VERB_GET_GPIO_DATA, 0);
8365
8366 if (!muted)
8367 gpiostate |= (1 << pin);
8368 else
8369 gpiostate &= ~(1 << pin);
8370
8371 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8372 AC_VERB_GET_GPIO_MASK, 0);
8373 gpiomask |= (1 << pin);
8374
8375 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8376 AC_VERB_GET_GPIO_DIRECTION, 0);
8377 gpiodir |= (1 << pin);
8378
8379
8380 snd_hda_codec_write(codec, codec->afg, 0,
8381 AC_VERB_SET_GPIO_MASK, gpiomask);
8382 snd_hda_codec_write(codec, codec->afg, 0,
8383 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8384
8385 msleep(1);
8386
8387 snd_hda_codec_write(codec, codec->afg, 0,
8388 AC_VERB_SET_GPIO_DATA, gpiostate);
8389}
8390
7debbe51
TI
8391/* set up GPIO at initialization */
8392static void alc885_macpro_init_hook(struct hda_codec *codec)
8393{
8394 alc882_gpio_mute(codec, 0, 0);
8395 alc882_gpio_mute(codec, 1, 0);
8396}
8397
8398/* set up GPIO and update auto-muting at initialization */
8399static void alc885_imac24_init_hook(struct hda_codec *codec)
8400{
8401 alc885_macpro_init_hook(codec);
4f5d1706 8402 alc_automute_amp(codec);
7debbe51
TI
8403}
8404
df694daa
KY
8405/*
8406 * generic initialization of ADC, input mixers and output mixers
8407 */
4953550a 8408static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8409 /*
8410 * Unmute ADC0-2 and set the default input to mic-in
8411 */
4953550a
TI
8412 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8413 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8414 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8415 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8416
4953550a
TI
8417 /*
8418 * Set up output mixers (0x0c - 0x0f)
8419 */
8420 /* set vol=0 to output mixers */
8421 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8422 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8423 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8424 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8425 /* set up input amps for analog loopback */
8426 /* Amp Indices: DAC = 0, mixer = 1 */
8427 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8428 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8429 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8430 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8431 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8432 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8433 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8434 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8435 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8436 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8437
4953550a
TI
8438 /* FIXME: use matrix-type input source selection */
8439 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8440 /* Input mixer2 */
88102f3f 8441 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8442 /* Input mixer3 */
88102f3f 8443 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8444 { }
9c7f852e
TI
8445};
8446
eb4c41d3
TS
8447/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8448static struct hda_verb alc889A_mb31_ch2_init[] = {
8449 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8450 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8451 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8452 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8453 { } /* end */
8454};
8455
8456/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8457static struct hda_verb alc889A_mb31_ch4_init[] = {
8458 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8459 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8460 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8461 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8462 { } /* end */
8463};
8464
8465/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8466static struct hda_verb alc889A_mb31_ch5_init[] = {
8467 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8468 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8469 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8470 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8471 { } /* end */
8472};
8473
8474/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8475static struct hda_verb alc889A_mb31_ch6_init[] = {
8476 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8477 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8478 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8479 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8480 { } /* end */
8481};
8482
8483static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8484 { 2, alc889A_mb31_ch2_init },
8485 { 4, alc889A_mb31_ch4_init },
8486 { 5, alc889A_mb31_ch5_init },
8487 { 6, alc889A_mb31_ch6_init },
8488};
8489
b373bdeb
AN
8490static struct hda_verb alc883_medion_eapd_verbs[] = {
8491 /* eanable EAPD on medion laptop */
8492 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8493 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8494 { }
8495};
8496
4953550a 8497#define alc883_base_mixer alc882_base_mixer
834be88d 8498
a8848bd6
AS
8499static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8500 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8501 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8502 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8503 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8504 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8505 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8506 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8507 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8508 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8509 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8510 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8511 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8512 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8513 { } /* end */
8514};
8515
0c4cc443 8516static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8517 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8518 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8519 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8520 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8521 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8522 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8523 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8524 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8525 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8526 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8527 { } /* end */
8528};
8529
fb97dc67
J
8530static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8531 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8532 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8533 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8534 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8535 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8536 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8537 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8538 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8539 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8540 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8541 { } /* end */
8542};
8543
9c7f852e
TI
8544static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8545 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8546 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8547 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8548 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8549 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8550 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8551 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8552 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8553 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8554 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8555 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8556 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8557 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8558 { } /* end */
8559};
df694daa 8560
9c7f852e
TI
8561static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8562 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8563 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8564 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8565 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8566 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8567 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8568 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8569 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8570 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8571 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8572 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8573 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8574 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8575 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8576 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8577 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8578 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8579 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8580 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8581 { } /* end */
8582};
8583
17bba1b7
J
8584static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8585 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8586 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8587 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8588 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8589 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8590 HDA_OUTPUT),
8591 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8592 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8593 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8594 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8595 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8596 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8597 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8598 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8599 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8600 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8601 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8602 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8603 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8604 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8605 { } /* end */
8606};
8607
87a8c370
JK
8608static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8609 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8610 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8611 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8612 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8613 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8614 HDA_OUTPUT),
8615 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8616 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8617 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8618 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8619 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8620 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8621 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8622 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8623 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8624 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
8625 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8626 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8627 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8628 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8629 { } /* end */
8630};
8631
d1d985f0 8632static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8633 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8634 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8635 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8636 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8637 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8638 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8639 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8640 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8641 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8642 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8643 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8644 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8645 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8646 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8647 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
8648 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8649 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8650 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8 8651 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
8652 { } /* end */
8653};
8654
c259249f 8655static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 8656 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8657 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8658 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8659 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8660 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8661 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8662 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8663 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8664 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8665 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8666 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8667 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8668 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8669 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8670 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8671 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8672 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 8673 { } /* end */
f12ab1e0 8674};
ccc656ce 8675
c259249f 8676static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 8677 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8678 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8679 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8680 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8681 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8682 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8683 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8684 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8685 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
8686 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8687 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8688 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 8689 { } /* end */
f12ab1e0 8690};
ccc656ce 8691
b99dba34
TI
8692static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8693 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8694 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8695 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8696 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8697 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8698 { } /* end */
8699};
8700
bc9f98a9
KY
8701static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8702 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8703 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
8704 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8705 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
8706 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8708 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8709 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 8710 { } /* end */
f12ab1e0 8711};
bc9f98a9 8712
272a527c
KY
8713static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8714 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8715 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8716 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8717 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8718 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8719 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8720 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
150b432f
DH
8721 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8722 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
8723 { } /* end */
8724};
8725
8726static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8727 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8728 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8729 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8730 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8731 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8732 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8733 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8734 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8735 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
272a527c 8736 { } /* end */
ea1fb29a 8737};
272a527c 8738
7ad7b218
MC
8739static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
8740 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8741 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8742 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8743 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
8744 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
8745 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
8746 { } /* end */
8747};
8748
8749static struct hda_verb alc883_medion_wim2160_verbs[] = {
8750 /* Unmute front mixer */
8751 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8752 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8753
8754 /* Set speaker pin to front mixer */
8755 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8756
8757 /* Init headphone pin */
8758 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8759 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8760 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8761 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8762
8763 { } /* end */
8764};
8765
8766/* toggle speaker-output according to the hp-jack state */
8767static void alc883_medion_wim2160_setup(struct hda_codec *codec)
8768{
8769 struct alc_spec *spec = codec->spec;
8770
8771 spec->autocfg.hp_pins[0] = 0x1a;
8772 spec->autocfg.speaker_pins[0] = 0x15;
8773}
8774
2880a867 8775static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
8776 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8777 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 8778 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
8779 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8780 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
8781 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8782 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8783 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 8784 { } /* end */
d1a991a6 8785};
2880a867 8786
d2fd4b09
TV
8787static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8788 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 8789 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
8790 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8791 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
8792 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8793 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8794 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8795 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8796 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8797 { } /* end */
8798};
8799
e2757d5e
KY
8800static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8801 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8802 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8803 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8804 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8805 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8806 0x0d, 1, 0x0, HDA_OUTPUT),
8807 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8808 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8809 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8810 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8811 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
8812 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8813 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8814 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8815 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8816 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8817 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8818 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8819 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8820 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8821 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
8822 { } /* end */
8823};
8824
eb4c41d3
TS
8825static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8826 /* Output mixers */
8827 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8828 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8829 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8830 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8831 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8832 HDA_OUTPUT),
8833 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8834 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8835 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8836 /* Output switches */
8837 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8838 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8839 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8840 /* Boost mixers */
8841 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8842 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8843 /* Input mixers */
8844 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8845 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8846 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8847 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8848 { } /* end */
8849};
8850
3e1647c5
GG
8851static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8852 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8853 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8854 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8855 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8856 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8857 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8858 { } /* end */
8859};
8860
e2757d5e
KY
8861static struct hda_bind_ctls alc883_bind_cap_vol = {
8862 .ops = &snd_hda_bind_vol,
8863 .values = {
8864 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8865 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8866 0
8867 },
8868};
8869
8870static struct hda_bind_ctls alc883_bind_cap_switch = {
8871 .ops = &snd_hda_bind_sw,
8872 .values = {
8873 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8874 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8875 0
8876 },
8877};
8878
8879static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8880 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8881 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8882 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8883 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8884 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8885 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4953550a
TI
8886 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8887 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8888 { } /* end */
8889};
df694daa 8890
4953550a
TI
8891static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8892 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8893 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8894 {
8895 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8896 /* .name = "Capture Source", */
8897 .name = "Input Source",
8898 .count = 1,
8899 .info = alc_mux_enum_info,
8900 .get = alc_mux_enum_get,
8901 .put = alc_mux_enum_put,
8902 },
8903 { } /* end */
8904};
9c7f852e 8905
4953550a
TI
8906static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8907 {
8908 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8909 .name = "Channel Mode",
8910 .info = alc_ch_mode_info,
8911 .get = alc_ch_mode_get,
8912 .put = alc_ch_mode_put,
8913 },
8914 { } /* end */
9c7f852e
TI
8915};
8916
a8848bd6 8917/* toggle speaker-output according to the hp-jack state */
4f5d1706 8918static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 8919{
a9fd4f3f 8920 struct alc_spec *spec = codec->spec;
a8848bd6 8921
a9fd4f3f
TI
8922 spec->autocfg.hp_pins[0] = 0x15;
8923 spec->autocfg.speaker_pins[0] = 0x14;
8924 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
8925}
8926
8927/* auto-toggle front mic */
8928/*
8929static void alc883_mitac_mic_automute(struct hda_codec *codec)
8930{
864f92be 8931 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
a8848bd6 8932
a8848bd6
AS
8933 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8934}
8935*/
8936
a8848bd6
AS
8937static struct hda_verb alc883_mitac_verbs[] = {
8938 /* HP */
8939 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8940 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8941 /* Subwoofer */
8942 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8943 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8944
8945 /* enable unsolicited event */
8946 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8947 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8948
8949 { } /* end */
8950};
8951
a65cc60f 8952static struct hda_verb alc883_clevo_m540r_verbs[] = {
8953 /* HP */
8954 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8955 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8956 /* Int speaker */
8957 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
8958
8959 /* enable unsolicited event */
8960 /*
8961 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8962 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8963 */
8964
8965 { } /* end */
8966};
8967
0c4cc443 8968static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
8969 /* HP */
8970 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8971 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8972 /* Int speaker */
8973 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8974 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8975
8976 /* enable unsolicited event */
8977 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 8978 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
8979
8980 { } /* end */
8981};
8982
fb97dc67
J
8983static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8984 /* HP */
8985 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8986 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8987 /* Subwoofer */
8988 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8989 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8990
8991 /* enable unsolicited event */
8992 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8993
8994 { } /* end */
8995};
8996
c259249f 8997static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
8998 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8999 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9000
9001 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9002 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9003
64a8be74
DH
9004/* Connect Line-Out side jack (SPDIF) to Side */
9005 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9006 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9007 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9008/* Connect Mic jack to CLFE */
9009 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9010 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9011 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9012/* Connect Line-in jack to Surround */
9013 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9014 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9015 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9016/* Connect HP out jack to Front */
9017 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9018 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9019 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9020
9021 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9022
9023 { } /* end */
9024};
9025
bc9f98a9
KY
9026static struct hda_verb alc883_lenovo_101e_verbs[] = {
9027 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9028 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9029 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9030 { } /* end */
9031};
9032
272a527c
KY
9033static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9034 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9035 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9036 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9037 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9038 { } /* end */
9039};
9040
9041static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9042 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9043 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9044 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9045 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9046 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9047 { } /* end */
9048};
9049
189609ae
KY
9050static struct hda_verb alc883_haier_w66_verbs[] = {
9051 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9052 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9053
9054 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9055
9056 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9057 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9058 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9059 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9060 { } /* end */
9061};
9062
e2757d5e
KY
9063static struct hda_verb alc888_lenovo_sky_verbs[] = {
9064 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9065 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9066 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9067 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9068 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9069 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9070 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9071 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9072 { } /* end */
9073};
9074
8718b700
HRK
9075static struct hda_verb alc888_6st_dell_verbs[] = {
9076 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9077 { }
9078};
9079
3e1647c5
GG
9080static struct hda_verb alc883_vaiott_verbs[] = {
9081 /* HP */
9082 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9083 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9084
9085 /* enable unsolicited event */
9086 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9087
9088 { } /* end */
9089};
9090
4f5d1706 9091static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9092{
a9fd4f3f 9093 struct alc_spec *spec = codec->spec;
8718b700 9094
a9fd4f3f
TI
9095 spec->autocfg.hp_pins[0] = 0x1b;
9096 spec->autocfg.speaker_pins[0] = 0x14;
9097 spec->autocfg.speaker_pins[1] = 0x16;
9098 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
9099}
9100
4723c022 9101static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9102 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9103 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9104 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9105 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9106 { } /* end */
5795b9e6
CM
9107};
9108
3ea0d7cf
HRK
9109/*
9110 * 2ch mode
9111 */
4723c022 9112static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9113 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9114 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9115 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9116 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9117 { } /* end */
8341de60
CM
9118};
9119
3ea0d7cf
HRK
9120/*
9121 * 4ch mode
9122 */
9123static struct hda_verb alc888_3st_hp_4ch_init[] = {
9124 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9125 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9126 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9127 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9128 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9129 { } /* end */
9130};
9131
9132/*
9133 * 6ch mode
9134 */
4723c022 9135static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9136 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9137 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9138 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9139 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9140 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9141 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9142 { } /* end */
8341de60
CM
9143};
9144
3ea0d7cf 9145static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9146 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9147 { 4, alc888_3st_hp_4ch_init },
4723c022 9148 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9149};
9150
272a527c
KY
9151/* toggle front-jack and RCA according to the hp-jack state */
9152static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9153{
864f92be 9154 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 9155
47fd830a
TI
9156 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9157 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9158 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9159 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
9160}
9161
9162/* toggle RCA according to the front-jack state */
9163static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9164{
864f92be 9165 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 9166
47fd830a
TI
9167 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9168 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 9169}
47fd830a 9170
272a527c
KY
9171static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9172 unsigned int res)
9173{
9174 if ((res >> 26) == ALC880_HP_EVENT)
9175 alc888_lenovo_ms7195_front_automute(codec);
9176 if ((res >> 26) == ALC880_FRONT_EVENT)
9177 alc888_lenovo_ms7195_rca_automute(codec);
9178}
9179
9180static struct hda_verb alc883_medion_md2_verbs[] = {
9181 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9182 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9183
9184 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9185
9186 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9187 { } /* end */
9188};
9189
9190/* toggle speaker-output according to the hp-jack state */
4f5d1706 9191static void alc883_medion_md2_setup(struct hda_codec *codec)
272a527c 9192{
a9fd4f3f 9193 struct alc_spec *spec = codec->spec;
272a527c 9194
a9fd4f3f
TI
9195 spec->autocfg.hp_pins[0] = 0x14;
9196 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
9197}
9198
ccc656ce 9199/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9200#define alc883_targa_init_hook alc882_targa_init_hook
9201#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9202
0c4cc443
HRK
9203static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
9204{
9205 unsigned int present;
9206
d56757ab 9207 present = snd_hda_jack_detect(codec, 0x18);
0c4cc443
HRK
9208 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
9209 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9210}
9211
4f5d1706 9212static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9213{
a9fd4f3f
TI
9214 struct alc_spec *spec = codec->spec;
9215
9216 spec->autocfg.hp_pins[0] = 0x15;
9217 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
9218}
9219
9220static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9221{
a9fd4f3f 9222 alc_automute_amp(codec);
0c4cc443
HRK
9223 alc883_clevo_m720_mic_automute(codec);
9224}
9225
9226static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9227 unsigned int res)
9228{
0c4cc443 9229 switch (res >> 26) {
0c4cc443
HRK
9230 case ALC880_MIC_EVENT:
9231 alc883_clevo_m720_mic_automute(codec);
9232 break;
a9fd4f3f
TI
9233 default:
9234 alc_automute_amp_unsol_event(codec, res);
9235 break;
0c4cc443 9236 }
368c7a95
J
9237}
9238
fb97dc67 9239/* toggle speaker-output according to the hp-jack state */
4f5d1706 9240static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9241{
a9fd4f3f 9242 struct alc_spec *spec = codec->spec;
fb97dc67 9243
a9fd4f3f
TI
9244 spec->autocfg.hp_pins[0] = 0x14;
9245 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9246}
9247
4f5d1706 9248static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9249{
a9fd4f3f 9250 struct alc_spec *spec = codec->spec;
189609ae 9251
a9fd4f3f
TI
9252 spec->autocfg.hp_pins[0] = 0x1b;
9253 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9254}
9255
bc9f98a9
KY
9256static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9257{
864f92be 9258 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9259
47fd830a
TI
9260 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9261 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9262}
9263
9264static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9265{
864f92be 9266 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9267
47fd830a
TI
9268 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9269 HDA_AMP_MUTE, bits);
9270 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9271 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9272}
9273
9274static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9275 unsigned int res)
9276{
9277 if ((res >> 26) == ALC880_HP_EVENT)
9278 alc883_lenovo_101e_all_automute(codec);
9279 if ((res >> 26) == ALC880_FRONT_EVENT)
9280 alc883_lenovo_101e_ispeaker_automute(codec);
9281}
9282
676a9b53 9283/* toggle speaker-output according to the hp-jack state */
4f5d1706 9284static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9285{
a9fd4f3f 9286 struct alc_spec *spec = codec->spec;
676a9b53 9287
a9fd4f3f
TI
9288 spec->autocfg.hp_pins[0] = 0x14;
9289 spec->autocfg.speaker_pins[0] = 0x15;
9290 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9291}
9292
d1a991a6
KY
9293static struct hda_verb alc883_acer_eapd_verbs[] = {
9294 /* HP Pin: output 0 (0x0c) */
9295 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9296 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9297 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9298 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9299 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9300 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9301 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9302 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9303 /* eanable EAPD on medion laptop */
9304 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9305 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9306 /* enable unsolicited event */
9307 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9308 { }
9309};
9310
fc86f954
DK
9311static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
9312 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9313 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9314 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9315 { } /* end */
9316};
9317
4f5d1706 9318static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9319{
a9fd4f3f 9320 struct alc_spec *spec = codec->spec;
5795b9e6 9321
a9fd4f3f
TI
9322 spec->autocfg.hp_pins[0] = 0x1b;
9323 spec->autocfg.speaker_pins[0] = 0x14;
9324 spec->autocfg.speaker_pins[1] = 0x15;
9325 spec->autocfg.speaker_pins[2] = 0x16;
9326 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9327}
9328
4f5d1706 9329static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9330{
a9fd4f3f 9331 struct alc_spec *spec = codec->spec;
e2757d5e 9332
a9fd4f3f
TI
9333 spec->autocfg.hp_pins[0] = 0x1b;
9334 spec->autocfg.speaker_pins[0] = 0x14;
9335 spec->autocfg.speaker_pins[1] = 0x15;
9336 spec->autocfg.speaker_pins[2] = 0x16;
9337 spec->autocfg.speaker_pins[3] = 0x17;
9338 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9339}
9340
4f5d1706 9341static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9342{
9343 struct alc_spec *spec = codec->spec;
9344
9345 spec->autocfg.hp_pins[0] = 0x15;
9346 spec->autocfg.speaker_pins[0] = 0x14;
9347 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9348}
9349
e2757d5e
KY
9350static struct hda_verb alc888_asus_m90v_verbs[] = {
9351 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9352 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9353 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9354 /* enable unsolicited event */
9355 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9356 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9357 { } /* end */
9358};
9359
4f5d1706 9360static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9361{
a9fd4f3f 9362 struct alc_spec *spec = codec->spec;
e2757d5e 9363
a9fd4f3f
TI
9364 spec->autocfg.hp_pins[0] = 0x1b;
9365 spec->autocfg.speaker_pins[0] = 0x14;
9366 spec->autocfg.speaker_pins[1] = 0x15;
9367 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9368 spec->ext_mic.pin = 0x18;
9369 spec->int_mic.pin = 0x19;
9370 spec->ext_mic.mux_idx = 0;
9371 spec->int_mic.mux_idx = 1;
9372 spec->auto_mic = 1;
e2757d5e
KY
9373}
9374
9375static struct hda_verb alc888_asus_eee1601_verbs[] = {
9376 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9377 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9378 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9379 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9380 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9381 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9382 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9383 /* enable unsolicited event */
9384 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9385 { } /* end */
9386};
9387
e2757d5e
KY
9388static void alc883_eee1601_inithook(struct hda_codec *codec)
9389{
a9fd4f3f
TI
9390 struct alc_spec *spec = codec->spec;
9391
9392 spec->autocfg.hp_pins[0] = 0x14;
9393 spec->autocfg.speaker_pins[0] = 0x1b;
9394 alc_automute_pin(codec);
e2757d5e
KY
9395}
9396
eb4c41d3
TS
9397static struct hda_verb alc889A_mb31_verbs[] = {
9398 /* Init rear pin (used as headphone output) */
9399 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9400 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9401 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9402 /* Init line pin (used as output in 4ch and 6ch mode) */
9403 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9404 /* Init line 2 pin (used as headphone out by default) */
9405 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9406 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9407 { } /* end */
9408};
9409
9410/* Mute speakers according to the headphone jack state */
9411static void alc889A_mb31_automute(struct hda_codec *codec)
9412{
9413 unsigned int present;
9414
9415 /* Mute only in 2ch or 4ch mode */
9416 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9417 == 0x00) {
864f92be 9418 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9419 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9420 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9421 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9422 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9423 }
9424}
9425
9426static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9427{
9428 if ((res >> 26) == ALC880_HP_EVENT)
9429 alc889A_mb31_automute(codec);
9430}
9431
4953550a 9432
cb53c626 9433#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9434#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9435#endif
9436
def319f9 9437/* pcm configuration: identical with ALC880 */
4953550a
TI
9438#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9439#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9440#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9441#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9442
9443static hda_nid_t alc883_slave_dig_outs[] = {
9444 ALC1200_DIGOUT_NID, 0,
9445};
9446
9447static hda_nid_t alc1200_slave_dig_outs[] = {
9448 ALC883_DIGOUT_NID, 0,
9449};
9c7f852e
TI
9450
9451/*
9452 * configuration and preset
9453 */
4953550a
TI
9454static const char *alc882_models[ALC882_MODEL_LAST] = {
9455 [ALC882_3ST_DIG] = "3stack-dig",
9456 [ALC882_6ST_DIG] = "6stack-dig",
9457 [ALC882_ARIMA] = "arima",
9458 [ALC882_W2JC] = "w2jc",
9459 [ALC882_TARGA] = "targa",
9460 [ALC882_ASUS_A7J] = "asus-a7j",
9461 [ALC882_ASUS_A7M] = "asus-a7m",
9462 [ALC885_MACPRO] = "macpro",
9463 [ALC885_MB5] = "mb5",
e458b1fa 9464 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9465 [ALC885_MBA21] = "mba21",
4953550a
TI
9466 [ALC885_MBP3] = "mbp3",
9467 [ALC885_IMAC24] = "imac24",
4b7e1803 9468 [ALC885_IMAC91] = "imac91",
4953550a 9469 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9470 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9471 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9472 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9473 [ALC883_TARGA_DIG] = "targa-dig",
9474 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9475 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9476 [ALC883_ACER] = "acer",
2880a867 9477 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9478 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9479 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9480 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9481 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9482 [ALC883_MEDION] = "medion",
272a527c 9483 [ALC883_MEDION_MD2] = "medion-md2",
7ad7b218 9484 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9485 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9486 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9487 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9488 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9489 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9490 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9491 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9492 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9493 [ALC883_MITAC] = "mitac",
a65cc60f 9494 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9495 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9496 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9497 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9498 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9499 [ALC889A_INTEL] = "intel-alc889a",
9500 [ALC889_INTEL] = "intel-x58",
3ab90935 9501 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9502 [ALC889A_MB31] = "mb31",
3e1647c5 9503 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9504 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9505};
9506
4953550a
TI
9507static struct snd_pci_quirk alc882_cfg_tbl[] = {
9508 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9509
ac3e3741 9510 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9511 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9512 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9513 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9514 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9515 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9516 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9517 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9518 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9519 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9520 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9521 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9522 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9523 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9524 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9525 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9526 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9527 ALC888_ACER_ASPIRE_6530G),
cc374c47 9528 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9529 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9530 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9531 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9532 /* default Acer -- disabled as it causes more problems.
9533 * model=auto should work fine now
9534 */
9535 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9536
5795b9e6 9537 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9538
febe3375 9539 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9540 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9541 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9542 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9543 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9544 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9545
9546 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9547 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9548 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9549 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9550 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9551 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9552 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9553 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9554 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9555 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9556 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9557
9558 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9559 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9560 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9561 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9562 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9563 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9564 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9565 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9566 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9567
6f3bf657 9568 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9569 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9570 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9571 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9572 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9573 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9574 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9575 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9576 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9577 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9578 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9579 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9580 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9581 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9582 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9583 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9584 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9585 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9586 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9587 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9588 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9589 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9590 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9591 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9592 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9593 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9594 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9595 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9596 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9597 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9598 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9599
ac3e3741 9600 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9601 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9602 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9603 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9604 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9605 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9606 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9607 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9608 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9609 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9610 ALC883_FUJITSU_PI2515),
bfb53037 9611 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9612 ALC888_FUJITSU_XA3530),
272a527c 9613 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9614 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9615 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9616 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9617 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
272a527c 9618 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
959973b9 9619 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9620 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9621 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9622
17bba1b7
J
9623 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9624 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9625 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9626 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9627 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9628 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9629 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9630
4953550a 9631 {}
f3cd3f5d
WF
9632};
9633
4953550a
TI
9634/* codec SSID table for Intel Mac */
9635static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9636 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9637 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9638 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9639 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9640 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9641 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9642 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 9643 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 9644 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 9645 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 9646 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
9647 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9648 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9649 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9650 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9651 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 9652 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
9653 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9654 * so apparently no perfect solution yet
4953550a
TI
9655 */
9656 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9657 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9658 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9659 {} /* terminator */
b25c9da1
WF
9660};
9661
4953550a
TI
9662static struct alc_config_preset alc882_presets[] = {
9663 [ALC882_3ST_DIG] = {
9664 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9665 .init_verbs = { alc882_base_init_verbs,
9666 alc882_adc1_init_verbs },
4953550a
TI
9667 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9668 .dac_nids = alc882_dac_nids,
9669 .dig_out_nid = ALC882_DIGOUT_NID,
9670 .dig_in_nid = ALC882_DIGIN_NID,
9671 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9672 .channel_mode = alc882_ch_modes,
9673 .need_dac_fix = 1,
9674 .input_mux = &alc882_capture_source,
9675 },
9676 [ALC882_6ST_DIG] = {
9677 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9678 .init_verbs = { alc882_base_init_verbs,
9679 alc882_adc1_init_verbs },
4953550a
TI
9680 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9681 .dac_nids = alc882_dac_nids,
9682 .dig_out_nid = ALC882_DIGOUT_NID,
9683 .dig_in_nid = ALC882_DIGIN_NID,
9684 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9685 .channel_mode = alc882_sixstack_modes,
9686 .input_mux = &alc882_capture_source,
9687 },
9688 [ALC882_ARIMA] = {
9689 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9690 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9691 alc882_eapd_verbs },
4953550a
TI
9692 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9693 .dac_nids = alc882_dac_nids,
9694 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9695 .channel_mode = alc882_sixstack_modes,
9696 .input_mux = &alc882_capture_source,
9697 },
9698 [ALC882_W2JC] = {
9699 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9700 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9701 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
9702 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9703 .dac_nids = alc882_dac_nids,
9704 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9705 .channel_mode = alc880_threestack_modes,
9706 .need_dac_fix = 1,
9707 .input_mux = &alc882_capture_source,
9708 .dig_out_nid = ALC882_DIGOUT_NID,
9709 },
76e6f5a9
RH
9710 [ALC885_MBA21] = {
9711 .mixers = { alc885_mba21_mixer },
9712 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9713 .num_dacs = 2,
9714 .dac_nids = alc882_dac_nids,
9715 .channel_mode = alc885_mba21_ch_modes,
9716 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9717 .input_mux = &alc882_capture_source,
9718 .unsol_event = alc_automute_amp_unsol_event,
9719 .setup = alc885_mba21_setup,
9720 .init_hook = alc_automute_amp,
9721 },
4953550a
TI
9722 [ALC885_MBP3] = {
9723 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9724 .init_verbs = { alc885_mbp3_init_verbs,
9725 alc880_gpio1_init_verbs },
be0ae923 9726 .num_dacs = 2,
4953550a 9727 .dac_nids = alc882_dac_nids,
be0ae923
TI
9728 .hp_nid = 0x04,
9729 .channel_mode = alc885_mbp_4ch_modes,
9730 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
9731 .input_mux = &alc882_capture_source,
9732 .dig_out_nid = ALC882_DIGOUT_NID,
9733 .dig_in_nid = ALC882_DIGIN_NID,
9734 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9735 .setup = alc885_mbp3_setup,
9736 .init_hook = alc_automute_amp,
4953550a
TI
9737 },
9738 [ALC885_MB5] = {
9739 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
9740 .init_verbs = { alc885_mb5_init_verbs,
9741 alc880_gpio1_init_verbs },
9742 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9743 .dac_nids = alc882_dac_nids,
9744 .channel_mode = alc885_mb5_6ch_modes,
9745 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
9746 .input_mux = &mb5_capture_source,
9747 .dig_out_nid = ALC882_DIGOUT_NID,
9748 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9749 .unsol_event = alc_automute_amp_unsol_event,
9750 .setup = alc885_mb5_setup,
9751 .init_hook = alc_automute_amp,
4953550a 9752 },
e458b1fa
LY
9753 [ALC885_MACMINI3] = {
9754 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9755 .init_verbs = { alc885_macmini3_init_verbs,
9756 alc880_gpio1_init_verbs },
9757 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9758 .dac_nids = alc882_dac_nids,
9759 .channel_mode = alc885_macmini3_6ch_modes,
9760 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9761 .input_mux = &macmini3_capture_source,
9762 .dig_out_nid = ALC882_DIGOUT_NID,
9763 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9764 .unsol_event = alc_automute_amp_unsol_event,
9765 .setup = alc885_macmini3_setup,
9766 .init_hook = alc_automute_amp,
e458b1fa 9767 },
4953550a
TI
9768 [ALC885_MACPRO] = {
9769 .mixers = { alc882_macpro_mixer },
9770 .init_verbs = { alc882_macpro_init_verbs },
9771 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9772 .dac_nids = alc882_dac_nids,
9773 .dig_out_nid = ALC882_DIGOUT_NID,
9774 .dig_in_nid = ALC882_DIGIN_NID,
9775 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9776 .channel_mode = alc882_ch_modes,
9777 .input_mux = &alc882_capture_source,
9778 .init_hook = alc885_macpro_init_hook,
9779 },
9780 [ALC885_IMAC24] = {
9781 .mixers = { alc885_imac24_mixer },
9782 .init_verbs = { alc885_imac24_init_verbs },
9783 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9784 .dac_nids = alc882_dac_nids,
9785 .dig_out_nid = ALC882_DIGOUT_NID,
9786 .dig_in_nid = ALC882_DIGIN_NID,
9787 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9788 .channel_mode = alc882_ch_modes,
9789 .input_mux = &alc882_capture_source,
9790 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 9791 .setup = alc885_imac24_setup,
4953550a
TI
9792 .init_hook = alc885_imac24_init_hook,
9793 },
4b7e1803 9794 [ALC885_IMAC91] = {
b7cccc52 9795 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
9796 .init_verbs = { alc885_imac91_init_verbs,
9797 alc880_gpio1_init_verbs },
9798 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9799 .dac_nids = alc882_dac_nids,
b7cccc52
JM
9800 .channel_mode = alc885_mba21_ch_modes,
9801 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9802 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
9803 .dig_out_nid = ALC882_DIGOUT_NID,
9804 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9805 .unsol_event = alc_automute_amp_unsol_event,
9806 .setup = alc885_imac91_setup,
9807 .init_hook = alc_automute_amp,
4b7e1803 9808 },
4953550a
TI
9809 [ALC882_TARGA] = {
9810 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 9811 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 9812 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
9813 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9814 .dac_nids = alc882_dac_nids,
9815 .dig_out_nid = ALC882_DIGOUT_NID,
9816 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9817 .adc_nids = alc882_adc_nids,
9818 .capsrc_nids = alc882_capsrc_nids,
9819 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9820 .channel_mode = alc882_3ST_6ch_modes,
9821 .need_dac_fix = 1,
9822 .input_mux = &alc882_capture_source,
9823 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
9824 .setup = alc882_targa_setup,
9825 .init_hook = alc882_targa_automute,
4953550a
TI
9826 },
9827 [ALC882_ASUS_A7J] = {
9828 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9829 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9830 alc882_asus_a7j_verbs},
4953550a
TI
9831 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9832 .dac_nids = alc882_dac_nids,
9833 .dig_out_nid = ALC882_DIGOUT_NID,
9834 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9835 .adc_nids = alc882_adc_nids,
9836 .capsrc_nids = alc882_capsrc_nids,
9837 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9838 .channel_mode = alc882_3ST_6ch_modes,
9839 .need_dac_fix = 1,
9840 .input_mux = &alc882_capture_source,
9841 },
9842 [ALC882_ASUS_A7M] = {
9843 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9844 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9845 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
9846 alc882_asus_a7m_verbs },
9847 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9848 .dac_nids = alc882_dac_nids,
9849 .dig_out_nid = ALC882_DIGOUT_NID,
9850 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9851 .channel_mode = alc880_threestack_modes,
9852 .need_dac_fix = 1,
9853 .input_mux = &alc882_capture_source,
9854 },
9c7f852e
TI
9855 [ALC883_3ST_2ch_DIG] = {
9856 .mixers = { alc883_3ST_2ch_mixer },
9857 .init_verbs = { alc883_init_verbs },
9858 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9859 .dac_nids = alc883_dac_nids,
9860 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9861 .dig_in_nid = ALC883_DIGIN_NID,
9862 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9863 .channel_mode = alc883_3ST_2ch_modes,
9864 .input_mux = &alc883_capture_source,
9865 },
9866 [ALC883_3ST_6ch_DIG] = {
9867 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9868 .init_verbs = { alc883_init_verbs },
9869 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9870 .dac_nids = alc883_dac_nids,
9871 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9872 .dig_in_nid = ALC883_DIGIN_NID,
9873 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9874 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9875 .need_dac_fix = 1,
9c7f852e 9876 .input_mux = &alc883_capture_source,
f12ab1e0 9877 },
9c7f852e
TI
9878 [ALC883_3ST_6ch] = {
9879 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9880 .init_verbs = { alc883_init_verbs },
9881 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9882 .dac_nids = alc883_dac_nids,
9c7f852e
TI
9883 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9884 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9885 .need_dac_fix = 1,
9c7f852e 9886 .input_mux = &alc883_capture_source,
f12ab1e0 9887 },
17bba1b7
J
9888 [ALC883_3ST_6ch_INTEL] = {
9889 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
9890 .init_verbs = { alc883_init_verbs },
9891 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9892 .dac_nids = alc883_dac_nids,
9893 .dig_out_nid = ALC883_DIGOUT_NID,
9894 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 9895 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
9896 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
9897 .channel_mode = alc883_3ST_6ch_intel_modes,
9898 .need_dac_fix = 1,
9899 .input_mux = &alc883_3stack_6ch_intel,
9900 },
87a8c370
JK
9901 [ALC889A_INTEL] = {
9902 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
9903 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
9904 alc_hp15_unsol_verbs },
87a8c370
JK
9905 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9906 .dac_nids = alc883_dac_nids,
9907 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9908 .adc_nids = alc889_adc_nids,
9909 .dig_out_nid = ALC883_DIGOUT_NID,
9910 .dig_in_nid = ALC883_DIGIN_NID,
9911 .slave_dig_outs = alc883_slave_dig_outs,
9912 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9913 .channel_mode = alc889_8ch_intel_modes,
9914 .capsrc_nids = alc889_capsrc_nids,
9915 .input_mux = &alc889_capture_source,
4f5d1706
TI
9916 .setup = alc889_automute_setup,
9917 .init_hook = alc_automute_amp,
6732bd0d 9918 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
9919 .need_dac_fix = 1,
9920 },
9921 [ALC889_INTEL] = {
9922 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9923 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 9924 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
9925 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9926 .dac_nids = alc883_dac_nids,
9927 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9928 .adc_nids = alc889_adc_nids,
9929 .dig_out_nid = ALC883_DIGOUT_NID,
9930 .dig_in_nid = ALC883_DIGIN_NID,
9931 .slave_dig_outs = alc883_slave_dig_outs,
9932 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9933 .channel_mode = alc889_8ch_intel_modes,
9934 .capsrc_nids = alc889_capsrc_nids,
9935 .input_mux = &alc889_capture_source,
4f5d1706 9936 .setup = alc889_automute_setup,
6732bd0d
WF
9937 .init_hook = alc889_intel_init_hook,
9938 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
9939 .need_dac_fix = 1,
9940 },
9c7f852e
TI
9941 [ALC883_6ST_DIG] = {
9942 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9943 .init_verbs = { alc883_init_verbs },
9944 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9945 .dac_nids = alc883_dac_nids,
9946 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9947 .dig_in_nid = ALC883_DIGIN_NID,
9948 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9949 .channel_mode = alc883_sixstack_modes,
9950 .input_mux = &alc883_capture_source,
9951 },
ccc656ce 9952 [ALC883_TARGA_DIG] = {
c259249f 9953 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
9954 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9955 alc883_targa_verbs},
ccc656ce
KY
9956 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9957 .dac_nids = alc883_dac_nids,
9958 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9959 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9960 .channel_mode = alc883_3ST_6ch_modes,
9961 .need_dac_fix = 1,
9962 .input_mux = &alc883_capture_source,
c259249f 9963 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9964 .setup = alc882_targa_setup,
9965 .init_hook = alc882_targa_automute,
ccc656ce
KY
9966 },
9967 [ALC883_TARGA_2ch_DIG] = {
c259249f 9968 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
9969 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9970 alc883_targa_verbs},
ccc656ce
KY
9971 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9972 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9973 .adc_nids = alc883_adc_nids_alt,
9974 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 9975 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 9976 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9977 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9978 .channel_mode = alc883_3ST_2ch_modes,
9979 .input_mux = &alc883_capture_source,
c259249f 9980 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9981 .setup = alc882_targa_setup,
9982 .init_hook = alc882_targa_automute,
ccc656ce 9983 },
64a8be74 9984 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
9985 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
9986 alc883_chmode_mixer },
64a8be74 9987 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 9988 alc883_targa_verbs },
64a8be74
DH
9989 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9990 .dac_nids = alc883_dac_nids,
9991 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9992 .adc_nids = alc883_adc_nids_rev,
9993 .capsrc_nids = alc883_capsrc_nids_rev,
9994 .dig_out_nid = ALC883_DIGOUT_NID,
9995 .dig_in_nid = ALC883_DIGIN_NID,
9996 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
9997 .channel_mode = alc883_4ST_8ch_modes,
9998 .need_dac_fix = 1,
9999 .input_mux = &alc883_capture_source,
c259249f 10000 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10001 .setup = alc882_targa_setup,
10002 .init_hook = alc882_targa_automute,
64a8be74 10003 },
bab282b9 10004 [ALC883_ACER] = {
676a9b53 10005 .mixers = { alc883_base_mixer },
bab282b9
VA
10006 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10007 * and the headphone jack. Turn this on and rely on the
10008 * standard mute methods whenever the user wants to turn
10009 * these outputs off.
10010 */
10011 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10012 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10013 .dac_nids = alc883_dac_nids,
bab282b9
VA
10014 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10015 .channel_mode = alc883_3ST_2ch_modes,
10016 .input_mux = &alc883_capture_source,
10017 },
2880a867 10018 [ALC883_ACER_ASPIRE] = {
676a9b53 10019 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10020 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10021 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10022 .dac_nids = alc883_dac_nids,
10023 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10024 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10025 .channel_mode = alc883_3ST_2ch_modes,
10026 .input_mux = &alc883_capture_source,
a9fd4f3f 10027 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10028 .setup = alc883_acer_aspire_setup,
10029 .init_hook = alc_automute_amp,
d1a991a6 10030 },
5b2d1eca 10031 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 10032 .mixers = { alc888_base_mixer,
5b2d1eca
VP
10033 alc883_chmode_mixer },
10034 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10035 alc888_acer_aspire_4930g_verbs },
10036 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10037 .dac_nids = alc883_dac_nids,
10038 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10039 .adc_nids = alc883_adc_nids_rev,
10040 .capsrc_nids = alc883_capsrc_nids_rev,
10041 .dig_out_nid = ALC883_DIGOUT_NID,
10042 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10043 .channel_mode = alc883_3ST_6ch_modes,
10044 .need_dac_fix = 1,
973b8cb0 10045 .const_channel_count = 6,
5b2d1eca 10046 .num_mux_defs =
ef8ef5fb
VP
10047 ARRAY_SIZE(alc888_2_capture_sources),
10048 .input_mux = alc888_2_capture_sources,
d2fd4b09 10049 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10050 .setup = alc888_acer_aspire_4930g_setup,
10051 .init_hook = alc_automute_amp,
d2fd4b09
TV
10052 },
10053 [ALC888_ACER_ASPIRE_6530G] = {
10054 .mixers = { alc888_acer_aspire_6530_mixer },
10055 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10056 alc888_acer_aspire_6530g_verbs },
10057 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10058 .dac_nids = alc883_dac_nids,
10059 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10060 .adc_nids = alc883_adc_nids_rev,
10061 .capsrc_nids = alc883_capsrc_nids_rev,
10062 .dig_out_nid = ALC883_DIGOUT_NID,
10063 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10064 .channel_mode = alc883_3ST_2ch_modes,
10065 .num_mux_defs =
10066 ARRAY_SIZE(alc888_2_capture_sources),
10067 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 10068 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10069 .setup = alc888_acer_aspire_6530g_setup,
10070 .init_hook = alc_automute_amp,
5b2d1eca 10071 },
3b315d70 10072 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10073 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10074 alc883_chmode_mixer },
10075 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10076 alc889_acer_aspire_8930g_verbs,
10077 alc889_eapd_verbs},
3b315d70
HM
10078 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10079 .dac_nids = alc883_dac_nids,
018df418
HM
10080 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10081 .adc_nids = alc889_adc_nids,
10082 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10083 .dig_out_nid = ALC883_DIGOUT_NID,
10084 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10085 .channel_mode = alc883_3ST_6ch_modes,
10086 .need_dac_fix = 1,
10087 .const_channel_count = 6,
10088 .num_mux_defs =
018df418
HM
10089 ARRAY_SIZE(alc889_capture_sources),
10090 .input_mux = alc889_capture_sources,
3b315d70 10091 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10092 .setup = alc889_acer_aspire_8930g_setup,
10093 .init_hook = alc_automute_amp,
f5de24b0 10094#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10095 .power_hook = alc_power_eapd,
f5de24b0 10096#endif
3b315d70 10097 },
fc86f954
DK
10098 [ALC888_ACER_ASPIRE_7730G] = {
10099 .mixers = { alc883_3ST_6ch_mixer,
10100 alc883_chmode_mixer },
10101 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10102 alc888_acer_aspire_7730G_verbs },
10103 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10104 .dac_nids = alc883_dac_nids,
10105 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10106 .adc_nids = alc883_adc_nids_rev,
10107 .capsrc_nids = alc883_capsrc_nids_rev,
10108 .dig_out_nid = ALC883_DIGOUT_NID,
10109 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10110 .channel_mode = alc883_3ST_6ch_modes,
10111 .need_dac_fix = 1,
10112 .const_channel_count = 6,
10113 .input_mux = &alc883_capture_source,
10114 .unsol_event = alc_automute_amp_unsol_event,
10115 .setup = alc888_acer_aspire_6530g_setup,
10116 .init_hook = alc_automute_amp,
10117 },
c07584c8
TD
10118 [ALC883_MEDION] = {
10119 .mixers = { alc883_fivestack_mixer,
10120 alc883_chmode_mixer },
10121 .init_verbs = { alc883_init_verbs,
b373bdeb 10122 alc883_medion_eapd_verbs },
c07584c8
TD
10123 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10124 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10125 .adc_nids = alc883_adc_nids_alt,
10126 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10127 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10128 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10129 .channel_mode = alc883_sixstack_modes,
10130 .input_mux = &alc883_capture_source,
b373bdeb 10131 },
272a527c
KY
10132 [ALC883_MEDION_MD2] = {
10133 .mixers = { alc883_medion_md2_mixer},
10134 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
10135 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10136 .dac_nids = alc883_dac_nids,
10137 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10138 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10139 .channel_mode = alc883_3ST_2ch_modes,
10140 .input_mux = &alc883_capture_source,
a9fd4f3f 10141 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10142 .setup = alc883_medion_md2_setup,
10143 .init_hook = alc_automute_amp,
ea1fb29a 10144 },
7ad7b218
MC
10145 [ALC883_MEDION_WIM2160] = {
10146 .mixers = { alc883_medion_wim2160_mixer },
10147 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10148 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10149 .dac_nids = alc883_dac_nids,
10150 .dig_out_nid = ALC883_DIGOUT_NID,
10151 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10152 .adc_nids = alc883_adc_nids,
10153 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10154 .channel_mode = alc883_3ST_2ch_modes,
10155 .input_mux = &alc883_capture_source,
10156 .unsol_event = alc_automute_amp_unsol_event,
10157 .setup = alc883_medion_wim2160_setup,
10158 .init_hook = alc_automute_amp,
10159 },
b373bdeb 10160 [ALC883_LAPTOP_EAPD] = {
676a9b53 10161 .mixers = { alc883_base_mixer },
b373bdeb
AN
10162 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10163 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10164 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10165 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10166 .channel_mode = alc883_3ST_2ch_modes,
10167 .input_mux = &alc883_capture_source,
10168 },
a65cc60f 10169 [ALC883_CLEVO_M540R] = {
10170 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10171 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10172 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10173 .dac_nids = alc883_dac_nids,
10174 .dig_out_nid = ALC883_DIGOUT_NID,
10175 .dig_in_nid = ALC883_DIGIN_NID,
10176 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10177 .channel_mode = alc883_3ST_6ch_clevo_modes,
10178 .need_dac_fix = 1,
10179 .input_mux = &alc883_capture_source,
10180 /* This machine has the hardware HP auto-muting, thus
10181 * we need no software mute via unsol event
10182 */
10183 },
0c4cc443
HRK
10184 [ALC883_CLEVO_M720] = {
10185 .mixers = { alc883_clevo_m720_mixer },
10186 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10187 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10188 .dac_nids = alc883_dac_nids,
10189 .dig_out_nid = ALC883_DIGOUT_NID,
10190 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10191 .channel_mode = alc883_3ST_2ch_modes,
10192 .input_mux = &alc883_capture_source,
0c4cc443 10193 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10194 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10195 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10196 },
bc9f98a9
KY
10197 [ALC883_LENOVO_101E_2ch] = {
10198 .mixers = { alc883_lenovo_101e_2ch_mixer},
10199 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10200 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10201 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10202 .adc_nids = alc883_adc_nids_alt,
10203 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10204 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10205 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10206 .channel_mode = alc883_3ST_2ch_modes,
10207 .input_mux = &alc883_lenovo_101e_capture_source,
10208 .unsol_event = alc883_lenovo_101e_unsol_event,
10209 .init_hook = alc883_lenovo_101e_all_automute,
10210 },
272a527c
KY
10211 [ALC883_LENOVO_NB0763] = {
10212 .mixers = { alc883_lenovo_nb0763_mixer },
10213 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10214 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10215 .dac_nids = alc883_dac_nids,
272a527c
KY
10216 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10217 .channel_mode = alc883_3ST_2ch_modes,
10218 .need_dac_fix = 1,
10219 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 10220 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10221 .setup = alc883_medion_md2_setup,
10222 .init_hook = alc_automute_amp,
272a527c
KY
10223 },
10224 [ALC888_LENOVO_MS7195_DIG] = {
10225 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10226 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10227 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10228 .dac_nids = alc883_dac_nids,
10229 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10230 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10231 .channel_mode = alc883_3ST_6ch_modes,
10232 .need_dac_fix = 1,
10233 .input_mux = &alc883_capture_source,
10234 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10235 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
10236 },
10237 [ALC883_HAIER_W66] = {
c259249f 10238 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10239 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10240 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10241 .dac_nids = alc883_dac_nids,
10242 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10243 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10244 .channel_mode = alc883_3ST_2ch_modes,
10245 .input_mux = &alc883_capture_source,
a9fd4f3f 10246 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10247 .setup = alc883_haier_w66_setup,
10248 .init_hook = alc_automute_amp,
eea6419e 10249 },
4723c022 10250 [ALC888_3ST_HP] = {
eea6419e 10251 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10252 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10253 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10254 .dac_nids = alc883_dac_nids,
4723c022
CM
10255 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10256 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10257 .need_dac_fix = 1,
10258 .input_mux = &alc883_capture_source,
a9fd4f3f 10259 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10260 .setup = alc888_3st_hp_setup,
10261 .init_hook = alc_automute_amp,
8341de60 10262 },
5795b9e6 10263 [ALC888_6ST_DELL] = {
f24dbdc6 10264 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10265 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10266 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10267 .dac_nids = alc883_dac_nids,
10268 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10269 .dig_in_nid = ALC883_DIGIN_NID,
10270 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10271 .channel_mode = alc883_sixstack_modes,
10272 .input_mux = &alc883_capture_source,
a9fd4f3f 10273 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10274 .setup = alc888_6st_dell_setup,
10275 .init_hook = alc_automute_amp,
5795b9e6 10276 },
a8848bd6
AS
10277 [ALC883_MITAC] = {
10278 .mixers = { alc883_mitac_mixer },
10279 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10280 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10281 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10282 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10283 .channel_mode = alc883_3ST_2ch_modes,
10284 .input_mux = &alc883_capture_source,
a9fd4f3f 10285 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10286 .setup = alc883_mitac_setup,
10287 .init_hook = alc_automute_amp,
a8848bd6 10288 },
fb97dc67
J
10289 [ALC883_FUJITSU_PI2515] = {
10290 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10291 .init_verbs = { alc883_init_verbs,
10292 alc883_2ch_fujitsu_pi2515_verbs},
10293 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10294 .dac_nids = alc883_dac_nids,
10295 .dig_out_nid = ALC883_DIGOUT_NID,
10296 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10297 .channel_mode = alc883_3ST_2ch_modes,
10298 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10299 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10300 .setup = alc883_2ch_fujitsu_pi2515_setup,
10301 .init_hook = alc_automute_amp,
fb97dc67 10302 },
ef8ef5fb
VP
10303 [ALC888_FUJITSU_XA3530] = {
10304 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10305 .init_verbs = { alc883_init_verbs,
10306 alc888_fujitsu_xa3530_verbs },
10307 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10308 .dac_nids = alc883_dac_nids,
10309 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10310 .adc_nids = alc883_adc_nids_rev,
10311 .capsrc_nids = alc883_capsrc_nids_rev,
10312 .dig_out_nid = ALC883_DIGOUT_NID,
10313 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10314 .channel_mode = alc888_4ST_8ch_intel_modes,
10315 .num_mux_defs =
10316 ARRAY_SIZE(alc888_2_capture_sources),
10317 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10318 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10319 .setup = alc888_fujitsu_xa3530_setup,
10320 .init_hook = alc_automute_amp,
ef8ef5fb 10321 },
e2757d5e
KY
10322 [ALC888_LENOVO_SKY] = {
10323 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10324 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10325 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10326 .dac_nids = alc883_dac_nids,
10327 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10328 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10329 .channel_mode = alc883_sixstack_modes,
10330 .need_dac_fix = 1,
10331 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10332 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10333 .setup = alc888_lenovo_sky_setup,
10334 .init_hook = alc_automute_amp,
e2757d5e
KY
10335 },
10336 [ALC888_ASUS_M90V] = {
10337 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10338 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10339 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10340 .dac_nids = alc883_dac_nids,
10341 .dig_out_nid = ALC883_DIGOUT_NID,
10342 .dig_in_nid = ALC883_DIGIN_NID,
10343 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10344 .channel_mode = alc883_3ST_6ch_modes,
10345 .need_dac_fix = 1,
10346 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10347 .unsol_event = alc_sku_unsol_event,
10348 .setup = alc883_mode2_setup,
10349 .init_hook = alc_inithook,
e2757d5e
KY
10350 },
10351 [ALC888_ASUS_EEE1601] = {
10352 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10353 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10354 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10355 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10356 .dac_nids = alc883_dac_nids,
10357 .dig_out_nid = ALC883_DIGOUT_NID,
10358 .dig_in_nid = ALC883_DIGIN_NID,
10359 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10360 .channel_mode = alc883_3ST_2ch_modes,
10361 .need_dac_fix = 1,
10362 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10363 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10364 .init_hook = alc883_eee1601_inithook,
10365 },
3ab90935
WF
10366 [ALC1200_ASUS_P5Q] = {
10367 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10368 .init_verbs = { alc883_init_verbs },
10369 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10370 .dac_nids = alc883_dac_nids,
10371 .dig_out_nid = ALC1200_DIGOUT_NID,
10372 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10373 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10374 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10375 .channel_mode = alc883_sixstack_modes,
10376 .input_mux = &alc883_capture_source,
10377 },
eb4c41d3
TS
10378 [ALC889A_MB31] = {
10379 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10380 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10381 alc880_gpio1_init_verbs },
10382 .adc_nids = alc883_adc_nids,
10383 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10384 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10385 .dac_nids = alc883_dac_nids,
10386 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10387 .channel_mode = alc889A_mb31_6ch_modes,
10388 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10389 .input_mux = &alc889A_mb31_capture_source,
10390 .dig_out_nid = ALC883_DIGOUT_NID,
10391 .unsol_event = alc889A_mb31_unsol_event,
10392 .init_hook = alc889A_mb31_automute,
10393 },
3e1647c5
GG
10394 [ALC883_SONY_VAIO_TT] = {
10395 .mixers = { alc883_vaiott_mixer },
10396 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10397 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10398 .dac_nids = alc883_dac_nids,
10399 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10400 .channel_mode = alc883_3ST_2ch_modes,
10401 .input_mux = &alc883_capture_source,
10402 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10403 .setup = alc883_vaiott_setup,
10404 .init_hook = alc_automute_amp,
3e1647c5 10405 },
9c7f852e
TI
10406};
10407
10408
4953550a
TI
10409/*
10410 * Pin config fixes
10411 */
10412enum {
954a29c8
TI
10413 PINFIX_ABIT_AW9D_MAX,
10414 PINFIX_PB_M5210,
4953550a
TI
10415};
10416
10417static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
10418 { 0x15, 0x01080104 }, /* side */
10419 { 0x16, 0x01011012 }, /* rear */
10420 { 0x17, 0x01016011 }, /* clfe */
10421 { }
10422};
10423
954a29c8
TI
10424static const struct hda_verb pb_m5210_verbs[] = {
10425 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10426 {}
10427};
10428
f8f25ba3
TI
10429static const struct alc_fixup alc882_fixups[] = {
10430 [PINFIX_ABIT_AW9D_MAX] = {
10431 .pins = alc882_abit_aw9d_pinfix
10432 },
954a29c8
TI
10433 [PINFIX_PB_M5210] = {
10434 .verbs = pb_m5210_verbs
10435 },
4953550a
TI
10436};
10437
f8f25ba3 10438static struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10439 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
4953550a
TI
10440 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10441 {}
10442};
10443
9c7f852e
TI
10444/*
10445 * BIOS auto configuration
10446 */
05f5f477
TI
10447static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10448 const struct auto_pin_cfg *cfg)
10449{
10450 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10451}
10452
4953550a 10453static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10454 hda_nid_t nid, int pin_type,
489008cd 10455 hda_nid_t dac)
9c7f852e 10456{
f12ab1e0
TI
10457 int idx;
10458
489008cd 10459 /* set as output */
f6c7e546 10460 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10461
10462 if (dac == 0x25)
9c7f852e 10463 idx = 4;
489008cd
TI
10464 else if (dac >= 0x02 && dac <= 0x05)
10465 idx = dac - 2;
f9700d5a 10466 else
489008cd 10467 return;
9c7f852e 10468 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
10469}
10470
4953550a 10471static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10472{
10473 struct alc_spec *spec = codec->spec;
10474 int i;
10475
10476 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10477 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10478 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10479 if (nid)
4953550a 10480 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 10481 spec->multiout.dac_nids[i]);
9c7f852e
TI
10482 }
10483}
10484
4953550a 10485static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10486{
10487 struct alc_spec *spec = codec->spec;
489008cd 10488 hda_nid_t pin, dac;
9c7f852e 10489
eb06ed8f 10490 pin = spec->autocfg.hp_pins[0];
489008cd
TI
10491 if (pin) {
10492 dac = spec->multiout.hp_nid;
10493 if (!dac)
10494 dac = spec->multiout.dac_nids[0]; /* to front */
10495 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10496 }
f6c7e546 10497 pin = spec->autocfg.speaker_pins[0];
489008cd
TI
10498 if (pin) {
10499 dac = spec->multiout.extra_out_nid[0];
10500 if (!dac)
10501 dac = spec->multiout.dac_nids[0]; /* to front */
10502 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10503 }
9c7f852e
TI
10504}
10505
4953550a 10506static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10507{
10508 struct alc_spec *spec = codec->spec;
10509 int i;
10510
10511 for (i = 0; i < AUTO_PIN_LAST; i++) {
10512 hda_nid_t nid = spec->autocfg.input_pins[i];
4953550a
TI
10513 if (!nid)
10514 continue;
0d971c9f 10515 alc_set_input_pin(codec, nid, i);
4953550a
TI
10516 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10517 snd_hda_codec_write(codec, nid, 0,
10518 AC_VERB_SET_AMP_GAIN_MUTE,
10519 AMP_OUT_MUTE);
10520 }
10521}
10522
10523static void alc882_auto_init_input_src(struct hda_codec *codec)
10524{
10525 struct alc_spec *spec = codec->spec;
10526 int c;
10527
10528 for (c = 0; c < spec->num_adc_nids; c++) {
10529 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10530 hda_nid_t nid = spec->capsrc_nids[c];
10531 unsigned int mux_idx;
10532 const struct hda_input_mux *imux;
10533 int conns, mute, idx, item;
10534
10535 conns = snd_hda_get_connections(codec, nid, conn_list,
10536 ARRAY_SIZE(conn_list));
10537 if (conns < 0)
10538 continue;
10539 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10540 imux = &spec->input_mux[mux_idx];
5311114d
TI
10541 if (!imux->num_items && mux_idx > 0)
10542 imux = &spec->input_mux[0];
4953550a
TI
10543 for (idx = 0; idx < conns; idx++) {
10544 /* if the current connection is the selected one,
10545 * unmute it as default - otherwise mute it
10546 */
10547 mute = AMP_IN_MUTE(idx);
10548 for (item = 0; item < imux->num_items; item++) {
10549 if (imux->items[item].index == idx) {
10550 if (spec->cur_mux[c] == item)
10551 mute = AMP_IN_UNMUTE(idx);
10552 break;
10553 }
10554 }
10555 /* check if we have a selector or mixer
10556 * we could check for the widget type instead, but
10557 * just check for Amp-In presence (in case of mixer
10558 * without amp-in there is something wrong, this
10559 * function shouldn't be used or capsrc nid is wrong)
10560 */
10561 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10562 snd_hda_codec_write(codec, nid, 0,
10563 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10564 mute);
10565 else if (mute != AMP_IN_MUTE(idx))
10566 snd_hda_codec_write(codec, nid, 0,
10567 AC_VERB_SET_CONNECT_SEL,
10568 idx);
9c7f852e
TI
10569 }
10570 }
10571}
10572
4953550a
TI
10573/* add mic boosts if needed */
10574static int alc_auto_add_mic_boost(struct hda_codec *codec)
10575{
10576 struct alc_spec *spec = codec->spec;
10577 int err;
10578 hda_nid_t nid;
10579
10580 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
10581 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10582 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10583 "Mic Boost",
10584 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10585 if (err < 0)
10586 return err;
10587 }
10588 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
10589 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10590 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10591 "Front Mic Boost",
10592 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10593 if (err < 0)
10594 return err;
10595 }
10596 return 0;
10597}
f511b01c 10598
9c7f852e 10599/* almost identical with ALC880 parser... */
4953550a 10600static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10601{
10602 struct alc_spec *spec = codec->spec;
05f5f477 10603 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 10604 int err;
9c7f852e 10605
05f5f477
TI
10606 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10607 alc882_ignore);
9c7f852e
TI
10608 if (err < 0)
10609 return err;
05f5f477
TI
10610 if (!spec->autocfg.line_outs)
10611 return 0; /* can't find valid BIOS pin config */
776e184e 10612
05f5f477
TI
10613 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10614 if (err < 0)
10615 return err;
10616 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
10617 if (err < 0)
10618 return err;
10619 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10620 "Headphone");
05f5f477
TI
10621 if (err < 0)
10622 return err;
10623 err = alc880_auto_create_extra_out(spec,
10624 spec->autocfg.speaker_pins[0],
10625 "Speaker");
10626 if (err < 0)
10627 return err;
05f5f477 10628 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10629 if (err < 0)
10630 return err;
10631
05f5f477
TI
10632 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10633
757899ac 10634 alc_auto_parse_digital(codec);
05f5f477
TI
10635
10636 if (spec->kctls.list)
10637 add_mixer(spec, spec->kctls.list);
10638
10639 add_verb(spec, alc883_auto_init_verbs);
4953550a 10640 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10641 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10642 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10643
05f5f477
TI
10644 spec->num_mux_defs = 1;
10645 spec->input_mux = &spec->private_imux[0];
10646
6227cdce 10647 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10648
10649 err = alc_auto_add_mic_boost(codec);
10650 if (err < 0)
10651 return err;
61b9b9b1 10652
776e184e 10653 return 1; /* config found */
9c7f852e
TI
10654}
10655
10656/* additional initialization for auto-configuration model */
4953550a 10657static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10658{
f6c7e546 10659 struct alc_spec *spec = codec->spec;
4953550a
TI
10660 alc882_auto_init_multi_out(codec);
10661 alc882_auto_init_hp_out(codec);
10662 alc882_auto_init_analog_input(codec);
10663 alc882_auto_init_input_src(codec);
757899ac 10664 alc_auto_init_digital(codec);
f6c7e546 10665 if (spec->unsol_event)
7fb0d78f 10666 alc_inithook(codec);
9c7f852e
TI
10667}
10668
4953550a 10669static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10670{
10671 struct alc_spec *spec;
10672 int err, board_config;
10673
10674 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10675 if (spec == NULL)
10676 return -ENOMEM;
10677
10678 codec->spec = spec;
10679
da00c244
KY
10680 alc_auto_parse_customize_define(codec);
10681
4953550a
TI
10682 switch (codec->vendor_id) {
10683 case 0x10ec0882:
10684 case 0x10ec0885:
10685 break;
10686 default:
10687 /* ALC883 and variants */
10688 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10689 break;
10690 }
2c3bf9ab 10691
4953550a
TI
10692 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10693 alc882_models,
10694 alc882_cfg_tbl);
10695
10696 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10697 board_config = snd_hda_check_board_codec_sid_config(codec,
10698 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10699
10700 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 10701 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
10702 codec->chip_name);
10703 board_config = ALC882_AUTO;
9c7f852e
TI
10704 }
10705
7fa90e87
TI
10706 if (board_config == ALC882_AUTO)
10707 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
4953550a
TI
10708
10709 if (board_config == ALC882_AUTO) {
9c7f852e 10710 /* automatic parse from the BIOS config */
4953550a 10711 err = alc882_parse_auto_config(codec);
9c7f852e
TI
10712 if (err < 0) {
10713 alc_free(codec);
10714 return err;
f12ab1e0 10715 } else if (!err) {
9c7f852e
TI
10716 printk(KERN_INFO
10717 "hda_codec: Cannot set up configuration "
10718 "from BIOS. Using base mode...\n");
4953550a 10719 board_config = ALC882_3ST_DIG;
9c7f852e
TI
10720 }
10721 }
10722
dc1eae25 10723 if (has_cdefine_beep(codec)) {
8af2591d
TI
10724 err = snd_hda_attach_beep_device(codec, 0x1);
10725 if (err < 0) {
10726 alc_free(codec);
10727 return err;
10728 }
680cd536
KK
10729 }
10730
4953550a 10731 if (board_config != ALC882_AUTO)
e9c364c0 10732 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 10733
4953550a
TI
10734 spec->stream_analog_playback = &alc882_pcm_analog_playback;
10735 spec->stream_analog_capture = &alc882_pcm_analog_capture;
10736 /* FIXME: setup DAC5 */
10737 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
10738 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
10739
10740 spec->stream_digital_playback = &alc882_pcm_digital_playback;
10741 spec->stream_digital_capture = &alc882_pcm_digital_capture;
10742
4953550a 10743 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 10744 int i, j;
4953550a
TI
10745 spec->num_adc_nids = 0;
10746 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 10747 const struct hda_input_mux *imux = spec->input_mux;
4953550a 10748 hda_nid_t cap;
d11f74c6 10749 hda_nid_t items[16];
4953550a
TI
10750 hda_nid_t nid = alc882_adc_nids[i];
10751 unsigned int wcap = get_wcaps(codec, nid);
10752 /* get type */
a22d543a 10753 wcap = get_wcaps_type(wcap);
4953550a
TI
10754 if (wcap != AC_WID_AUD_IN)
10755 continue;
10756 spec->private_adc_nids[spec->num_adc_nids] = nid;
10757 err = snd_hda_get_connections(codec, nid, &cap, 1);
10758 if (err < 0)
10759 continue;
d11f74c6
TI
10760 err = snd_hda_get_connections(codec, cap, items,
10761 ARRAY_SIZE(items));
10762 if (err < 0)
10763 continue;
10764 for (j = 0; j < imux->num_items; j++)
10765 if (imux->items[j].index >= err)
10766 break;
10767 if (j < imux->num_items)
10768 continue;
4953550a
TI
10769 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
10770 spec->num_adc_nids++;
61b9b9b1 10771 }
4953550a
TI
10772 spec->adc_nids = spec->private_adc_nids;
10773 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
10774 }
10775
b59bdf3b 10776 set_capture_mixer(codec);
da00c244 10777
dc1eae25 10778 if (has_cdefine_beep(codec))
da00c244 10779 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 10780
7fa90e87
TI
10781 if (board_config == ALC882_AUTO)
10782 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
10783
2134ea4f
TI
10784 spec->vmaster_nid = 0x0c;
10785
9c7f852e 10786 codec->patch_ops = alc_patch_ops;
4953550a
TI
10787 if (board_config == ALC882_AUTO)
10788 spec->init_hook = alc882_auto_init;
cb53c626
TI
10789#ifdef CONFIG_SND_HDA_POWER_SAVE
10790 if (!spec->loopback.amplist)
4953550a 10791 spec->loopback.amplist = alc882_loopbacks;
cb53c626 10792#endif
9c7f852e
TI
10793
10794 return 0;
10795}
10796
4953550a 10797
9c7f852e
TI
10798/*
10799 * ALC262 support
10800 */
10801
10802#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
10803#define ALC262_DIGIN_NID ALC880_DIGIN_NID
10804
10805#define alc262_dac_nids alc260_dac_nids
10806#define alc262_adc_nids alc882_adc_nids
10807#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
10808#define alc262_capsrc_nids alc882_capsrc_nids
10809#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
10810
10811#define alc262_modes alc260_modes
10812#define alc262_capture_source alc882_capture_source
10813
4e555fe5
KY
10814static hda_nid_t alc262_dmic_adc_nids[1] = {
10815 /* ADC0 */
10816 0x09
10817};
10818
10819static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
10820
9c7f852e
TI
10821static struct snd_kcontrol_new alc262_base_mixer[] = {
10822 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10823 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10824 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10825 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10826 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10827 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10828 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10829 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10830 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
10831 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10832 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 10833 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
10834 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
10835 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10836 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
10837 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10838 { } /* end */
10839};
10840
ce875f07
TI
10841/* update HP, line and mono-out pins according to the master switch */
10842static void alc262_hp_master_update(struct hda_codec *codec)
10843{
10844 struct alc_spec *spec = codec->spec;
10845 int val = spec->master_sw;
10846
10847 /* HP & line-out */
10848 snd_hda_codec_write_cache(codec, 0x1b, 0,
10849 AC_VERB_SET_PIN_WIDGET_CONTROL,
10850 val ? PIN_HP : 0);
10851 snd_hda_codec_write_cache(codec, 0x15, 0,
10852 AC_VERB_SET_PIN_WIDGET_CONTROL,
10853 val ? PIN_HP : 0);
10854 /* mono (speaker) depending on the HP jack sense */
10855 val = val && !spec->jack_present;
10856 snd_hda_codec_write_cache(codec, 0x16, 0,
10857 AC_VERB_SET_PIN_WIDGET_CONTROL,
10858 val ? PIN_OUT : 0);
10859}
10860
10861static void alc262_hp_bpc_automute(struct hda_codec *codec)
10862{
10863 struct alc_spec *spec = codec->spec;
864f92be
WF
10864
10865 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
10866 alc262_hp_master_update(codec);
10867}
10868
10869static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
10870{
10871 if ((res >> 26) != ALC880_HP_EVENT)
10872 return;
10873 alc262_hp_bpc_automute(codec);
10874}
10875
10876static void alc262_hp_wildwest_automute(struct hda_codec *codec)
10877{
10878 struct alc_spec *spec = codec->spec;
864f92be
WF
10879
10880 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
10881 alc262_hp_master_update(codec);
10882}
10883
10884static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
10885 unsigned int res)
10886{
10887 if ((res >> 26) != ALC880_HP_EVENT)
10888 return;
10889 alc262_hp_wildwest_automute(codec);
10890}
10891
b72519b5 10892#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
10893
10894static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10895 struct snd_ctl_elem_value *ucontrol)
10896{
10897 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10898 struct alc_spec *spec = codec->spec;
10899 int val = !!*ucontrol->value.integer.value;
10900
10901 if (val == spec->master_sw)
10902 return 0;
10903 spec->master_sw = val;
10904 alc262_hp_master_update(codec);
10905 return 1;
10906}
10907
b72519b5
TI
10908#define ALC262_HP_MASTER_SWITCH \
10909 { \
10910 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10911 .name = "Master Playback Switch", \
10912 .info = snd_ctl_boolean_mono_info, \
10913 .get = alc262_hp_master_sw_get, \
10914 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
10915 }, \
10916 { \
10917 .iface = NID_MAPPING, \
10918 .name = "Master Playback Switch", \
10919 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
10920 }
10921
5b0cb1d8 10922
9c7f852e 10923static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 10924 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
10925 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10926 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10927 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
10928 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10929 HDA_OUTPUT),
10930 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10931 HDA_OUTPUT),
9c7f852e
TI
10932 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10933 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10934 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
10935 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10936 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 10937 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
10938 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10939 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10940 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10941 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
10942 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
10943 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
10944 { } /* end */
10945};
10946
cd7509a4 10947static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 10948 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
10949 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10950 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10951 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10952 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
10953 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10954 HDA_OUTPUT),
10955 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10956 HDA_OUTPUT),
cd7509a4
KY
10957 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
10958 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 10959 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
10960 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10961 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10962 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10963 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
10964 { } /* end */
10965};
10966
10967static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
10968 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10969 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10970 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
10971 { } /* end */
10972};
10973
66d2a9d6 10974/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 10975static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
10976{
10977 struct alc_spec *spec = codec->spec;
66d2a9d6 10978
a9fd4f3f 10979 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 10980 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
10981}
10982
66d2a9d6 10983static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
10984 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10985 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
10986 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10987 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10988 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10989 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10990 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10991 { } /* end */
10992};
10993
10994static struct hda_verb alc262_hp_t5735_verbs[] = {
10995 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10996 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10997
10998 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10999 { }
11000};
11001
8c427226 11002static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11003 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11004 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11005 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11006 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11007 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11008 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11009 { } /* end */
11010};
11011
11012static struct hda_verb alc262_hp_rp5700_verbs[] = {
11013 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11014 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11015 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11016 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11017 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11018 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11019 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11020 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11021 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11022 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11023 {}
11024};
11025
11026static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11027 .num_items = 1,
11028 .items = {
11029 { "Line", 0x1 },
11030 },
11031};
11032
42171c17
TI
11033/* bind hp and internal speaker mute (with plug check) as master switch */
11034static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 11035{
42171c17
TI
11036 struct alc_spec *spec = codec->spec;
11037 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11038 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11039 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11040 unsigned int mute;
0724ea2a 11041
42171c17
TI
11042 /* HP */
11043 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11044 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11045 HDA_AMP_MUTE, mute);
11046 /* mute internal speaker per jack sense */
11047 if (spec->jack_present)
11048 mute = HDA_AMP_MUTE;
11049 if (line_nid)
11050 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11051 HDA_AMP_MUTE, mute);
11052 if (speaker_nid && speaker_nid != line_nid)
11053 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 11054 HDA_AMP_MUTE, mute);
42171c17
TI
11055}
11056
11057#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11058
11059static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11060 struct snd_ctl_elem_value *ucontrol)
11061{
11062 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11063 struct alc_spec *spec = codec->spec;
11064 int val = !!*ucontrol->value.integer.value;
11065
11066 if (val == spec->master_sw)
11067 return 0;
11068 spec->master_sw = val;
11069 alc262_hippo_master_update(codec);
11070 return 1;
11071}
11072
11073#define ALC262_HIPPO_MASTER_SWITCH \
11074 { \
11075 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11076 .name = "Master Playback Switch", \
11077 .info = snd_ctl_boolean_mono_info, \
11078 .get = alc262_hippo_master_sw_get, \
11079 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11080 }, \
11081 { \
11082 .iface = NID_MAPPING, \
11083 .name = "Master Playback Switch", \
11084 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11085 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11086 }
42171c17
TI
11087
11088static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11089 ALC262_HIPPO_MASTER_SWITCH,
11090 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11091 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11092 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11093 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11094 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11095 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11096 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11097 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11098 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11099 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11100 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11101 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11102 { } /* end */
11103};
11104
11105static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11106 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11107 ALC262_HIPPO_MASTER_SWITCH,
11108 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11109 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11110 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11111 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11112 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11113 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11114 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11115 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11116 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11117 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11118 { } /* end */
11119};
11120
11121/* mute/unmute internal speaker according to the hp jack and mute state */
11122static void alc262_hippo_automute(struct hda_codec *codec)
11123{
11124 struct alc_spec *spec = codec->spec;
11125 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 11126
864f92be 11127 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 11128 alc262_hippo_master_update(codec);
0724ea2a 11129}
5b31954e 11130
42171c17
TI
11131static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11132{
11133 if ((res >> 26) != ALC880_HP_EVENT)
11134 return;
11135 alc262_hippo_automute(codec);
11136}
11137
4f5d1706 11138static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11139{
11140 struct alc_spec *spec = codec->spec;
11141
11142 spec->autocfg.hp_pins[0] = 0x15;
11143 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11144}
11145
4f5d1706 11146static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11147{
11148 struct alc_spec *spec = codec->spec;
11149
11150 spec->autocfg.hp_pins[0] = 0x1b;
11151 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11152}
11153
11154
272a527c 11155static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11156 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11157 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11158 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11159 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11160 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11161 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11162 { } /* end */
11163};
11164
83c34218 11165static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11166 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11167 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11168 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11169 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11170 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11171 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11172 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11173 { } /* end */
11174};
272a527c 11175
ba340e82
TV
11176static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11177 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11178 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11179 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11180 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11181 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11182 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11183 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11184 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11185 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11186 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11187 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11188 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11189 { } /* end */
11190};
11191
11192static struct hda_verb alc262_tyan_verbs[] = {
11193 /* Headphone automute */
11194 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11195 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11196 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11197
11198 /* P11 AUX_IN, white 4-pin connector */
11199 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11200 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11201 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11202 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11203
11204 {}
11205};
11206
11207/* unsolicited event for HP jack sensing */
4f5d1706 11208static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11209{
a9fd4f3f 11210 struct alc_spec *spec = codec->spec;
ba340e82 11211
a9fd4f3f
TI
11212 spec->autocfg.hp_pins[0] = 0x1b;
11213 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
11214}
11215
ba340e82 11216
9c7f852e
TI
11217#define alc262_capture_mixer alc882_capture_mixer
11218#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11219
11220/*
11221 * generic initialization of ADC, input mixers and output mixers
11222 */
11223static struct hda_verb alc262_init_verbs[] = {
11224 /*
11225 * Unmute ADC0-2 and set the default input to mic-in
11226 */
11227 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11228 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11229 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11230 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11231 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11232 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11233
cb53c626 11234 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11235 * mixer widget
f12ab1e0
TI
11236 * Note: PASD motherboards uses the Line In 2 as the input for
11237 * front panel mic (mic 2)
9c7f852e
TI
11238 */
11239 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11240 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11241 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11242 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11243 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11244 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11245
11246 /*
df694daa
KY
11247 * Set up output mixers (0x0c - 0x0e)
11248 */
11249 /* set vol=0 to output mixers */
11250 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11251 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11252 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11253 /* set up input amps for analog loopback */
11254 /* Amp Indices: DAC = 0, mixer = 1 */
11255 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11256 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11257 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11258 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11259 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11260 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11261
11262 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11263 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11264 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11265 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11266 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11267 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11268
11269 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11270 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11271 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11272 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11273 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11274
df694daa
KY
11275 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11276 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11277
df694daa
KY
11278 /* FIXME: use matrix-type input source selection */
11279 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11280 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11281 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11282 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11283 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11284 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11285 /* Input mixer2 */
11286 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11287 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11288 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11289 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11290 /* Input mixer3 */
11291 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11292 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11293 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11294 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11295
11296 { }
11297};
1da177e4 11298
4e555fe5
KY
11299static struct hda_verb alc262_eapd_verbs[] = {
11300 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11301 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11302 { }
11303};
11304
ccc656ce
KY
11305static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11306 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11307 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11308 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11309
11310 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11311 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11312 {}
11313};
11314
272a527c
KY
11315static struct hda_verb alc262_sony_unsol_verbs[] = {
11316 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11317 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11318 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11319
11320 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11321 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11322 {}
272a527c
KY
11323};
11324
4e555fe5
KY
11325static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11326 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11327 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11328 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11329 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11330 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11331 { } /* end */
11332};
11333
11334static struct hda_verb alc262_toshiba_s06_verbs[] = {
11335 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11336 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11337 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11338 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11339 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11340 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11341 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11342 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11343 {}
11344};
11345
4f5d1706 11346static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11347{
a9fd4f3f
TI
11348 struct alc_spec *spec = codec->spec;
11349
11350 spec->autocfg.hp_pins[0] = 0x15;
11351 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11352 spec->ext_mic.pin = 0x18;
11353 spec->ext_mic.mux_idx = 0;
11354 spec->int_mic.pin = 0x12;
11355 spec->int_mic.mux_idx = 9;
11356 spec->auto_mic = 1;
4e555fe5
KY
11357}
11358
e8f9ae2a
PT
11359/*
11360 * nec model
11361 * 0x15 = headphone
11362 * 0x16 = internal speaker
11363 * 0x18 = external mic
11364 */
11365
11366static struct snd_kcontrol_new alc262_nec_mixer[] = {
11367 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11368 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11369
11370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11371 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11372 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11373
11374 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11375 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11376 { } /* end */
11377};
11378
11379static struct hda_verb alc262_nec_verbs[] = {
11380 /* Unmute Speaker */
11381 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11382
11383 /* Headphone */
11384 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11385 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11386
11387 /* External mic to headphone */
11388 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11389 /* External mic to speaker */
11390 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11391 {}
11392};
11393
834be88d
TI
11394/*
11395 * fujitsu model
5d9fab2d
TV
11396 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11397 * 0x1b = port replicator headphone out
834be88d
TI
11398 */
11399
11400#define ALC_HP_EVENT 0x37
11401
11402static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11403 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11404 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11405 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11406 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11407 {}
11408};
11409
0e31daf7
J
11410static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11411 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11412 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11413 {}
11414};
11415
e2595322
DC
11416static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11417 /* Front Mic pin: input vref at 50% */
11418 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11419 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11420 {}
11421};
11422
834be88d 11423static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11424 .num_items = 3,
834be88d
TI
11425 .items = {
11426 { "Mic", 0x0 },
39d3ed38 11427 { "Int Mic", 0x1 },
834be88d
TI
11428 { "CD", 0x4 },
11429 },
11430};
11431
9c7f852e
TI
11432static struct hda_input_mux alc262_HP_capture_source = {
11433 .num_items = 5,
11434 .items = {
11435 { "Mic", 0x0 },
accbe498 11436 { "Front Mic", 0x1 },
9c7f852e
TI
11437 { "Line", 0x2 },
11438 { "CD", 0x4 },
11439 { "AUX IN", 0x6 },
11440 },
11441};
11442
accbe498 11443static struct hda_input_mux alc262_HP_D7000_capture_source = {
11444 .num_items = 4,
11445 .items = {
11446 { "Mic", 0x0 },
11447 { "Front Mic", 0x2 },
11448 { "Line", 0x1 },
11449 { "CD", 0x4 },
11450 },
11451};
11452
ebc7a406 11453/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11454static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11455{
11456 struct alc_spec *spec = codec->spec;
11457 unsigned int mute;
11458
f12ab1e0 11459 if (force || !spec->sense_updated) {
864f92be
WF
11460 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11461 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11462 spec->sense_updated = 1;
11463 }
ebc7a406
TI
11464 /* unmute internal speaker only if both HPs are unplugged and
11465 * master switch is on
11466 */
11467 if (spec->jack_present)
11468 mute = HDA_AMP_MUTE;
11469 else
834be88d 11470 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11471 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11472 HDA_AMP_MUTE, mute);
834be88d
TI
11473}
11474
11475/* unsolicited event for HP jack sensing */
11476static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11477 unsigned int res)
11478{
11479 if ((res >> 26) != ALC_HP_EVENT)
11480 return;
11481 alc262_fujitsu_automute(codec, 1);
11482}
11483
ebc7a406
TI
11484static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11485{
11486 alc262_fujitsu_automute(codec, 1);
11487}
11488
834be88d 11489/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11490static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11491 .ops = &snd_hda_bind_vol,
11492 .values = {
11493 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11494 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11495 0
11496 },
11497};
834be88d 11498
0e31daf7
J
11499/* mute/unmute internal speaker according to the hp jack and mute state */
11500static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11501{
11502 struct alc_spec *spec = codec->spec;
11503 unsigned int mute;
11504
11505 if (force || !spec->sense_updated) {
864f92be 11506 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11507 spec->sense_updated = 1;
11508 }
11509 if (spec->jack_present) {
11510 /* mute internal speaker */
11511 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11512 HDA_AMP_MUTE, HDA_AMP_MUTE);
11513 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11514 HDA_AMP_MUTE, HDA_AMP_MUTE);
11515 } else {
11516 /* unmute internal speaker if necessary */
11517 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11518 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11519 HDA_AMP_MUTE, mute);
11520 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11521 HDA_AMP_MUTE, mute);
11522 }
11523}
11524
11525/* unsolicited event for HP jack sensing */
11526static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11527 unsigned int res)
11528{
11529 if ((res >> 26) != ALC_HP_EVENT)
11530 return;
11531 alc262_lenovo_3000_automute(codec, 1);
11532}
11533
8de56b7d
TI
11534static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11535 int dir, int idx, long *valp)
11536{
11537 int i, change = 0;
11538
11539 for (i = 0; i < 2; i++, valp++)
11540 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11541 HDA_AMP_MUTE,
11542 *valp ? 0 : HDA_AMP_MUTE);
11543 return change;
11544}
11545
834be88d
TI
11546/* bind hp and internal speaker mute (with plug check) */
11547static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11548 struct snd_ctl_elem_value *ucontrol)
11549{
11550 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11551 long *valp = ucontrol->value.integer.value;
11552 int change;
11553
8de56b7d
TI
11554 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11555 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11556 if (change)
11557 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11558 return change;
11559}
11560
11561static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11562 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11563 {
11564 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11565 .name = "Master Playback Switch",
5e26dfd0 11566 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11567 .info = snd_hda_mixer_amp_switch_info,
11568 .get = snd_hda_mixer_amp_switch_get,
11569 .put = alc262_fujitsu_master_sw_put,
11570 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11571 },
5b0cb1d8
JK
11572 {
11573 .iface = NID_MAPPING,
11574 .name = "Master Playback Switch",
11575 .private_value = 0x1b,
11576 },
834be88d
TI
11577 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11578 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11579 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11580 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11581 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
11582 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11583 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11584 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11585 { } /* end */
11586};
11587
0e31daf7
J
11588/* bind hp and internal speaker mute (with plug check) */
11589static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11590 struct snd_ctl_elem_value *ucontrol)
11591{
11592 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11593 long *valp = ucontrol->value.integer.value;
11594 int change;
11595
8de56b7d 11596 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11597 if (change)
11598 alc262_lenovo_3000_automute(codec, 0);
11599 return change;
11600}
11601
11602static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11603 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11604 {
11605 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11606 .name = "Master Playback Switch",
5e26dfd0 11607 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11608 .info = snd_hda_mixer_amp_switch_info,
11609 .get = snd_hda_mixer_amp_switch_get,
11610 .put = alc262_lenovo_3000_master_sw_put,
11611 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11612 },
11613 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11614 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11615 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11616 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11617 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11618 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11619 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11620 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11621 { } /* end */
11622};
11623
9f99a638
HM
11624static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11625 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11626 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11627 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11628 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11629 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11630 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11631 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11632 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11633 { } /* end */
11634};
11635
304dcaac
TI
11636/* additional init verbs for Benq laptops */
11637static struct hda_verb alc262_EAPD_verbs[] = {
11638 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11639 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11640 {}
11641};
11642
83c34218
KY
11643static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11644 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11645 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11646
11647 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11648 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11649 {}
11650};
11651
f651b50b
TD
11652/* Samsung Q1 Ultra Vista model setup */
11653static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11654 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11655 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11656 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11657 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11658 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 11659 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
11660 { } /* end */
11661};
11662
11663static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11664 /* output mixer */
11665 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11666 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11667 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11668 /* speaker */
11669 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11670 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11671 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11672 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11673 /* HP */
f651b50b 11674 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11675 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11676 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11677 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11678 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11679 /* internal mic */
11680 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11681 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11682 /* ADC, choose mic */
11683 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11684 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11685 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11686 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11687 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11688 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11689 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11690 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11691 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11692 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
11693 {}
11694};
11695
f651b50b
TD
11696/* mute/unmute internal speaker according to the hp jack and mute state */
11697static void alc262_ultra_automute(struct hda_codec *codec)
11698{
11699 struct alc_spec *spec = codec->spec;
11700 unsigned int mute;
f651b50b 11701
bb9f76cd
TI
11702 mute = 0;
11703 /* auto-mute only when HP is used as HP */
11704 if (!spec->cur_mux[0]) {
864f92be 11705 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
11706 if (spec->jack_present)
11707 mute = HDA_AMP_MUTE;
f651b50b 11708 }
bb9f76cd
TI
11709 /* mute/unmute internal speaker */
11710 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11711 HDA_AMP_MUTE, mute);
11712 /* mute/unmute HP */
11713 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11714 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
11715}
11716
11717/* unsolicited event for HP jack sensing */
11718static void alc262_ultra_unsol_event(struct hda_codec *codec,
11719 unsigned int res)
11720{
11721 if ((res >> 26) != ALC880_HP_EVENT)
11722 return;
11723 alc262_ultra_automute(codec);
11724}
11725
bb9f76cd
TI
11726static struct hda_input_mux alc262_ultra_capture_source = {
11727 .num_items = 2,
11728 .items = {
11729 { "Mic", 0x1 },
11730 { "Headphone", 0x7 },
11731 },
11732};
11733
11734static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11735 struct snd_ctl_elem_value *ucontrol)
11736{
11737 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11738 struct alc_spec *spec = codec->spec;
11739 int ret;
11740
54cbc9ab 11741 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
11742 if (!ret)
11743 return 0;
11744 /* reprogram the HP pin as mic or HP according to the input source */
11745 snd_hda_codec_write_cache(codec, 0x15, 0,
11746 AC_VERB_SET_PIN_WIDGET_CONTROL,
11747 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11748 alc262_ultra_automute(codec); /* mute/unmute HP */
11749 return ret;
11750}
11751
11752static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11753 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11754 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11755 {
11756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11757 .name = "Capture Source",
54cbc9ab
TI
11758 .info = alc_mux_enum_info,
11759 .get = alc_mux_enum_get,
bb9f76cd
TI
11760 .put = alc262_ultra_mux_enum_put,
11761 },
5b0cb1d8
JK
11762 {
11763 .iface = NID_MAPPING,
11764 .name = "Capture Source",
11765 .private_value = 0x15,
11766 },
bb9f76cd
TI
11767 { } /* end */
11768};
11769
c3fc1f50
TI
11770/* We use two mixers depending on the output pin; 0x16 is a mono output
11771 * and thus it's bound with a different mixer.
11772 * This function returns which mixer amp should be used.
11773 */
11774static int alc262_check_volbit(hda_nid_t nid)
11775{
11776 if (!nid)
11777 return 0;
11778 else if (nid == 0x16)
11779 return 2;
11780 else
11781 return 1;
11782}
11783
11784static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
11785 const char *pfx, int *vbits)
11786{
c3fc1f50
TI
11787 unsigned long val;
11788 int vbit;
11789
11790 vbit = alc262_check_volbit(nid);
11791 if (!vbit)
11792 return 0;
11793 if (*vbits & vbit) /* a volume control for this mixer already there */
11794 return 0;
11795 *vbits |= vbit;
c3fc1f50
TI
11796 if (vbit == 2)
11797 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11798 else
11799 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
0afe5f89 11800 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val);
c3fc1f50
TI
11801}
11802
11803static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
11804 const char *pfx)
11805{
c3fc1f50
TI
11806 unsigned long val;
11807
11808 if (!nid)
11809 return 0;
c3fc1f50
TI
11810 if (nid == 0x16)
11811 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11812 else
11813 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
0afe5f89 11814 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
c3fc1f50
TI
11815}
11816
df694daa 11817/* add playback controls from the parsed DAC table */
f12ab1e0
TI
11818static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11819 const struct auto_pin_cfg *cfg)
df694daa 11820{
c3fc1f50
TI
11821 const char *pfx;
11822 int vbits;
df694daa
KY
11823 int err;
11824
11825 spec->multiout.num_dacs = 1; /* only use one dac */
11826 spec->multiout.dac_nids = spec->private_dac_nids;
11827 spec->multiout.dac_nids[0] = 2;
11828
c3fc1f50
TI
11829 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
11830 pfx = "Master";
11831 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11832 pfx = "Speaker";
11833 else
11834 pfx = "Front";
11835 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx);
11836 if (err < 0)
11837 return err;
11838 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker");
11839 if (err < 0)
11840 return err;
11841 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone");
11842 if (err < 0)
11843 return err;
df694daa 11844
c3fc1f50
TI
11845 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
11846 alc262_check_volbit(cfg->speaker_pins[0]) |
11847 alc262_check_volbit(cfg->hp_pins[0]);
11848 if (vbits == 1 || vbits == 2)
11849 pfx = "Master"; /* only one mixer is used */
11850 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11851 pfx = "Speaker";
11852 else
11853 pfx = "Front";
11854 vbits = 0;
11855 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits);
11856 if (err < 0)
11857 return err;
11858 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker",
11859 &vbits);
11860 if (err < 0)
11861 return err;
11862 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone",
11863 &vbits);
11864 if (err < 0)
11865 return err;
f12ab1e0 11866 return 0;
df694daa
KY
11867}
11868
05f5f477 11869#define alc262_auto_create_input_ctls \
eaa9b3a7 11870 alc882_auto_create_input_ctls
df694daa
KY
11871
11872/*
11873 * generic initialization of ADC, input mixers and output mixers
11874 */
11875static struct hda_verb alc262_volume_init_verbs[] = {
11876 /*
11877 * Unmute ADC0-2 and set the default input to mic-in
11878 */
11879 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11880 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11881 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11882 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11883 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11884 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11885
cb53c626 11886 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 11887 * mixer widget
f12ab1e0
TI
11888 * Note: PASD motherboards uses the Line In 2 as the input for
11889 * front panel mic (mic 2)
df694daa
KY
11890 */
11891 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11892 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11893 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11894 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11895 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11896 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
11897
11898 /*
11899 * Set up output mixers (0x0c - 0x0f)
11900 */
11901 /* set vol=0 to output mixers */
11902 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11903 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11904 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 11905
df694daa
KY
11906 /* set up input amps for analog loopback */
11907 /* Amp Indices: DAC = 0, mixer = 1 */
11908 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11909 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11910 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11911 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11912 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11913 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11914
11915 /* FIXME: use matrix-type input source selection */
11916 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11917 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11918 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11919 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11920 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11921 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11922 /* Input mixer2 */
11923 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11924 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11925 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11926 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11927 /* Input mixer3 */
11928 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11929 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11930 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11931 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11932
11933 { }
11934};
11935
9c7f852e
TI
11936static struct hda_verb alc262_HP_BPC_init_verbs[] = {
11937 /*
11938 * Unmute ADC0-2 and set the default input to mic-in
11939 */
11940 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11941 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11942 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11943 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11944 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11945 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11946
cb53c626 11947 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11948 * mixer widget
f12ab1e0
TI
11949 * Note: PASD motherboards uses the Line In 2 as the input for
11950 * front panel mic (mic 2)
9c7f852e
TI
11951 */
11952 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11953 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11954 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11955 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11956 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11957 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11958 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11959 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 11960
9c7f852e
TI
11961 /*
11962 * Set up output mixers (0x0c - 0x0e)
11963 */
11964 /* set vol=0 to output mixers */
11965 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11966 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11967 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11968
11969 /* set up input amps for analog loopback */
11970 /* Amp Indices: DAC = 0, mixer = 1 */
11971 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11972 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11973 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11974 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11975 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11976 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11977
ce875f07 11978 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
11979 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11980 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11981
11982 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11983 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11984
11985 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11986 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11987
11988 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11989 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11990 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11991 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11992 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11993
0e4835c1 11994 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
11995 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11996 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 11997 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
11998 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11999 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12000
12001
12002 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12003 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12004 /* Input mixer1: only unmute Mic */
9c7f852e 12005 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12006 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12007 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12008 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12009 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12010 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12011 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12012 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12013 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12014 /* Input mixer2 */
12015 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12016 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12017 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12018 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12019 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12020 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12021 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12022 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12023 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12024 /* Input mixer3 */
12025 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12026 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12027 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12028 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12029 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12030 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12031 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12032 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12033 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12034
ce875f07
TI
12035 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12036
9c7f852e
TI
12037 { }
12038};
12039
cd7509a4
KY
12040static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12041 /*
12042 * Unmute ADC0-2 and set the default input to mic-in
12043 */
12044 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12045 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12046 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12047 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12048 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12049 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12050
cb53c626 12051 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12052 * mixer widget
12053 * Note: PASD motherboards uses the Line In 2 as the input for front
12054 * panel mic (mic 2)
12055 */
12056 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12057 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12058 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12059 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12060 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12061 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12062 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12063 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12064 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12065 /*
12066 * Set up output mixers (0x0c - 0x0e)
12067 */
12068 /* set vol=0 to output mixers */
12069 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12070 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12071 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12072
12073 /* set up input amps for analog loopback */
12074 /* Amp Indices: DAC = 0, mixer = 1 */
12075 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12076 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12077 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12078 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12079 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12080 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12081
12082
12083 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12084 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12085 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12086 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12087 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12088 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12089 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12090
12091 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12092 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12093
12094 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12095 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12096
12097 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12098 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12099 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12100 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12101 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12102 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12103
12104 /* FIXME: use matrix-type input source selection */
12105 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12106 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12107 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12108 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12109 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12110 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12111 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12112 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12113 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12114 /* Input mixer2 */
12115 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12116 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12117 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12118 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12119 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12120 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12121 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12122 /* Input mixer3 */
12123 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12124 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12125 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12126 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12127 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12128 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12129 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12130
ce875f07
TI
12131 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12132
cd7509a4
KY
12133 { }
12134};
12135
9f99a638
HM
12136static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12137
12138 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12139 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12140 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12141
12142 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12143 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12144 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12145 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12146
12147 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12148 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12149 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12150 {}
12151};
12152
12153
cb53c626
TI
12154#ifdef CONFIG_SND_HDA_POWER_SAVE
12155#define alc262_loopbacks alc880_loopbacks
12156#endif
12157
def319f9 12158/* pcm configuration: identical with ALC880 */
df694daa
KY
12159#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12160#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12161#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12162#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12163
12164/*
12165 * BIOS auto configuration
12166 */
12167static int alc262_parse_auto_config(struct hda_codec *codec)
12168{
12169 struct alc_spec *spec = codec->spec;
12170 int err;
12171 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12172
f12ab1e0
TI
12173 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12174 alc262_ignore);
12175 if (err < 0)
df694daa 12176 return err;
e64f14f4 12177 if (!spec->autocfg.line_outs) {
0852d7a6 12178 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12179 spec->multiout.max_channels = 2;
12180 spec->no_analog = 1;
12181 goto dig_only;
12182 }
df694daa 12183 return 0; /* can't find valid BIOS pin config */
e64f14f4 12184 }
f12ab1e0
TI
12185 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12186 if (err < 0)
12187 return err;
05f5f477 12188 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12189 if (err < 0)
df694daa
KY
12190 return err;
12191
12192 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12193
e64f14f4 12194 dig_only:
757899ac 12195 alc_auto_parse_digital(codec);
df694daa 12196
603c4019 12197 if (spec->kctls.list)
d88897ea 12198 add_mixer(spec, spec->kctls.list);
df694daa 12199
d88897ea 12200 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12201 spec->num_mux_defs = 1;
61b9b9b1 12202 spec->input_mux = &spec->private_imux[0];
df694daa 12203
776e184e
TI
12204 err = alc_auto_add_mic_boost(codec);
12205 if (err < 0)
12206 return err;
12207
6227cdce 12208 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12209
df694daa
KY
12210 return 1;
12211}
12212
12213#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12214#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12215#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12216#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12217
12218
12219/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12220static void alc262_auto_init(struct hda_codec *codec)
df694daa 12221{
f6c7e546 12222 struct alc_spec *spec = codec->spec;
df694daa
KY
12223 alc262_auto_init_multi_out(codec);
12224 alc262_auto_init_hp_out(codec);
12225 alc262_auto_init_analog_input(codec);
f511b01c 12226 alc262_auto_init_input_src(codec);
757899ac 12227 alc_auto_init_digital(codec);
f6c7e546 12228 if (spec->unsol_event)
7fb0d78f 12229 alc_inithook(codec);
df694daa
KY
12230}
12231
12232/*
12233 * configuration and preset
12234 */
f5fcc13c
TI
12235static const char *alc262_models[ALC262_MODEL_LAST] = {
12236 [ALC262_BASIC] = "basic",
12237 [ALC262_HIPPO] = "hippo",
12238 [ALC262_HIPPO_1] = "hippo_1",
12239 [ALC262_FUJITSU] = "fujitsu",
12240 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12241 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12242 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12243 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12244 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12245 [ALC262_BENQ_T31] = "benq-t31",
12246 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12247 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12248 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12249 [ALC262_ULTRA] = "ultra",
0e31daf7 12250 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12251 [ALC262_NEC] = "nec",
ba340e82 12252 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12253 [ALC262_AUTO] = "auto",
12254};
12255
12256static struct snd_pci_quirk alc262_cfg_tbl[] = {
12257 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12258 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12259 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12260 ALC262_HP_BPC),
12261 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12262 ALC262_HP_BPC),
53eff7e1
TI
12263 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12264 ALC262_HP_BPC),
cd7509a4 12265 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12266 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12267 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12268 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12269 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12270 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12271 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12272 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12273 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12274 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12275 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12276 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12277 ALC262_HP_TC_T5735),
8c427226 12278 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12279 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12280 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12281 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12282 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12283 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12284 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12285 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12286#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12287 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12288 ALC262_SONY_ASSAMD),
c5b5165c 12289#endif
36ca6e13 12290 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12291 ALC262_TOSHIBA_RX1),
80ffe869 12292 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12293 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12294 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12295 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12296 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12297 ALC262_ULTRA),
3e420e78 12298 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12299 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12300 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12301 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12302 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12303 {}
12304};
12305
12306static struct alc_config_preset alc262_presets[] = {
12307 [ALC262_BASIC] = {
12308 .mixers = { alc262_base_mixer },
12309 .init_verbs = { alc262_init_verbs },
12310 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12311 .dac_nids = alc262_dac_nids,
12312 .hp_nid = 0x03,
12313 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12314 .channel_mode = alc262_modes,
a3bcba38 12315 .input_mux = &alc262_capture_source,
df694daa 12316 },
ccc656ce 12317 [ALC262_HIPPO] = {
42171c17 12318 .mixers = { alc262_hippo_mixer },
6732bd0d 12319 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12320 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12321 .dac_nids = alc262_dac_nids,
12322 .hp_nid = 0x03,
12323 .dig_out_nid = ALC262_DIGOUT_NID,
12324 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12325 .channel_mode = alc262_modes,
12326 .input_mux = &alc262_capture_source,
12327 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12328 .setup = alc262_hippo_setup,
12329 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12330 },
12331 [ALC262_HIPPO_1] = {
12332 .mixers = { alc262_hippo1_mixer },
12333 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12334 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12335 .dac_nids = alc262_dac_nids,
12336 .hp_nid = 0x02,
12337 .dig_out_nid = ALC262_DIGOUT_NID,
12338 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12339 .channel_mode = alc262_modes,
12340 .input_mux = &alc262_capture_source,
42171c17 12341 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12342 .setup = alc262_hippo1_setup,
12343 .init_hook = alc262_hippo_automute,
ccc656ce 12344 },
834be88d
TI
12345 [ALC262_FUJITSU] = {
12346 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12347 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12348 alc262_fujitsu_unsol_verbs },
834be88d
TI
12349 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12350 .dac_nids = alc262_dac_nids,
12351 .hp_nid = 0x03,
12352 .dig_out_nid = ALC262_DIGOUT_NID,
12353 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12354 .channel_mode = alc262_modes,
12355 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12356 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12357 .init_hook = alc262_fujitsu_init_hook,
834be88d 12358 },
9c7f852e
TI
12359 [ALC262_HP_BPC] = {
12360 .mixers = { alc262_HP_BPC_mixer },
12361 .init_verbs = { alc262_HP_BPC_init_verbs },
12362 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12363 .dac_nids = alc262_dac_nids,
12364 .hp_nid = 0x03,
12365 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12366 .channel_mode = alc262_modes,
12367 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12368 .unsol_event = alc262_hp_bpc_unsol_event,
12369 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12370 },
cd7509a4
KY
12371 [ALC262_HP_BPC_D7000_WF] = {
12372 .mixers = { alc262_HP_BPC_WildWest_mixer },
12373 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12374 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12375 .dac_nids = alc262_dac_nids,
12376 .hp_nid = 0x03,
12377 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12378 .channel_mode = alc262_modes,
accbe498 12379 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12380 .unsol_event = alc262_hp_wildwest_unsol_event,
12381 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12382 },
cd7509a4
KY
12383 [ALC262_HP_BPC_D7000_WL] = {
12384 .mixers = { alc262_HP_BPC_WildWest_mixer,
12385 alc262_HP_BPC_WildWest_option_mixer },
12386 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12387 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12388 .dac_nids = alc262_dac_nids,
12389 .hp_nid = 0x03,
12390 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12391 .channel_mode = alc262_modes,
accbe498 12392 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12393 .unsol_event = alc262_hp_wildwest_unsol_event,
12394 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12395 },
66d2a9d6
KY
12396 [ALC262_HP_TC_T5735] = {
12397 .mixers = { alc262_hp_t5735_mixer },
12398 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12399 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12400 .dac_nids = alc262_dac_nids,
12401 .hp_nid = 0x03,
12402 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12403 .channel_mode = alc262_modes,
12404 .input_mux = &alc262_capture_source,
dc99be47 12405 .unsol_event = alc_sku_unsol_event,
4f5d1706 12406 .setup = alc262_hp_t5735_setup,
dc99be47 12407 .init_hook = alc_inithook,
8c427226
KY
12408 },
12409 [ALC262_HP_RP5700] = {
12410 .mixers = { alc262_hp_rp5700_mixer },
12411 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12412 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12413 .dac_nids = alc262_dac_nids,
12414 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12415 .channel_mode = alc262_modes,
12416 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12417 },
304dcaac
TI
12418 [ALC262_BENQ_ED8] = {
12419 .mixers = { alc262_base_mixer },
12420 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12421 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12422 .dac_nids = alc262_dac_nids,
12423 .hp_nid = 0x03,
12424 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12425 .channel_mode = alc262_modes,
12426 .input_mux = &alc262_capture_source,
f12ab1e0 12427 },
272a527c
KY
12428 [ALC262_SONY_ASSAMD] = {
12429 .mixers = { alc262_sony_mixer },
12430 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12431 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12432 .dac_nids = alc262_dac_nids,
12433 .hp_nid = 0x02,
12434 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12435 .channel_mode = alc262_modes,
12436 .input_mux = &alc262_capture_source,
12437 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12438 .setup = alc262_hippo_setup,
12439 .init_hook = alc262_hippo_automute,
83c34218
KY
12440 },
12441 [ALC262_BENQ_T31] = {
12442 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12443 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12444 alc_hp15_unsol_verbs },
83c34218
KY
12445 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12446 .dac_nids = alc262_dac_nids,
12447 .hp_nid = 0x03,
12448 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12449 .channel_mode = alc262_modes,
12450 .input_mux = &alc262_capture_source,
12451 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12452 .setup = alc262_hippo_setup,
12453 .init_hook = alc262_hippo_automute,
ea1fb29a 12454 },
f651b50b 12455 [ALC262_ULTRA] = {
f9e336f6
TI
12456 .mixers = { alc262_ultra_mixer },
12457 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12458 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12459 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12460 .dac_nids = alc262_dac_nids,
f651b50b
TD
12461 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12462 .channel_mode = alc262_modes,
12463 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12464 .adc_nids = alc262_adc_nids, /* ADC0 */
12465 .capsrc_nids = alc262_capsrc_nids,
12466 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12467 .unsol_event = alc262_ultra_unsol_event,
12468 .init_hook = alc262_ultra_automute,
12469 },
0e31daf7
J
12470 [ALC262_LENOVO_3000] = {
12471 .mixers = { alc262_lenovo_3000_mixer },
12472 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12473 alc262_lenovo_3000_unsol_verbs,
12474 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12475 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12476 .dac_nids = alc262_dac_nids,
12477 .hp_nid = 0x03,
12478 .dig_out_nid = ALC262_DIGOUT_NID,
12479 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12480 .channel_mode = alc262_modes,
12481 .input_mux = &alc262_fujitsu_capture_source,
12482 .unsol_event = alc262_lenovo_3000_unsol_event,
12483 },
e8f9ae2a
PT
12484 [ALC262_NEC] = {
12485 .mixers = { alc262_nec_mixer },
12486 .init_verbs = { alc262_nec_verbs },
12487 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12488 .dac_nids = alc262_dac_nids,
12489 .hp_nid = 0x03,
12490 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12491 .channel_mode = alc262_modes,
12492 .input_mux = &alc262_capture_source,
12493 },
4e555fe5
KY
12494 [ALC262_TOSHIBA_S06] = {
12495 .mixers = { alc262_toshiba_s06_mixer },
12496 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12497 alc262_eapd_verbs },
12498 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12499 .capsrc_nids = alc262_dmic_capsrc_nids,
12500 .dac_nids = alc262_dac_nids,
12501 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12502 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12503 .dig_out_nid = ALC262_DIGOUT_NID,
12504 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12505 .channel_mode = alc262_modes,
4f5d1706
TI
12506 .unsol_event = alc_sku_unsol_event,
12507 .setup = alc262_toshiba_s06_setup,
12508 .init_hook = alc_inithook,
4e555fe5 12509 },
9f99a638
HM
12510 [ALC262_TOSHIBA_RX1] = {
12511 .mixers = { alc262_toshiba_rx1_mixer },
12512 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12513 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12514 .dac_nids = alc262_dac_nids,
12515 .hp_nid = 0x03,
12516 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12517 .channel_mode = alc262_modes,
12518 .input_mux = &alc262_capture_source,
12519 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12520 .setup = alc262_hippo_setup,
12521 .init_hook = alc262_hippo_automute,
9f99a638 12522 },
ba340e82
TV
12523 [ALC262_TYAN] = {
12524 .mixers = { alc262_tyan_mixer },
12525 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12526 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12527 .dac_nids = alc262_dac_nids,
12528 .hp_nid = 0x02,
12529 .dig_out_nid = ALC262_DIGOUT_NID,
12530 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12531 .channel_mode = alc262_modes,
12532 .input_mux = &alc262_capture_source,
a9fd4f3f 12533 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12534 .setup = alc262_tyan_setup,
12535 .init_hook = alc_automute_amp,
ba340e82 12536 },
df694daa
KY
12537};
12538
12539static int patch_alc262(struct hda_codec *codec)
12540{
12541 struct alc_spec *spec;
12542 int board_config;
12543 int err;
12544
dc041e0b 12545 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12546 if (spec == NULL)
12547 return -ENOMEM;
12548
12549 codec->spec = spec;
12550#if 0
f12ab1e0
TI
12551 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12552 * under-run
12553 */
df694daa
KY
12554 {
12555 int tmp;
12556 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12557 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12558 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12559 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12560 }
12561#endif
da00c244 12562 alc_auto_parse_customize_define(codec);
df694daa 12563
2c3bf9ab
TI
12564 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12565
f5fcc13c
TI
12566 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12567 alc262_models,
12568 alc262_cfg_tbl);
cd7509a4 12569
f5fcc13c 12570 if (board_config < 0) {
9a11f1aa
TI
12571 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12572 codec->chip_name);
df694daa
KY
12573 board_config = ALC262_AUTO;
12574 }
12575
12576 if (board_config == ALC262_AUTO) {
12577 /* automatic parse from the BIOS config */
12578 err = alc262_parse_auto_config(codec);
12579 if (err < 0) {
12580 alc_free(codec);
12581 return err;
f12ab1e0 12582 } else if (!err) {
9c7f852e
TI
12583 printk(KERN_INFO
12584 "hda_codec: Cannot set up configuration "
12585 "from BIOS. Using base mode...\n");
df694daa
KY
12586 board_config = ALC262_BASIC;
12587 }
12588 }
12589
dc1eae25 12590 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12591 err = snd_hda_attach_beep_device(codec, 0x1);
12592 if (err < 0) {
12593 alc_free(codec);
12594 return err;
12595 }
680cd536
KK
12596 }
12597
df694daa 12598 if (board_config != ALC262_AUTO)
e9c364c0 12599 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12600
df694daa
KY
12601 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12602 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12603
df694daa
KY
12604 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12605 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12606
f12ab1e0 12607 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12608 int i;
12609 /* check whether the digital-mic has to be supported */
12610 for (i = 0; i < spec->input_mux->num_items; i++) {
12611 if (spec->input_mux->items[i].index >= 9)
12612 break;
12613 }
12614 if (i < spec->input_mux->num_items) {
12615 /* use only ADC0 */
12616 spec->adc_nids = alc262_dmic_adc_nids;
12617 spec->num_adc_nids = 1;
12618 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12619 } else {
8c927b4a
TI
12620 /* all analog inputs */
12621 /* check whether NID 0x07 is valid */
12622 unsigned int wcap = get_wcaps(codec, 0x07);
12623
12624 /* get type */
a22d543a 12625 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12626 if (wcap != AC_WID_AUD_IN) {
12627 spec->adc_nids = alc262_adc_nids_alt;
12628 spec->num_adc_nids =
12629 ARRAY_SIZE(alc262_adc_nids_alt);
12630 spec->capsrc_nids = alc262_capsrc_nids_alt;
12631 } else {
12632 spec->adc_nids = alc262_adc_nids;
12633 spec->num_adc_nids =
12634 ARRAY_SIZE(alc262_adc_nids);
12635 spec->capsrc_nids = alc262_capsrc_nids;
12636 }
df694daa
KY
12637 }
12638 }
e64f14f4 12639 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12640 set_capture_mixer(codec);
dc1eae25 12641 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 12642 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12643
2134ea4f
TI
12644 spec->vmaster_nid = 0x0c;
12645
df694daa
KY
12646 codec->patch_ops = alc_patch_ops;
12647 if (board_config == ALC262_AUTO)
ae6b813a 12648 spec->init_hook = alc262_auto_init;
cb53c626
TI
12649#ifdef CONFIG_SND_HDA_POWER_SAVE
12650 if (!spec->loopback.amplist)
12651 spec->loopback.amplist = alc262_loopbacks;
12652#endif
ea1fb29a 12653
df694daa
KY
12654 return 0;
12655}
12656
a361d84b
KY
12657/*
12658 * ALC268 channel source setting (2 channel)
12659 */
12660#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12661#define alc268_modes alc260_modes
ea1fb29a 12662
a361d84b
KY
12663static hda_nid_t alc268_dac_nids[2] = {
12664 /* front, hp */
12665 0x02, 0x03
12666};
12667
12668static hda_nid_t alc268_adc_nids[2] = {
12669 /* ADC0-1 */
12670 0x08, 0x07
12671};
12672
12673static hda_nid_t alc268_adc_nids_alt[1] = {
12674 /* ADC0 */
12675 0x08
12676};
12677
e1406348
TI
12678static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12679
a361d84b
KY
12680static struct snd_kcontrol_new alc268_base_mixer[] = {
12681 /* output mixer control */
12682 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12683 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12684 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12685 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
12686 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12687 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12688 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
12689 { }
12690};
12691
42171c17
TI
12692static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12693 /* output mixer control */
12694 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12695 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12696 ALC262_HIPPO_MASTER_SWITCH,
12697 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12698 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12699 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12700 { }
12701};
12702
aef9d318
TI
12703/* bind Beep switches of both NID 0x0f and 0x10 */
12704static struct hda_bind_ctls alc268_bind_beep_sw = {
12705 .ops = &snd_hda_bind_sw,
12706 .values = {
12707 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12708 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12709 0
12710 },
12711};
12712
12713static struct snd_kcontrol_new alc268_beep_mixer[] = {
12714 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12715 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12716 { }
12717};
12718
d1a991a6
KY
12719static struct hda_verb alc268_eapd_verbs[] = {
12720 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12721 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12722 { }
12723};
12724
d273809e 12725/* Toshiba specific */
d273809e
TI
12726static struct hda_verb alc268_toshiba_verbs[] = {
12727 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12728 { } /* end */
12729};
12730
12731/* Acer specific */
889c4395 12732/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
12733static struct hda_bind_ctls alc268_acer_bind_master_vol = {
12734 .ops = &snd_hda_bind_vol,
12735 .values = {
12736 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12737 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12738 0
12739 },
12740};
12741
889c4395
TI
12742/* mute/unmute internal speaker according to the hp jack and mute state */
12743static void alc268_acer_automute(struct hda_codec *codec, int force)
12744{
12745 struct alc_spec *spec = codec->spec;
12746 unsigned int mute;
12747
12748 if (force || !spec->sense_updated) {
864f92be 12749 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
12750 spec->sense_updated = 1;
12751 }
12752 if (spec->jack_present)
12753 mute = HDA_AMP_MUTE; /* mute internal speaker */
12754 else /* unmute internal speaker if necessary */
12755 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
12756 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12757 HDA_AMP_MUTE, mute);
12758}
12759
12760
12761/* bind hp and internal speaker mute (with plug check) */
12762static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
12763 struct snd_ctl_elem_value *ucontrol)
12764{
12765 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12766 long *valp = ucontrol->value.integer.value;
12767 int change;
12768
8de56b7d 12769 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
12770 if (change)
12771 alc268_acer_automute(codec, 0);
12772 return change;
12773}
d273809e 12774
8ef355da
KY
12775static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12776 /* output mixer control */
12777 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12778 {
12779 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12780 .name = "Master Playback Switch",
5e26dfd0 12781 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
12782 .info = snd_hda_mixer_amp_switch_info,
12783 .get = snd_hda_mixer_amp_switch_get,
12784 .put = alc268_acer_master_sw_put,
12785 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12786 },
12787 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12788 { }
12789};
12790
d273809e
TI
12791static struct snd_kcontrol_new alc268_acer_mixer[] = {
12792 /* output mixer control */
12793 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12794 {
12795 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12796 .name = "Master Playback Switch",
5e26dfd0 12797 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
12798 .info = snd_hda_mixer_amp_switch_info,
12799 .get = snd_hda_mixer_amp_switch_get,
12800 .put = alc268_acer_master_sw_put,
12801 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12802 },
33bf17ab
TI
12803 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12804 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12805 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
12806 { }
12807};
12808
c238b4f4
TI
12809static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12810 /* output mixer control */
12811 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12812 {
12813 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12814 .name = "Master Playback Switch",
5e26dfd0 12815 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
12816 .info = snd_hda_mixer_amp_switch_info,
12817 .get = snd_hda_mixer_amp_switch_get,
12818 .put = alc268_acer_master_sw_put,
12819 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12820 },
12821 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12822 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12823 { }
12824};
12825
8ef355da
KY
12826static struct hda_verb alc268_acer_aspire_one_verbs[] = {
12827 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12828 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12829 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12830 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12831 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12832 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12833 { }
12834};
12835
d273809e 12836static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
12837 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12838 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
12839 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12840 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
12841 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12842 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
12843 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12844 { }
12845};
12846
12847/* unsolicited event for HP jack sensing */
42171c17 12848#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
12849#define alc268_toshiba_setup alc262_hippo_setup
12850#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
12851
12852static void alc268_acer_unsol_event(struct hda_codec *codec,
12853 unsigned int res)
12854{
889c4395 12855 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
12856 return;
12857 alc268_acer_automute(codec, 1);
12858}
12859
889c4395
TI
12860static void alc268_acer_init_hook(struct hda_codec *codec)
12861{
12862 alc268_acer_automute(codec, 1);
12863}
12864
8ef355da
KY
12865/* toggle speaker-output according to the hp-jack state */
12866static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
12867{
12868 unsigned int present;
12869 unsigned char bits;
12870
864f92be 12871 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 12872 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 12873 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 12874 HDA_AMP_MUTE, bits);
8ef355da 12875 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 12876 HDA_AMP_MUTE, bits);
8ef355da
KY
12877}
12878
8ef355da
KY
12879static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
12880 unsigned int res)
12881{
4f5d1706
TI
12882 switch (res >> 26) {
12883 case ALC880_HP_EVENT:
8ef355da 12884 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
12885 break;
12886 case ALC880_MIC_EVENT:
12887 alc_mic_automute(codec);
12888 break;
12889 }
12890}
12891
12892static void alc268_acer_lc_setup(struct hda_codec *codec)
12893{
12894 struct alc_spec *spec = codec->spec;
12895 spec->ext_mic.pin = 0x18;
12896 spec->ext_mic.mux_idx = 0;
12897 spec->int_mic.pin = 0x12;
12898 spec->int_mic.mux_idx = 6;
12899 spec->auto_mic = 1;
8ef355da
KY
12900}
12901
12902static void alc268_acer_lc_init_hook(struct hda_codec *codec)
12903{
12904 alc268_aspire_one_speaker_automute(codec);
4f5d1706 12905 alc_mic_automute(codec);
8ef355da
KY
12906}
12907
3866f0b0
TI
12908static struct snd_kcontrol_new alc268_dell_mixer[] = {
12909 /* output mixer control */
12910 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12911 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12912 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12913 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12914 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12915 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12916 { }
12917};
12918
12919static struct hda_verb alc268_dell_verbs[] = {
12920 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12921 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12922 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 12923 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
12924 { }
12925};
12926
12927/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 12928static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 12929{
a9fd4f3f 12930 struct alc_spec *spec = codec->spec;
3866f0b0 12931
a9fd4f3f
TI
12932 spec->autocfg.hp_pins[0] = 0x15;
12933 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12934 spec->ext_mic.pin = 0x18;
12935 spec->ext_mic.mux_idx = 0;
12936 spec->int_mic.pin = 0x19;
12937 spec->int_mic.mux_idx = 1;
12938 spec->auto_mic = 1;
3866f0b0
TI
12939}
12940
eb5a6621
HRK
12941static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12942 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12943 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12944 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12945 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12946 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12947 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12948 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12949 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12950 { }
12951};
12952
12953static struct hda_verb alc267_quanta_il1_verbs[] = {
12954 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12955 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12956 { }
12957};
12958
4f5d1706 12959static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 12960{
a9fd4f3f 12961 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
12962 spec->autocfg.hp_pins[0] = 0x15;
12963 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12964 spec->ext_mic.pin = 0x18;
12965 spec->ext_mic.mux_idx = 0;
12966 spec->int_mic.pin = 0x19;
12967 spec->int_mic.mux_idx = 1;
12968 spec->auto_mic = 1;
eb5a6621
HRK
12969}
12970
a361d84b
KY
12971/*
12972 * generic initialization of ADC, input mixers and output mixers
12973 */
12974static struct hda_verb alc268_base_init_verbs[] = {
12975 /* Unmute DAC0-1 and set vol = 0 */
12976 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 12977 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
12978
12979 /*
12980 * Set up output mixers (0x0c - 0x0e)
12981 */
12982 /* set vol=0 to output mixers */
12983 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
12984 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12985
12986 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12987 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12988
12989 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12990 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12991 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12992 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12993 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12994 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12995 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12996 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12997
12998 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12999 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13000 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13001 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13002 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13003
13004 /* set PCBEEP vol = 0, mute connections */
13005 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13006 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13007 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13008
a9b3aa8a 13009 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13010
a9b3aa8a
JZ
13011 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13012 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13013 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13014 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13015
a361d84b
KY
13016 { }
13017};
13018
13019/*
13020 * generic initialization of ADC, input mixers and output mixers
13021 */
13022static struct hda_verb alc268_volume_init_verbs[] = {
13023 /* set output DAC */
4cfb91c6
TI
13024 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13025 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13026
13027 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13028 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13029 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13030 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13031 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13032
a361d84b 13033 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13034 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13035 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13036
13037 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13038 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13039
aef9d318
TI
13040 /* set PCBEEP vol = 0, mute connections */
13041 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13042 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13043 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13044
13045 { }
13046};
13047
fdbc6626
TI
13048static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13049 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13050 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13051 { } /* end */
13052};
13053
a361d84b
KY
13054static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13055 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13056 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13057 _DEFINE_CAPSRC(1),
a361d84b
KY
13058 { } /* end */
13059};
13060
13061static struct snd_kcontrol_new alc268_capture_mixer[] = {
13062 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13063 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13064 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13065 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13066 _DEFINE_CAPSRC(2),
a361d84b
KY
13067 { } /* end */
13068};
13069
13070static struct hda_input_mux alc268_capture_source = {
13071 .num_items = 4,
13072 .items = {
13073 { "Mic", 0x0 },
13074 { "Front Mic", 0x1 },
13075 { "Line", 0x2 },
13076 { "CD", 0x3 },
13077 },
13078};
13079
0ccb541c 13080static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13081 .num_items = 3,
13082 .items = {
13083 { "Mic", 0x0 },
13084 { "Internal Mic", 0x1 },
13085 { "Line", 0x2 },
13086 },
13087};
13088
13089static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13090 .num_items = 3,
13091 .items = {
13092 { "Mic", 0x0 },
13093 { "Internal Mic", 0x6 },
13094 { "Line", 0x2 },
13095 },
13096};
13097
86c53bd2
JW
13098#ifdef CONFIG_SND_DEBUG
13099static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13100 /* Volume widgets */
13101 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13102 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13103 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13104 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13105 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13106 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13107 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13108 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13109 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13110 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13111 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13112 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13113 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13114 /* The below appears problematic on some hardwares */
13115 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13116 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13117 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13118 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13119 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13120
13121 /* Modes for retasking pin widgets */
13122 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13123 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13124 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13125 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13126
13127 /* Controls for GPIO pins, assuming they are configured as outputs */
13128 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13129 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13130 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13131 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13132
13133 /* Switches to allow the digital SPDIF output pin to be enabled.
13134 * The ALC268 does not have an SPDIF input.
13135 */
13136 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13137
13138 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13139 * this output to turn on an external amplifier.
13140 */
13141 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13142 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13143
13144 { } /* end */
13145};
13146#endif
13147
a361d84b
KY
13148/* create input playback/capture controls for the given pin */
13149static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13150 const char *ctlname, int idx)
13151{
3f3b7c1a 13152 hda_nid_t dac;
a361d84b
KY
13153 int err;
13154
3f3b7c1a
TI
13155 switch (nid) {
13156 case 0x14:
13157 case 0x16:
13158 dac = 0x02;
13159 break;
13160 case 0x15:
b08b1637
TI
13161 case 0x1a: /* ALC259/269 only */
13162 case 0x1b: /* ALC259/269 only */
531d8791 13163 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13164 dac = 0x03;
13165 break;
13166 default:
13167 return 0;
13168 }
13169 if (spec->multiout.dac_nids[0] != dac &&
13170 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13171 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13172 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13173 HDA_OUTPUT));
13174 if (err < 0)
13175 return err;
3f3b7c1a
TI
13176 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13177 }
13178
3f3b7c1a 13179 if (nid != 0x16)
0afe5f89 13180 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13181 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13182 else /* mono */
0afe5f89 13183 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13184 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13185 if (err < 0)
13186 return err;
13187 return 0;
13188}
13189
13190/* add playback controls from the parsed DAC table */
13191static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13192 const struct auto_pin_cfg *cfg)
13193{
13194 hda_nid_t nid;
13195 int err;
13196
a361d84b 13197 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13198
13199 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13200 if (nid) {
13201 const char *name;
13202 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13203 name = "Speaker";
13204 else
13205 name = "Front";
13206 err = alc268_new_analog_output(spec, nid, name, 0);
13207 if (err < 0)
13208 return err;
13209 }
a361d84b
KY
13210
13211 nid = cfg->speaker_pins[0];
13212 if (nid == 0x1d) {
0afe5f89 13213 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13214 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13215 if (err < 0)
13216 return err;
3f3b7c1a
TI
13217 } else {
13218 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13219 if (err < 0)
13220 return err;
a361d84b
KY
13221 }
13222 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13223 if (nid) {
13224 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13225 if (err < 0)
13226 return err;
13227 }
a361d84b
KY
13228
13229 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13230 if (nid == 0x16) {
0afe5f89 13231 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13232 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13233 if (err < 0)
13234 return err;
13235 }
ea1fb29a 13236 return 0;
a361d84b
KY
13237}
13238
13239/* create playback/capture controls for input pins */
05f5f477 13240static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13241 const struct auto_pin_cfg *cfg)
13242{
05f5f477 13243 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13244}
13245
e9af4f36
TI
13246static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13247 hda_nid_t nid, int pin_type)
13248{
13249 int idx;
13250
13251 alc_set_pin_output(codec, nid, pin_type);
13252 if (nid == 0x14 || nid == 0x16)
13253 idx = 0;
13254 else
13255 idx = 1;
13256 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13257}
13258
13259static void alc268_auto_init_multi_out(struct hda_codec *codec)
13260{
13261 struct alc_spec *spec = codec->spec;
13262 hda_nid_t nid = spec->autocfg.line_out_pins[0];
13263 if (nid) {
13264 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13265 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13266 }
13267}
13268
13269static void alc268_auto_init_hp_out(struct hda_codec *codec)
13270{
13271 struct alc_spec *spec = codec->spec;
13272 hda_nid_t pin;
13273
13274 pin = spec->autocfg.hp_pins[0];
13275 if (pin)
13276 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13277 pin = spec->autocfg.speaker_pins[0];
13278 if (pin)
13279 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13280}
13281
a361d84b
KY
13282static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13283{
13284 struct alc_spec *spec = codec->spec;
13285 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13286 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13287 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13288 unsigned int dac_vol1, dac_vol2;
13289
e9af4f36 13290 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13291 snd_hda_codec_write(codec, speaker_nid, 0,
13292 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13293 /* mute mixer inputs from 0x1d */
a361d84b
KY
13294 snd_hda_codec_write(codec, 0x0f, 0,
13295 AC_VERB_SET_AMP_GAIN_MUTE,
13296 AMP_IN_UNMUTE(1));
13297 snd_hda_codec_write(codec, 0x10, 0,
13298 AC_VERB_SET_AMP_GAIN_MUTE,
13299 AMP_IN_UNMUTE(1));
13300 } else {
e9af4f36 13301 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13302 snd_hda_codec_write(codec, 0x0f, 0,
13303 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13304 snd_hda_codec_write(codec, 0x10, 0,
13305 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13306 }
13307
13308 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13309 if (line_nid == 0x14)
a361d84b
KY
13310 dac_vol2 = AMP_OUT_ZERO;
13311 else if (line_nid == 0x15)
13312 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13313 if (hp_nid == 0x14)
a361d84b
KY
13314 dac_vol2 = AMP_OUT_ZERO;
13315 else if (hp_nid == 0x15)
13316 dac_vol1 = AMP_OUT_ZERO;
13317 if (line_nid != 0x16 || hp_nid != 0x16 ||
13318 spec->autocfg.line_out_pins[1] != 0x16 ||
13319 spec->autocfg.line_out_pins[2] != 0x16)
13320 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13321
13322 snd_hda_codec_write(codec, 0x02, 0,
13323 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13324 snd_hda_codec_write(codec, 0x03, 0,
13325 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13326}
13327
def319f9 13328/* pcm configuration: identical with ALC880 */
a361d84b
KY
13329#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13330#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13331#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13332#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13333
13334/*
13335 * BIOS auto configuration
13336 */
13337static int alc268_parse_auto_config(struct hda_codec *codec)
13338{
13339 struct alc_spec *spec = codec->spec;
13340 int err;
13341 static hda_nid_t alc268_ignore[] = { 0 };
13342
13343 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13344 alc268_ignore);
13345 if (err < 0)
13346 return err;
7e0e44d4
TI
13347 if (!spec->autocfg.line_outs) {
13348 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13349 spec->multiout.max_channels = 2;
13350 spec->no_analog = 1;
13351 goto dig_only;
13352 }
a361d84b 13353 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13354 }
a361d84b
KY
13355 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13356 if (err < 0)
13357 return err;
05f5f477 13358 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13359 if (err < 0)
13360 return err;
13361
13362 spec->multiout.max_channels = 2;
13363
7e0e44d4 13364 dig_only:
a361d84b 13365 /* digital only support output */
757899ac 13366 alc_auto_parse_digital(codec);
603c4019 13367 if (spec->kctls.list)
d88897ea 13368 add_mixer(spec, spec->kctls.list);
a361d84b 13369
892981ff 13370 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13371 add_mixer(spec, alc268_beep_mixer);
aef9d318 13372
d88897ea 13373 add_verb(spec, alc268_volume_init_verbs);
5908589f 13374 spec->num_mux_defs = 2;
61b9b9b1 13375 spec->input_mux = &spec->private_imux[0];
a361d84b 13376
776e184e
TI
13377 err = alc_auto_add_mic_boost(codec);
13378 if (err < 0)
13379 return err;
13380
6227cdce 13381 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13382
a361d84b
KY
13383 return 1;
13384}
13385
a361d84b
KY
13386#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13387
13388/* init callback for auto-configuration model -- overriding the default init */
13389static void alc268_auto_init(struct hda_codec *codec)
13390{
f6c7e546 13391 struct alc_spec *spec = codec->spec;
a361d84b
KY
13392 alc268_auto_init_multi_out(codec);
13393 alc268_auto_init_hp_out(codec);
13394 alc268_auto_init_mono_speaker_out(codec);
13395 alc268_auto_init_analog_input(codec);
757899ac 13396 alc_auto_init_digital(codec);
f6c7e546 13397 if (spec->unsol_event)
7fb0d78f 13398 alc_inithook(codec);
a361d84b
KY
13399}
13400
13401/*
13402 * configuration and preset
13403 */
13404static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13405 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13406 [ALC268_3ST] = "3stack",
983f8ae4 13407 [ALC268_TOSHIBA] = "toshiba",
d273809e 13408 [ALC268_ACER] = "acer",
c238b4f4 13409 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13410 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13411 [ALC268_DELL] = "dell",
f12462c5 13412 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13413#ifdef CONFIG_SND_DEBUG
13414 [ALC268_TEST] = "test",
13415#endif
a361d84b
KY
13416 [ALC268_AUTO] = "auto",
13417};
13418
13419static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13420 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13421 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13422 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13423 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13424 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13425 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13426 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13427 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13428 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13429 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13430 /* almost compatible with toshiba but with optional digital outs;
13431 * auto-probing seems working fine
13432 */
8871e5b9 13433 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13434 ALC268_AUTO),
a361d84b 13435 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13436 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13437 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13438 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13439 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
8871e5b9 13440 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
a361d84b
KY
13441 {}
13442};
13443
3abf2f36
TI
13444/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13445static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13446 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13447 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13448 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13449 ALC268_TOSHIBA),
13450 {}
13451};
13452
a361d84b 13453static struct alc_config_preset alc268_presets[] = {
eb5a6621 13454 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13455 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13456 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13457 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13458 alc267_quanta_il1_verbs },
13459 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13460 .dac_nids = alc268_dac_nids,
13461 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13462 .adc_nids = alc268_adc_nids_alt,
13463 .hp_nid = 0x03,
13464 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13465 .channel_mode = alc268_modes,
4f5d1706
TI
13466 .unsol_event = alc_sku_unsol_event,
13467 .setup = alc267_quanta_il1_setup,
13468 .init_hook = alc_inithook,
eb5a6621 13469 },
a361d84b 13470 [ALC268_3ST] = {
aef9d318
TI
13471 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13472 alc268_beep_mixer },
a361d84b
KY
13473 .init_verbs = { alc268_base_init_verbs },
13474 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13475 .dac_nids = alc268_dac_nids,
13476 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13477 .adc_nids = alc268_adc_nids_alt,
e1406348 13478 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13479 .hp_nid = 0x03,
13480 .dig_out_nid = ALC268_DIGOUT_NID,
13481 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13482 .channel_mode = alc268_modes,
13483 .input_mux = &alc268_capture_source,
13484 },
d1a991a6 13485 [ALC268_TOSHIBA] = {
42171c17 13486 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13487 alc268_beep_mixer },
d273809e
TI
13488 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13489 alc268_toshiba_verbs },
d1a991a6
KY
13490 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13491 .dac_nids = alc268_dac_nids,
13492 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13493 .adc_nids = alc268_adc_nids_alt,
e1406348 13494 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13495 .hp_nid = 0x03,
13496 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13497 .channel_mode = alc268_modes,
13498 .input_mux = &alc268_capture_source,
d273809e 13499 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13500 .setup = alc268_toshiba_setup,
13501 .init_hook = alc268_toshiba_automute,
d273809e
TI
13502 },
13503 [ALC268_ACER] = {
432fd133 13504 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13505 alc268_beep_mixer },
d273809e
TI
13506 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13507 alc268_acer_verbs },
13508 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13509 .dac_nids = alc268_dac_nids,
13510 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13511 .adc_nids = alc268_adc_nids_alt,
e1406348 13512 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13513 .hp_nid = 0x02,
13514 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13515 .channel_mode = alc268_modes,
0ccb541c 13516 .input_mux = &alc268_acer_capture_source,
d273809e 13517 .unsol_event = alc268_acer_unsol_event,
889c4395 13518 .init_hook = alc268_acer_init_hook,
d1a991a6 13519 },
c238b4f4
TI
13520 [ALC268_ACER_DMIC] = {
13521 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13522 alc268_beep_mixer },
13523 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13524 alc268_acer_verbs },
13525 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13526 .dac_nids = alc268_dac_nids,
13527 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13528 .adc_nids = alc268_adc_nids_alt,
13529 .capsrc_nids = alc268_capsrc_nids,
13530 .hp_nid = 0x02,
13531 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13532 .channel_mode = alc268_modes,
13533 .input_mux = &alc268_acer_dmic_capture_source,
13534 .unsol_event = alc268_acer_unsol_event,
13535 .init_hook = alc268_acer_init_hook,
13536 },
8ef355da
KY
13537 [ALC268_ACER_ASPIRE_ONE] = {
13538 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13539 alc268_beep_mixer,
fdbc6626 13540 alc268_capture_nosrc_mixer },
8ef355da
KY
13541 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13542 alc268_acer_aspire_one_verbs },
13543 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13544 .dac_nids = alc268_dac_nids,
13545 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13546 .adc_nids = alc268_adc_nids_alt,
13547 .capsrc_nids = alc268_capsrc_nids,
13548 .hp_nid = 0x03,
13549 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13550 .channel_mode = alc268_modes,
8ef355da 13551 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13552 .setup = alc268_acer_lc_setup,
8ef355da
KY
13553 .init_hook = alc268_acer_lc_init_hook,
13554 },
3866f0b0 13555 [ALC268_DELL] = {
fdbc6626
TI
13556 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13557 alc268_capture_nosrc_mixer },
3866f0b0
TI
13558 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13559 alc268_dell_verbs },
13560 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13561 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13562 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13563 .adc_nids = alc268_adc_nids_alt,
13564 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13565 .hp_nid = 0x02,
13566 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13567 .channel_mode = alc268_modes,
a9fd4f3f 13568 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13569 .setup = alc268_dell_setup,
13570 .init_hook = alc_inithook,
3866f0b0 13571 },
f12462c5 13572 [ALC268_ZEPTO] = {
aef9d318
TI
13573 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13574 alc268_beep_mixer },
f12462c5
MT
13575 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13576 alc268_toshiba_verbs },
13577 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13578 .dac_nids = alc268_dac_nids,
13579 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13580 .adc_nids = alc268_adc_nids_alt,
e1406348 13581 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13582 .hp_nid = 0x03,
13583 .dig_out_nid = ALC268_DIGOUT_NID,
13584 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13585 .channel_mode = alc268_modes,
13586 .input_mux = &alc268_capture_source,
4f5d1706
TI
13587 .setup = alc268_toshiba_setup,
13588 .init_hook = alc268_toshiba_automute,
f12462c5 13589 },
86c53bd2
JW
13590#ifdef CONFIG_SND_DEBUG
13591 [ALC268_TEST] = {
13592 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13593 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13594 alc268_volume_init_verbs },
13595 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13596 .dac_nids = alc268_dac_nids,
13597 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13598 .adc_nids = alc268_adc_nids_alt,
e1406348 13599 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13600 .hp_nid = 0x03,
13601 .dig_out_nid = ALC268_DIGOUT_NID,
13602 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13603 .channel_mode = alc268_modes,
13604 .input_mux = &alc268_capture_source,
13605 },
13606#endif
a361d84b
KY
13607};
13608
13609static int patch_alc268(struct hda_codec *codec)
13610{
13611 struct alc_spec *spec;
13612 int board_config;
22971e3a 13613 int i, has_beep, err;
a361d84b 13614
ef86f581 13615 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13616 if (spec == NULL)
13617 return -ENOMEM;
13618
13619 codec->spec = spec;
13620
13621 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13622 alc268_models,
13623 alc268_cfg_tbl);
13624
3abf2f36
TI
13625 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13626 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13627 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13628
a361d84b 13629 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13630 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13631 codec->chip_name);
a361d84b
KY
13632 board_config = ALC268_AUTO;
13633 }
13634
13635 if (board_config == ALC268_AUTO) {
13636 /* automatic parse from the BIOS config */
13637 err = alc268_parse_auto_config(codec);
13638 if (err < 0) {
13639 alc_free(codec);
13640 return err;
13641 } else if (!err) {
13642 printk(KERN_INFO
13643 "hda_codec: Cannot set up configuration "
13644 "from BIOS. Using base mode...\n");
13645 board_config = ALC268_3ST;
13646 }
13647 }
13648
13649 if (board_config != ALC268_AUTO)
e9c364c0 13650 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 13651
a361d84b
KY
13652 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13653 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 13654 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 13655
a361d84b
KY
13656 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13657
22971e3a
TI
13658 has_beep = 0;
13659 for (i = 0; i < spec->num_mixers; i++) {
13660 if (spec->mixers[i] == alc268_beep_mixer) {
13661 has_beep = 1;
13662 break;
13663 }
13664 }
13665
13666 if (has_beep) {
13667 err = snd_hda_attach_beep_device(codec, 0x1);
13668 if (err < 0) {
13669 alc_free(codec);
13670 return err;
13671 }
13672 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13673 /* override the amp caps for beep generator */
13674 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
13675 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13676 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13677 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13678 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 13679 }
aef9d318 13680
7e0e44d4 13681 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
13682 /* check whether NID 0x07 is valid */
13683 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 13684 int i;
3866f0b0 13685
defb5ab2 13686 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 13687 /* get type */
a22d543a 13688 wcap = get_wcaps_type(wcap);
fdbc6626
TI
13689 if (spec->auto_mic ||
13690 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
13691 spec->adc_nids = alc268_adc_nids_alt;
13692 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
13693 if (spec->auto_mic)
13694 fixup_automic_adc(codec);
fdbc6626
TI
13695 if (spec->auto_mic || spec->input_mux->num_items == 1)
13696 add_mixer(spec, alc268_capture_nosrc_mixer);
13697 else
13698 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
13699 } else {
13700 spec->adc_nids = alc268_adc_nids;
13701 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 13702 add_mixer(spec, alc268_capture_mixer);
a361d84b 13703 }
85860c06
TI
13704 /* set default input source */
13705 for (i = 0; i < spec->num_adc_nids; i++)
13706 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
13707 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
13708 i < spec->num_mux_defs ?
13709 spec->input_mux[i].items[0].index :
85860c06 13710 spec->input_mux->items[0].index);
a361d84b 13711 }
2134ea4f
TI
13712
13713 spec->vmaster_nid = 0x02;
13714
a361d84b
KY
13715 codec->patch_ops = alc_patch_ops;
13716 if (board_config == ALC268_AUTO)
13717 spec->init_hook = alc268_auto_init;
ea1fb29a 13718
a361d84b
KY
13719 return 0;
13720}
13721
f6a92248
KY
13722/*
13723 * ALC269 channel source setting (2 channel)
13724 */
13725#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13726
13727#define alc269_dac_nids alc260_dac_nids
13728
13729static hda_nid_t alc269_adc_nids[1] = {
13730 /* ADC1 */
f53281e6
KY
13731 0x08,
13732};
13733
e01bf509
TI
13734static hda_nid_t alc269_capsrc_nids[1] = {
13735 0x23,
13736};
13737
84898e87
KY
13738static hda_nid_t alc269vb_adc_nids[1] = {
13739 /* ADC1 */
13740 0x09,
13741};
13742
13743static hda_nid_t alc269vb_capsrc_nids[1] = {
13744 0x22,
13745};
13746
6694635d
TI
13747static hda_nid_t alc269_adc_candidates[] = {
13748 0x08, 0x09, 0x07,
13749};
e01bf509 13750
f6a92248
KY
13751#define alc269_modes alc260_modes
13752#define alc269_capture_source alc880_lg_lw_capture_source
13753
13754static struct snd_kcontrol_new alc269_base_mixer[] = {
13755 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13756 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13757 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13758 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13759 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13760 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13761 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13762 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13763 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13764 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13765 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13766 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
13767 { } /* end */
13768};
13769
60db6b53
KY
13770static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13771 /* output mixer control */
13772 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13773 {
13774 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13775 .name = "Master Playback Switch",
5e26dfd0 13776 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
13777 .info = snd_hda_mixer_amp_switch_info,
13778 .get = snd_hda_mixer_amp_switch_get,
13779 .put = alc268_acer_master_sw_put,
13780 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13781 },
13782 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13783 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13784 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13785 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13786 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13787 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
60db6b53
KY
13788 { }
13789};
13790
64154835
TV
13791static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13792 /* output mixer control */
13793 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13794 {
13795 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13796 .name = "Master Playback Switch",
5e26dfd0 13797 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
13798 .info = snd_hda_mixer_amp_switch_info,
13799 .get = snd_hda_mixer_amp_switch_get,
13800 .put = alc268_acer_master_sw_put,
13801 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13802 },
13803 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13804 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13805 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13806 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13807 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13808 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13809 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13810 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
13811 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
64154835
TV
13812 { }
13813};
13814
84898e87 13815static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 13816 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 13817 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 13818 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 13819 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
13820 { } /* end */
13821};
13822
84898e87
KY
13823static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13824 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13825 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13826 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13827 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13828 { } /* end */
13829};
13830
f53281e6 13831/* capture mixer elements */
84898e87
KY
13832static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13833 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13834 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13835 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13836 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13837 { } /* end */
13838};
13839
13840static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
13841 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13842 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
26f5df26
TI
13843 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13844 { } /* end */
13845};
13846
84898e87
KY
13847static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13848 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13849 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13850 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13851 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13852 { } /* end */
13853};
13854
13855static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13856 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13857 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13858 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13859 { } /* end */
13860};
13861
26f5df26 13862/* FSC amilo */
84898e87 13863#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 13864
60db6b53
KY
13865static struct hda_verb alc269_quanta_fl1_verbs[] = {
13866 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13867 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13868 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13869 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13870 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13871 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13872 { }
13873};
f6a92248 13874
64154835
TV
13875static struct hda_verb alc269_lifebook_verbs[] = {
13876 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13877 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13878 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13879 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13880 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13881 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13882 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13883 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13884 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13885 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13886 { }
13887};
13888
60db6b53
KY
13889/* toggle speaker-output according to the hp-jack state */
13890static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13891{
13892 unsigned int present;
13893 unsigned char bits;
f6a92248 13894
864f92be 13895 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13896 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 13897 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 13898 HDA_AMP_MUTE, bits);
60db6b53 13899 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 13900 HDA_AMP_MUTE, bits);
f6a92248 13901
60db6b53
KY
13902 snd_hda_codec_write(codec, 0x20, 0,
13903 AC_VERB_SET_COEF_INDEX, 0x0c);
13904 snd_hda_codec_write(codec, 0x20, 0,
13905 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 13906
60db6b53
KY
13907 snd_hda_codec_write(codec, 0x20, 0,
13908 AC_VERB_SET_COEF_INDEX, 0x0c);
13909 snd_hda_codec_write(codec, 0x20, 0,
13910 AC_VERB_SET_PROC_COEF, 0x480);
13911}
f6a92248 13912
64154835
TV
13913/* toggle speaker-output according to the hp-jacks state */
13914static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
13915{
13916 unsigned int present;
13917 unsigned char bits;
13918
13919 /* Check laptop headphone socket */
864f92be 13920 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
13921
13922 /* Check port replicator headphone socket */
864f92be 13923 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 13924
5dbd5ec6 13925 bits = present ? HDA_AMP_MUTE : 0;
64154835 13926 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 13927 HDA_AMP_MUTE, bits);
64154835 13928 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 13929 HDA_AMP_MUTE, bits);
64154835
TV
13930
13931 snd_hda_codec_write(codec, 0x20, 0,
13932 AC_VERB_SET_COEF_INDEX, 0x0c);
13933 snd_hda_codec_write(codec, 0x20, 0,
13934 AC_VERB_SET_PROC_COEF, 0x680);
13935
13936 snd_hda_codec_write(codec, 0x20, 0,
13937 AC_VERB_SET_COEF_INDEX, 0x0c);
13938 snd_hda_codec_write(codec, 0x20, 0,
13939 AC_VERB_SET_PROC_COEF, 0x480);
13940}
13941
64154835
TV
13942static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13943{
13944 unsigned int present_laptop;
13945 unsigned int present_dock;
13946
864f92be
WF
13947 present_laptop = snd_hda_jack_detect(codec, 0x18);
13948 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
13949
13950 /* Laptop mic port overrides dock mic port, design decision */
13951 if (present_dock)
13952 snd_hda_codec_write(codec, 0x23, 0,
13953 AC_VERB_SET_CONNECT_SEL, 0x3);
13954 if (present_laptop)
13955 snd_hda_codec_write(codec, 0x23, 0,
13956 AC_VERB_SET_CONNECT_SEL, 0x0);
13957 if (!present_dock && !present_laptop)
13958 snd_hda_codec_write(codec, 0x23, 0,
13959 AC_VERB_SET_CONNECT_SEL, 0x1);
13960}
13961
60db6b53
KY
13962static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13963 unsigned int res)
13964{
4f5d1706
TI
13965 switch (res >> 26) {
13966 case ALC880_HP_EVENT:
60db6b53 13967 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
13968 break;
13969 case ALC880_MIC_EVENT:
13970 alc_mic_automute(codec);
13971 break;
13972 }
60db6b53 13973}
f6a92248 13974
64154835
TV
13975static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13976 unsigned int res)
13977{
13978 if ((res >> 26) == ALC880_HP_EVENT)
13979 alc269_lifebook_speaker_automute(codec);
13980 if ((res >> 26) == ALC880_MIC_EVENT)
13981 alc269_lifebook_mic_autoswitch(codec);
13982}
13983
4f5d1706
TI
13984static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13985{
13986 struct alc_spec *spec = codec->spec;
20645d70
TI
13987 spec->autocfg.hp_pins[0] = 0x15;
13988 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13989 spec->ext_mic.pin = 0x18;
13990 spec->ext_mic.mux_idx = 0;
13991 spec->int_mic.pin = 0x19;
13992 spec->int_mic.mux_idx = 1;
13993 spec->auto_mic = 1;
13994}
13995
60db6b53
KY
13996static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13997{
13998 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 13999 alc_mic_automute(codec);
60db6b53 14000}
f6a92248 14001
64154835
TV
14002static void alc269_lifebook_init_hook(struct hda_codec *codec)
14003{
14004 alc269_lifebook_speaker_automute(codec);
14005 alc269_lifebook_mic_autoswitch(codec);
14006}
14007
84898e87 14008static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14009 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14010 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14011 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14012 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14013 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14014 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14015 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14016 {}
14017};
14018
84898e87 14019static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14020 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14021 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14022 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14023 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14024 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14025 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14026 {}
14027};
14028
84898e87
KY
14029static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14030 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14031 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14032 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14033 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14034 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14035 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14036 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14037 {}
14038};
14039
14040static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14041 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14042 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14043 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14044 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14045 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14046 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14047 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14048 {}
14049};
14050
f53281e6
KY
14051/* toggle speaker-output according to the hp-jack state */
14052static void alc269_speaker_automute(struct hda_codec *codec)
14053{
ebb83eeb
KY
14054 struct alc_spec *spec = codec->spec;
14055 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 14056 unsigned int present;
60db6b53 14057 unsigned char bits;
f53281e6 14058
ebb83eeb 14059 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 14060 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 14061 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14062 HDA_AMP_MUTE, bits);
f53281e6 14063 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14064 HDA_AMP_MUTE, bits);
f53281e6
KY
14065}
14066
f53281e6 14067/* unsolicited event for HP jack sensing */
84898e87 14068static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 14069 unsigned int res)
f53281e6 14070{
4f5d1706
TI
14071 switch (res >> 26) {
14072 case ALC880_HP_EVENT:
f53281e6 14073 alc269_speaker_automute(codec);
4f5d1706
TI
14074 break;
14075 case ALC880_MIC_EVENT:
14076 alc_mic_automute(codec);
14077 break;
14078 }
f53281e6
KY
14079}
14080
226b1ec8 14081static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14082{
4f5d1706 14083 struct alc_spec *spec = codec->spec;
20645d70
TI
14084 spec->autocfg.hp_pins[0] = 0x15;
14085 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14086 spec->ext_mic.pin = 0x18;
14087 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14088 spec->int_mic.pin = 0x19;
14089 spec->int_mic.mux_idx = 1;
4f5d1706 14090 spec->auto_mic = 1;
f53281e6
KY
14091}
14092
226b1ec8 14093static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14094{
14095 struct alc_spec *spec = codec->spec;
20645d70
TI
14096 spec->autocfg.hp_pins[0] = 0x15;
14097 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
14098 spec->ext_mic.pin = 0x18;
14099 spec->ext_mic.mux_idx = 0;
14100 spec->int_mic.pin = 0x12;
226b1ec8 14101 spec->int_mic.mux_idx = 5;
84898e87
KY
14102 spec->auto_mic = 1;
14103}
14104
226b1ec8 14105static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14106{
4f5d1706 14107 struct alc_spec *spec = codec->spec;
226b1ec8 14108 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14109 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14110 spec->ext_mic.pin = 0x18;
14111 spec->ext_mic.mux_idx = 0;
14112 spec->int_mic.pin = 0x19;
14113 spec->int_mic.mux_idx = 1;
14114 spec->auto_mic = 1;
f53281e6
KY
14115}
14116
226b1ec8
KY
14117static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14118{
14119 struct alc_spec *spec = codec->spec;
14120 spec->autocfg.hp_pins[0] = 0x21;
14121 spec->autocfg.speaker_pins[0] = 0x14;
14122 spec->ext_mic.pin = 0x18;
14123 spec->ext_mic.mux_idx = 0;
14124 spec->int_mic.pin = 0x12;
14125 spec->int_mic.mux_idx = 6;
14126 spec->auto_mic = 1;
14127}
14128
84898e87 14129static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
14130{
14131 alc269_speaker_automute(codec);
4f5d1706 14132 alc_mic_automute(codec);
f53281e6
KY
14133}
14134
60db6b53
KY
14135/*
14136 * generic initialization of ADC, input mixers and output mixers
14137 */
14138static struct hda_verb alc269_init_verbs[] = {
14139 /*
14140 * Unmute ADC0 and set the default input to mic-in
14141 */
84898e87 14142 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14143
14144 /*
84898e87 14145 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14146 */
14147 /* set vol=0 to output mixers */
14148 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14149 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14150
14151 /* set up input amps for analog loopback */
14152 /* Amp Indices: DAC = 0, mixer = 1 */
14153 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14154 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14155 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14156 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14157 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14158 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14159
14160 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14161 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14162 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14163 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14164 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14165 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14166 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14167
14168 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14169 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14170
84898e87
KY
14171 /* FIXME: use Mux-type input source selection */
14172 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14173 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14174 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14175
84898e87
KY
14176 /* set EAPD */
14177 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14178 { }
14179};
14180
14181static struct hda_verb alc269vb_init_verbs[] = {
14182 /*
14183 * Unmute ADC0 and set the default input to mic-in
14184 */
14185 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14186
14187 /*
14188 * Set up output mixers (0x02 - 0x03)
14189 */
14190 /* set vol=0 to output mixers */
14191 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14192 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14193
14194 /* set up input amps for analog loopback */
14195 /* Amp Indices: DAC = 0, mixer = 1 */
14196 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14197 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14198 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14199 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14200 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14201 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14202
14203 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14204 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14205 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14206 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14207 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14208 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14209 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14210
14211 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14212 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14213
14214 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14215 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14216 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14217 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14218
14219 /* set EAPD */
14220 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14221 { }
14222};
14223
9d0b71b1
TI
14224#define alc269_auto_create_multi_out_ctls \
14225 alc268_auto_create_multi_out_ctls
05f5f477
TI
14226#define alc269_auto_create_input_ctls \
14227 alc268_auto_create_input_ctls
f6a92248
KY
14228
14229#ifdef CONFIG_SND_HDA_POWER_SAVE
14230#define alc269_loopbacks alc880_loopbacks
14231#endif
14232
def319f9 14233/* pcm configuration: identical with ALC880 */
f6a92248
KY
14234#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14235#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14236#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14237#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14238
f03d3115
TI
14239static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14240 .substreams = 1,
14241 .channels_min = 2,
14242 .channels_max = 8,
14243 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14244 /* NID is set in alc_build_pcms */
14245 .ops = {
14246 .open = alc880_playback_pcm_open,
14247 .prepare = alc880_playback_pcm_prepare,
14248 .cleanup = alc880_playback_pcm_cleanup
14249 },
14250};
14251
14252static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14253 .substreams = 1,
14254 .channels_min = 2,
14255 .channels_max = 2,
14256 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14257 /* NID is set in alc_build_pcms */
14258};
14259
ad35879a
TI
14260#ifdef CONFIG_SND_HDA_POWER_SAVE
14261static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14262{
14263 switch (codec->subsystem_id) {
14264 case 0x103c1586:
14265 return 1;
14266 }
14267 return 0;
14268}
14269
14270static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14271{
14272 /* update mute-LED according to the speaker mute state */
14273 if (nid == 0x01 || nid == 0x14) {
14274 int pinval;
14275 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14276 HDA_AMP_MUTE)
14277 pinval = 0x24;
14278 else
14279 pinval = 0x20;
14280 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14281 snd_hda_codec_update_cache(codec, 0x19, 0,
14282 AC_VERB_SET_PIN_WIDGET_CONTROL,
14283 pinval);
ad35879a
TI
14284 }
14285 return alc_check_power_status(codec, nid);
14286}
14287#endif /* CONFIG_SND_HDA_POWER_SAVE */
14288
840b64c0
TI
14289static int alc275_setup_dual_adc(struct hda_codec *codec)
14290{
14291 struct alc_spec *spec = codec->spec;
14292
14293 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14294 return 0;
14295 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14296 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14297 if (spec->ext_mic.pin <= 0x12) {
14298 spec->private_adc_nids[0] = 0x08;
14299 spec->private_adc_nids[1] = 0x11;
14300 spec->private_capsrc_nids[0] = 0x23;
14301 spec->private_capsrc_nids[1] = 0x22;
14302 } else {
14303 spec->private_adc_nids[0] = 0x11;
14304 spec->private_adc_nids[1] = 0x08;
14305 spec->private_capsrc_nids[0] = 0x22;
14306 spec->private_capsrc_nids[1] = 0x23;
14307 }
14308 spec->adc_nids = spec->private_adc_nids;
14309 spec->capsrc_nids = spec->private_capsrc_nids;
14310 spec->num_adc_nids = 2;
14311 spec->dual_adc_switch = 1;
14312 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14313 spec->adc_nids[0], spec->adc_nids[1]);
14314 return 1;
14315 }
14316 return 0;
14317}
14318
f6a92248
KY
14319/*
14320 * BIOS auto configuration
14321 */
14322static int alc269_parse_auto_config(struct hda_codec *codec)
14323{
14324 struct alc_spec *spec = codec->spec;
cfb9fb55 14325 int err;
f6a92248
KY
14326 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14327
14328 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14329 alc269_ignore);
14330 if (err < 0)
14331 return err;
14332
14333 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14334 if (err < 0)
14335 return err;
05f5f477 14336 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
f6a92248
KY
14337 if (err < 0)
14338 return err;
14339
14340 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14341
757899ac 14342 alc_auto_parse_digital(codec);
f6a92248 14343
603c4019 14344 if (spec->kctls.list)
d88897ea 14345 add_mixer(spec, spec->kctls.list);
f6a92248 14346
84898e87
KY
14347 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
14348 add_verb(spec, alc269vb_init_verbs);
6227cdce 14349 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14350 } else {
14351 add_verb(spec, alc269_init_verbs);
6227cdce 14352 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14353 }
14354
f6a92248 14355 spec->num_mux_defs = 1;
61b9b9b1 14356 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14357
14358 if (!alc275_setup_dual_adc(codec))
14359 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14360 sizeof(alc269_adc_candidates));
6694635d 14361
e01bf509 14362 /* set default input source */
840b64c0
TI
14363 if (!spec->dual_adc_switch)
14364 snd_hda_codec_write_cache(codec, spec->capsrc_nids[0],
e01bf509
TI
14365 0, AC_VERB_SET_CONNECT_SEL,
14366 spec->input_mux->items[0].index);
f6a92248
KY
14367
14368 err = alc_auto_add_mic_boost(codec);
14369 if (err < 0)
14370 return err;
14371
7e0e44d4 14372 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14373 set_capture_mixer(codec);
f53281e6 14374
f6a92248
KY
14375 return 1;
14376}
14377
e9af4f36
TI
14378#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14379#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14380#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14381
14382
14383/* init callback for auto-configuration model -- overriding the default init */
14384static void alc269_auto_init(struct hda_codec *codec)
14385{
f6c7e546 14386 struct alc_spec *spec = codec->spec;
f6a92248
KY
14387 alc269_auto_init_multi_out(codec);
14388 alc269_auto_init_hp_out(codec);
14389 alc269_auto_init_analog_input(codec);
757899ac 14390 alc_auto_init_digital(codec);
f6c7e546 14391 if (spec->unsol_event)
7fb0d78f 14392 alc_inithook(codec);
f6a92248
KY
14393}
14394
ff818c24
TI
14395enum {
14396 ALC269_FIXUP_SONY_VAIO,
14397};
14398
fbc25669 14399static const struct hda_verb alc269_sony_vaio_fixup_verbs[] = {
ff818c24
TI
14400 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14401 {}
14402};
14403
14404static const struct alc_fixup alc269_fixups[] = {
14405 [ALC269_FIXUP_SONY_VAIO] = {
14406 .verbs = alc269_sony_vaio_fixup_verbs
14407 },
14408};
14409
14410static struct snd_pci_quirk alc269_fixup_tbl[] = {
14411 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14412 {}
14413};
14414
14415
f6a92248
KY
14416/*
14417 * configuration and preset
14418 */
14419static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14420 [ALC269_BASIC] = "basic",
2922c9af 14421 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14422 [ALC269_AMIC] = "laptop-amic",
14423 [ALC269_DMIC] = "laptop-dmic",
64154835 14424 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14425 [ALC269_LIFEBOOK] = "lifebook",
14426 [ALC269_AUTO] = "auto",
f6a92248
KY
14427};
14428
14429static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14430 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
f53281e6 14431 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14432 ALC269_AMIC),
14433 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14434 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14435 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14436 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14437 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14438 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14439 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14440 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14441 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14442 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14443 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14444 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14445 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14446 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14447 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14448 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14449 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14450 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14451 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14452 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14453 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14454 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14455 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14456 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14457 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14458 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14459 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14460 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14461 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14462 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14463 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14464 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14465 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14466 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14467 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14468 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14469 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14470 ALC269_DMIC),
60db6b53 14471 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14472 ALC269_DMIC),
14473 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14474 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14475 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14476 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14477 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14478 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14479 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14480 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14481 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14482 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14483 {}
14484};
14485
14486static struct alc_config_preset alc269_presets[] = {
14487 [ALC269_BASIC] = {
f9e336f6 14488 .mixers = { alc269_base_mixer },
f6a92248
KY
14489 .init_verbs = { alc269_init_verbs },
14490 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14491 .dac_nids = alc269_dac_nids,
14492 .hp_nid = 0x03,
14493 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14494 .channel_mode = alc269_modes,
14495 .input_mux = &alc269_capture_source,
14496 },
60db6b53
KY
14497 [ALC269_QUANTA_FL1] = {
14498 .mixers = { alc269_quanta_fl1_mixer },
14499 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14500 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14501 .dac_nids = alc269_dac_nids,
14502 .hp_nid = 0x03,
14503 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14504 .channel_mode = alc269_modes,
14505 .input_mux = &alc269_capture_source,
14506 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 14507 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
14508 .init_hook = alc269_quanta_fl1_init_hook,
14509 },
84898e87
KY
14510 [ALC269_AMIC] = {
14511 .mixers = { alc269_laptop_mixer },
14512 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 14513 .init_verbs = { alc269_init_verbs,
84898e87 14514 alc269_laptop_amic_init_verbs },
f53281e6
KY
14515 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14516 .dac_nids = alc269_dac_nids,
14517 .hp_nid = 0x03,
14518 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14519 .channel_mode = alc269_modes,
84898e87
KY
14520 .unsol_event = alc269_laptop_unsol_event,
14521 .setup = alc269_laptop_amic_setup,
14522 .init_hook = alc269_laptop_inithook,
f53281e6 14523 },
84898e87
KY
14524 [ALC269_DMIC] = {
14525 .mixers = { alc269_laptop_mixer },
14526 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 14527 .init_verbs = { alc269_init_verbs,
84898e87
KY
14528 alc269_laptop_dmic_init_verbs },
14529 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14530 .dac_nids = alc269_dac_nids,
14531 .hp_nid = 0x03,
14532 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14533 .channel_mode = alc269_modes,
14534 .unsol_event = alc269_laptop_unsol_event,
14535 .setup = alc269_laptop_dmic_setup,
14536 .init_hook = alc269_laptop_inithook,
14537 },
14538 [ALC269VB_AMIC] = {
14539 .mixers = { alc269vb_laptop_mixer },
14540 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14541 .init_verbs = { alc269vb_init_verbs,
14542 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
14543 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14544 .dac_nids = alc269_dac_nids,
14545 .hp_nid = 0x03,
14546 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14547 .channel_mode = alc269_modes,
84898e87 14548 .unsol_event = alc269_laptop_unsol_event,
226b1ec8 14549 .setup = alc269vb_laptop_amic_setup,
84898e87
KY
14550 .init_hook = alc269_laptop_inithook,
14551 },
14552 [ALC269VB_DMIC] = {
14553 .mixers = { alc269vb_laptop_mixer },
14554 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14555 .init_verbs = { alc269vb_init_verbs,
14556 alc269vb_laptop_dmic_init_verbs },
14557 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14558 .dac_nids = alc269_dac_nids,
14559 .hp_nid = 0x03,
14560 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14561 .channel_mode = alc269_modes,
14562 .unsol_event = alc269_laptop_unsol_event,
14563 .setup = alc269vb_laptop_dmic_setup,
14564 .init_hook = alc269_laptop_inithook,
f53281e6 14565 },
26f5df26 14566 [ALC269_FUJITSU] = {
45bdd1c1 14567 .mixers = { alc269_fujitsu_mixer },
84898e87 14568 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 14569 .init_verbs = { alc269_init_verbs,
84898e87 14570 alc269_laptop_dmic_init_verbs },
26f5df26
TI
14571 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14572 .dac_nids = alc269_dac_nids,
14573 .hp_nid = 0x03,
14574 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14575 .channel_mode = alc269_modes,
84898e87
KY
14576 .unsol_event = alc269_laptop_unsol_event,
14577 .setup = alc269_laptop_dmic_setup,
14578 .init_hook = alc269_laptop_inithook,
26f5df26 14579 },
64154835
TV
14580 [ALC269_LIFEBOOK] = {
14581 .mixers = { alc269_lifebook_mixer },
14582 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14583 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14584 .dac_nids = alc269_dac_nids,
14585 .hp_nid = 0x03,
14586 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14587 .channel_mode = alc269_modes,
14588 .input_mux = &alc269_capture_source,
14589 .unsol_event = alc269_lifebook_unsol_event,
14590 .init_hook = alc269_lifebook_init_hook,
14591 },
f6a92248
KY
14592};
14593
14594static int patch_alc269(struct hda_codec *codec)
14595{
14596 struct alc_spec *spec;
14597 int board_config;
14598 int err;
84898e87 14599 int is_alc269vb = 0;
f6a92248
KY
14600
14601 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14602 if (spec == NULL)
14603 return -ENOMEM;
14604
14605 codec->spec = spec;
14606
da00c244
KY
14607 alc_auto_parse_customize_define(codec);
14608
274693f3 14609 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
c027ddcd
KY
14610 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
14611 spec->cdefine.platform_type == 1)
14612 alc_codec_rename(codec, "ALC271X");
14613 else
14614 alc_codec_rename(codec, "ALC259");
84898e87 14615 is_alc269vb = 1;
c027ddcd
KY
14616 } else
14617 alc_fix_pll_init(codec, 0x20, 0x04, 15);
274693f3 14618
f6a92248
KY
14619 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14620 alc269_models,
14621 alc269_cfg_tbl);
14622
14623 if (board_config < 0) {
9a11f1aa
TI
14624 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14625 codec->chip_name);
f6a92248
KY
14626 board_config = ALC269_AUTO;
14627 }
14628
ff818c24
TI
14629 if (board_config == ALC269_AUTO)
14630 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
14631
f6a92248
KY
14632 if (board_config == ALC269_AUTO) {
14633 /* automatic parse from the BIOS config */
14634 err = alc269_parse_auto_config(codec);
14635 if (err < 0) {
14636 alc_free(codec);
14637 return err;
14638 } else if (!err) {
14639 printk(KERN_INFO
14640 "hda_codec: Cannot set up configuration "
14641 "from BIOS. Using base mode...\n");
14642 board_config = ALC269_BASIC;
14643 }
14644 }
14645
dc1eae25 14646 if (has_cdefine_beep(codec)) {
8af2591d
TI
14647 err = snd_hda_attach_beep_device(codec, 0x1);
14648 if (err < 0) {
14649 alc_free(codec);
14650 return err;
14651 }
680cd536
KK
14652 }
14653
f6a92248 14654 if (board_config != ALC269_AUTO)
e9c364c0 14655 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 14656
84898e87 14657 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
14658 /* Due to a hardware problem on Lenovo Ideadpad, we need to
14659 * fix the sample rate of analog I/O to 44.1kHz
14660 */
14661 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
14662 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
14663 } else if (spec->dual_adc_switch) {
14664 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14665 /* switch ADC dynamically */
14666 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
14667 } else {
14668 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14669 spec->stream_analog_capture = &alc269_pcm_analog_capture;
14670 }
f6a92248
KY
14671 spec->stream_digital_playback = &alc269_pcm_digital_playback;
14672 spec->stream_digital_capture = &alc269_pcm_digital_capture;
14673
6694635d
TI
14674 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
14675 if (!is_alc269vb) {
14676 spec->adc_nids = alc269_adc_nids;
14677 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
14678 spec->capsrc_nids = alc269_capsrc_nids;
14679 } else {
14680 spec->adc_nids = alc269vb_adc_nids;
14681 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
14682 spec->capsrc_nids = alc269vb_capsrc_nids;
14683 }
84898e87
KY
14684 }
14685
f9e336f6 14686 if (!spec->cap_mixer)
b59bdf3b 14687 set_capture_mixer(codec);
dc1eae25 14688 if (has_cdefine_beep(codec))
da00c244 14689 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 14690
ff818c24
TI
14691 if (board_config == ALC269_AUTO)
14692 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
14693
100d5eb3
TI
14694 spec->vmaster_nid = 0x02;
14695
f6a92248
KY
14696 codec->patch_ops = alc_patch_ops;
14697 if (board_config == ALC269_AUTO)
14698 spec->init_hook = alc269_auto_init;
14699#ifdef CONFIG_SND_HDA_POWER_SAVE
14700 if (!spec->loopback.amplist)
14701 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
14702 if (alc269_mic2_for_mute_led(codec))
14703 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
14704#endif
14705
14706 return 0;
14707}
14708
df694daa
KY
14709/*
14710 * ALC861 channel source setting (2/6 channel selection for 3-stack)
14711 */
14712
14713/*
14714 * set the path ways for 2 channel output
14715 * need to set the codec line out and mic 1 pin widgets to inputs
14716 */
14717static struct hda_verb alc861_threestack_ch2_init[] = {
14718 /* set pin widget 1Ah (line in) for input */
14719 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14720 /* set pin widget 18h (mic1/2) for input, for mic also enable
14721 * the vref
14722 */
df694daa
KY
14723 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14724
9c7f852e
TI
14725 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14726#if 0
14727 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14728 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14729#endif
df694daa
KY
14730 { } /* end */
14731};
14732/*
14733 * 6ch mode
14734 * need to set the codec line out and mic 1 pin widgets to outputs
14735 */
14736static struct hda_verb alc861_threestack_ch6_init[] = {
14737 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14738 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14739 /* set pin widget 18h (mic1) for output (CLFE)*/
14740 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14741
14742 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 14743 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 14744
9c7f852e
TI
14745 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14746#if 0
14747 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14748 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14749#endif
df694daa
KY
14750 { } /* end */
14751};
14752
14753static struct hda_channel_mode alc861_threestack_modes[2] = {
14754 { 2, alc861_threestack_ch2_init },
14755 { 6, alc861_threestack_ch6_init },
14756};
22309c3e
TI
14757/* Set mic1 as input and unmute the mixer */
14758static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
14759 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14760 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14761 { } /* end */
14762};
14763/* Set mic1 as output and mute mixer */
14764static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
14765 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14766 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14767 { } /* end */
14768};
14769
14770static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
14771 { 2, alc861_uniwill_m31_ch2_init },
14772 { 4, alc861_uniwill_m31_ch4_init },
14773};
df694daa 14774
7cdbff94
MD
14775/* Set mic1 and line-in as input and unmute the mixer */
14776static struct hda_verb alc861_asus_ch2_init[] = {
14777 /* set pin widget 1Ah (line in) for input */
14778 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14779 /* set pin widget 18h (mic1/2) for input, for mic also enable
14780 * the vref
14781 */
7cdbff94
MD
14782 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14783
14784 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14785#if 0
14786 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14787 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14788#endif
14789 { } /* end */
14790};
14791/* Set mic1 nad line-in as output and mute mixer */
14792static struct hda_verb alc861_asus_ch6_init[] = {
14793 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14794 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14795 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14796 /* set pin widget 18h (mic1) for output (CLFE)*/
14797 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14798 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14799 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14800 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14801
14802 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14803#if 0
14804 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14805 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14806#endif
14807 { } /* end */
14808};
14809
14810static struct hda_channel_mode alc861_asus_modes[2] = {
14811 { 2, alc861_asus_ch2_init },
14812 { 6, alc861_asus_ch6_init },
14813};
14814
df694daa
KY
14815/* patch-ALC861 */
14816
14817static struct snd_kcontrol_new alc861_base_mixer[] = {
14818 /* output mixer control */
14819 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14820 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14821 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14822 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14823 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14824
14825 /*Input mixer control */
14826 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14827 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14828 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14829 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14830 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14831 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14832 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14833 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14834 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14835 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14836
df694daa
KY
14837 { } /* end */
14838};
14839
14840static struct snd_kcontrol_new alc861_3ST_mixer[] = {
14841 /* output mixer control */
14842 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14843 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14844 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14845 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14846 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14847
14848 /* Input mixer control */
14849 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14850 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14851 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14852 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14853 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14854 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14855 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14856 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14857 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14858 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14859
df694daa
KY
14860 {
14861 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14862 .name = "Channel Mode",
14863 .info = alc_ch_mode_info,
14864 .get = alc_ch_mode_get,
14865 .put = alc_ch_mode_put,
14866 .private_value = ARRAY_SIZE(alc861_threestack_modes),
14867 },
14868 { } /* end */
a53d1aec
TD
14869};
14870
d1d985f0 14871static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
14872 /* output mixer control */
14873 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14874 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14875 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 14876
a53d1aec 14877 { } /* end */
f12ab1e0 14878};
a53d1aec 14879
22309c3e
TI
14880static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
14881 /* output mixer control */
14882 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14883 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14884 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14885 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14886 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14887
14888 /* Input mixer control */
14889 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14890 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14891 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14892 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14893 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14894 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14895 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14896 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14897 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14898 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14899
22309c3e
TI
14900 {
14901 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14902 .name = "Channel Mode",
14903 .info = alc_ch_mode_info,
14904 .get = alc_ch_mode_get,
14905 .put = alc_ch_mode_put,
14906 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
14907 },
14908 { } /* end */
f12ab1e0 14909};
7cdbff94
MD
14910
14911static struct snd_kcontrol_new alc861_asus_mixer[] = {
14912 /* output mixer control */
14913 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14914 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14915 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14916 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14917 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14918
14919 /* Input mixer control */
14920 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14921 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14922 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14923 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14924 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14925 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14926 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14927 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14928 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
14929 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
14930
7cdbff94
MD
14931 {
14932 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14933 .name = "Channel Mode",
14934 .info = alc_ch_mode_info,
14935 .get = alc_ch_mode_get,
14936 .put = alc_ch_mode_put,
14937 .private_value = ARRAY_SIZE(alc861_asus_modes),
14938 },
14939 { }
56bb0cab
TI
14940};
14941
14942/* additional mixer */
d1d985f0 14943static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
14944 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14945 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
14946 { }
14947};
7cdbff94 14948
df694daa
KY
14949/*
14950 * generic initialization of ADC, input mixers and output mixers
14951 */
14952static struct hda_verb alc861_base_init_verbs[] = {
14953 /*
14954 * Unmute ADC0 and set the default input to mic-in
14955 */
14956 /* port-A for surround (rear panel) */
14957 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14958 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
14959 /* port-B for mic-in (rear panel) with vref */
14960 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14961 /* port-C for line-in (rear panel) */
14962 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14963 /* port-D for Front */
14964 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14965 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14966 /* port-E for HP out (front panel) */
14967 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
14968 /* route front PCM to HP */
9dece1d7 14969 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
14970 /* port-F for mic-in (front panel) with vref */
14971 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14972 /* port-G for CLFE (rear panel) */
14973 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14974 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14975 /* port-H for side (rear panel) */
14976 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14977 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
14978 /* CD-in */
14979 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14980 /* route front mic to ADC1*/
14981 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14982 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 14983
df694daa
KY
14984 /* Unmute DAC0~3 & spdif out*/
14985 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14986 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14987 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14988 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14989 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 14990
df694daa
KY
14991 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14992 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14993 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14994 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14995 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14996
df694daa
KY
14997 /* Unmute Stereo Mixer 15 */
14998 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14999 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15000 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15001 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15002
15003 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15004 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15005 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15006 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15007 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15008 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15009 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15010 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15011 /* hp used DAC 3 (Front) */
15012 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15013 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15014
15015 { }
15016};
15017
15018static struct hda_verb alc861_threestack_init_verbs[] = {
15019 /*
15020 * Unmute ADC0 and set the default input to mic-in
15021 */
15022 /* port-A for surround (rear panel) */
15023 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15024 /* port-B for mic-in (rear panel) with vref */
15025 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15026 /* port-C for line-in (rear panel) */
15027 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15028 /* port-D for Front */
15029 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15030 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15031 /* port-E for HP out (front panel) */
15032 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15033 /* route front PCM to HP */
9dece1d7 15034 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15035 /* port-F for mic-in (front panel) with vref */
15036 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15037 /* port-G for CLFE (rear panel) */
15038 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15039 /* port-H for side (rear panel) */
15040 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15041 /* CD-in */
15042 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15043 /* route front mic to ADC1*/
15044 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15045 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15046 /* Unmute DAC0~3 & spdif out*/
15047 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15048 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15049 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15050 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15051 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15052
df694daa
KY
15053 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15054 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15055 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15056 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15057 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15058
df694daa
KY
15059 /* Unmute Stereo Mixer 15 */
15060 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15061 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15062 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15063 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15064
15065 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15066 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15067 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15068 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15069 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15070 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15071 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15072 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15073 /* hp used DAC 3 (Front) */
15074 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15075 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15076 { }
15077};
22309c3e
TI
15078
15079static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15080 /*
15081 * Unmute ADC0 and set the default input to mic-in
15082 */
15083 /* port-A for surround (rear panel) */
15084 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15085 /* port-B for mic-in (rear panel) with vref */
15086 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15087 /* port-C for line-in (rear panel) */
15088 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15089 /* port-D for Front */
15090 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15091 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15092 /* port-E for HP out (front panel) */
f12ab1e0
TI
15093 /* this has to be set to VREF80 */
15094 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15095 /* route front PCM to HP */
9dece1d7 15096 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15097 /* port-F for mic-in (front panel) with vref */
15098 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15099 /* port-G for CLFE (rear panel) */
15100 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15101 /* port-H for side (rear panel) */
15102 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15103 /* CD-in */
15104 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15105 /* route front mic to ADC1*/
15106 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15107 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15108 /* Unmute DAC0~3 & spdif out*/
15109 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15110 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15111 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15112 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15113 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15114
22309c3e
TI
15115 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15116 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15117 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15118 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15119 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15120
22309c3e
TI
15121 /* Unmute Stereo Mixer 15 */
15122 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15123 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15124 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15125 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15126
15127 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15128 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15129 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15130 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15131 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15132 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15133 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15134 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15135 /* hp used DAC 3 (Front) */
15136 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15137 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15138 { }
15139};
15140
7cdbff94
MD
15141static struct hda_verb alc861_asus_init_verbs[] = {
15142 /*
15143 * Unmute ADC0 and set the default input to mic-in
15144 */
f12ab1e0
TI
15145 /* port-A for surround (rear panel)
15146 * according to codec#0 this is the HP jack
15147 */
7cdbff94
MD
15148 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15149 /* route front PCM to HP */
15150 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15151 /* port-B for mic-in (rear panel) with vref */
15152 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15153 /* port-C for line-in (rear panel) */
15154 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15155 /* port-D for Front */
15156 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15157 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15158 /* port-E for HP out (front panel) */
f12ab1e0
TI
15159 /* this has to be set to VREF80 */
15160 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15161 /* route front PCM to HP */
9dece1d7 15162 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15163 /* port-F for mic-in (front panel) with vref */
15164 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15165 /* port-G for CLFE (rear panel) */
15166 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15167 /* port-H for side (rear panel) */
15168 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15169 /* CD-in */
15170 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15171 /* route front mic to ADC1*/
15172 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15173 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15174 /* Unmute DAC0~3 & spdif out*/
15175 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15176 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15177 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15178 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15179 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15180 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15181 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15182 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15183 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15184 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15185
7cdbff94
MD
15186 /* Unmute Stereo Mixer 15 */
15187 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15188 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15189 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15190 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15191
15192 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15193 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15194 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15195 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15196 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15197 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15198 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15199 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15200 /* hp used DAC 3 (Front) */
15201 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15202 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15203 { }
15204};
15205
56bb0cab
TI
15206/* additional init verbs for ASUS laptops */
15207static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15208 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15209 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15210 { }
15211};
7cdbff94 15212
df694daa
KY
15213/*
15214 * generic initialization of ADC, input mixers and output mixers
15215 */
15216static struct hda_verb alc861_auto_init_verbs[] = {
15217 /*
15218 * Unmute ADC0 and set the default input to mic-in
15219 */
f12ab1e0 15220 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15221 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15222
df694daa
KY
15223 /* Unmute DAC0~3 & spdif out*/
15224 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15225 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15226 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15227 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15228 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15229
df694daa
KY
15230 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15231 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15232 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15233 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15234 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15235
df694daa
KY
15236 /* Unmute Stereo Mixer 15 */
15237 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15238 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15239 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15240 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15241
1c20930a
TI
15242 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15243 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15244 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15245 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15246 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15247 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15248 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15249 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15250
15251 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15252 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15253 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15254 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15255 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15256 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15257 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15258 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15259
f12ab1e0 15260 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15261
15262 { }
15263};
15264
a53d1aec
TD
15265static struct hda_verb alc861_toshiba_init_verbs[] = {
15266 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15267
a53d1aec
TD
15268 { }
15269};
15270
15271/* toggle speaker-output according to the hp-jack state */
15272static void alc861_toshiba_automute(struct hda_codec *codec)
15273{
864f92be 15274 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15275
47fd830a
TI
15276 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15277 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15278 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15279 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15280}
15281
15282static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15283 unsigned int res)
15284{
a53d1aec
TD
15285 if ((res >> 26) == ALC880_HP_EVENT)
15286 alc861_toshiba_automute(codec);
15287}
15288
def319f9 15289/* pcm configuration: identical with ALC880 */
df694daa
KY
15290#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15291#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15292#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15293#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15294
15295
15296#define ALC861_DIGOUT_NID 0x07
15297
15298static struct hda_channel_mode alc861_8ch_modes[1] = {
15299 { 8, NULL }
15300};
15301
15302static hda_nid_t alc861_dac_nids[4] = {
15303 /* front, surround, clfe, side */
15304 0x03, 0x06, 0x05, 0x04
15305};
15306
9c7f852e
TI
15307static hda_nid_t alc660_dac_nids[3] = {
15308 /* front, clfe, surround */
15309 0x03, 0x05, 0x06
15310};
15311
df694daa
KY
15312static hda_nid_t alc861_adc_nids[1] = {
15313 /* ADC0-2 */
15314 0x08,
15315};
15316
15317static struct hda_input_mux alc861_capture_source = {
15318 .num_items = 5,
15319 .items = {
15320 { "Mic", 0x0 },
15321 { "Front Mic", 0x3 },
15322 { "Line", 0x1 },
15323 { "CD", 0x4 },
15324 { "Mixer", 0x5 },
15325 },
15326};
15327
1c20930a
TI
15328static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15329{
15330 struct alc_spec *spec = codec->spec;
15331 hda_nid_t mix, srcs[5];
15332 int i, j, num;
15333
15334 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15335 return 0;
15336 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15337 if (num < 0)
15338 return 0;
15339 for (i = 0; i < num; i++) {
15340 unsigned int type;
a22d543a 15341 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15342 if (type != AC_WID_AUD_OUT)
15343 continue;
15344 for (j = 0; j < spec->multiout.num_dacs; j++)
15345 if (spec->multiout.dac_nids[j] == srcs[i])
15346 break;
15347 if (j >= spec->multiout.num_dacs)
15348 return srcs[i];
15349 }
15350 return 0;
15351}
15352
df694daa 15353/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15354static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15355 const struct auto_pin_cfg *cfg)
df694daa 15356{
1c20930a 15357 struct alc_spec *spec = codec->spec;
df694daa 15358 int i;
1c20930a 15359 hda_nid_t nid, dac;
df694daa
KY
15360
15361 spec->multiout.dac_nids = spec->private_dac_nids;
15362 for (i = 0; i < cfg->line_outs; i++) {
15363 nid = cfg->line_out_pins[i];
1c20930a
TI
15364 dac = alc861_look_for_dac(codec, nid);
15365 if (!dac)
15366 continue;
15367 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15368 }
df694daa
KY
15369 return 0;
15370}
15371
1c20930a
TI
15372static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15373 hda_nid_t nid, unsigned int chs)
15374{
0afe5f89 15375 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
1c20930a
TI
15376 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15377}
15378
df694daa 15379/* add playback controls from the parsed DAC table */
1c20930a 15380static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15381 const struct auto_pin_cfg *cfg)
15382{
1c20930a 15383 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
15384 static const char *chname[4] = {
15385 "Front", "Surround", NULL /*CLFE*/, "Side"
15386 };
df694daa 15387 hda_nid_t nid;
1c20930a
TI
15388 int i, err;
15389
15390 if (cfg->line_outs == 1) {
15391 const char *pfx = NULL;
15392 if (!cfg->hp_outs)
15393 pfx = "Master";
15394 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15395 pfx = "Speaker";
15396 if (pfx) {
15397 nid = spec->multiout.dac_nids[0];
15398 return alc861_create_out_sw(codec, pfx, nid, 3);
15399 }
15400 }
df694daa
KY
15401
15402 for (i = 0; i < cfg->line_outs; i++) {
15403 nid = spec->multiout.dac_nids[i];
f12ab1e0 15404 if (!nid)
df694daa 15405 continue;
1c20930a 15406 if (i == 2) {
df694daa 15407 /* Center/LFE */
1c20930a 15408 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15409 if (err < 0)
df694daa 15410 return err;
1c20930a 15411 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15412 if (err < 0)
df694daa
KY
15413 return err;
15414 } else {
1c20930a 15415 err = alc861_create_out_sw(codec, chname[i], nid, 3);
f12ab1e0 15416 if (err < 0)
df694daa
KY
15417 return err;
15418 }
15419 }
15420 return 0;
15421}
15422
1c20930a 15423static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 15424{
1c20930a 15425 struct alc_spec *spec = codec->spec;
df694daa
KY
15426 int err;
15427 hda_nid_t nid;
15428
f12ab1e0 15429 if (!pin)
df694daa
KY
15430 return 0;
15431
15432 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
15433 nid = alc861_look_for_dac(codec, pin);
15434 if (nid) {
15435 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15436 if (err < 0)
15437 return err;
15438 spec->multiout.hp_nid = nid;
15439 }
df694daa
KY
15440 }
15441 return 0;
15442}
15443
15444/* create playback/capture controls for input pins */
05f5f477 15445static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 15446 const struct auto_pin_cfg *cfg)
df694daa 15447{
05f5f477 15448 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
15449}
15450
f12ab1e0
TI
15451static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15452 hda_nid_t nid,
1c20930a 15453 int pin_type, hda_nid_t dac)
df694daa 15454{
1c20930a
TI
15455 hda_nid_t mix, srcs[5];
15456 int i, num;
15457
564c5bea
JL
15458 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15459 pin_type);
1c20930a 15460 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 15461 AMP_OUT_UNMUTE);
1c20930a
TI
15462 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15463 return;
15464 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15465 if (num < 0)
15466 return;
15467 for (i = 0; i < num; i++) {
15468 unsigned int mute;
15469 if (srcs[i] == dac || srcs[i] == 0x15)
15470 mute = AMP_IN_UNMUTE(i);
15471 else
15472 mute = AMP_IN_MUTE(i);
15473 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15474 mute);
15475 }
df694daa
KY
15476}
15477
15478static void alc861_auto_init_multi_out(struct hda_codec *codec)
15479{
15480 struct alc_spec *spec = codec->spec;
15481 int i;
15482
15483 for (i = 0; i < spec->autocfg.line_outs; i++) {
15484 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 15485 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 15486 if (nid)
baba8ee9 15487 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 15488 spec->multiout.dac_nids[i]);
df694daa
KY
15489 }
15490}
15491
15492static void alc861_auto_init_hp_out(struct hda_codec *codec)
15493{
15494 struct alc_spec *spec = codec->spec;
df694daa 15495
15870f05
TI
15496 if (spec->autocfg.hp_outs)
15497 alc861_auto_set_output_and_unmute(codec,
15498 spec->autocfg.hp_pins[0],
15499 PIN_HP,
1c20930a 15500 spec->multiout.hp_nid);
15870f05
TI
15501 if (spec->autocfg.speaker_outs)
15502 alc861_auto_set_output_and_unmute(codec,
15503 spec->autocfg.speaker_pins[0],
15504 PIN_OUT,
1c20930a 15505 spec->multiout.dac_nids[0]);
df694daa
KY
15506}
15507
15508static void alc861_auto_init_analog_input(struct hda_codec *codec)
15509{
15510 struct alc_spec *spec = codec->spec;
15511 int i;
15512
15513 for (i = 0; i < AUTO_PIN_LAST; i++) {
15514 hda_nid_t nid = spec->autocfg.input_pins[i];
23f0c048
TI
15515 if (nid >= 0x0c && nid <= 0x11)
15516 alc_set_input_pin(codec, nid, i);
df694daa
KY
15517 }
15518}
15519
15520/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
15521/* return 1 if successful, 0 if the proper config is not found,
15522 * or a negative error code
15523 */
df694daa
KY
15524static int alc861_parse_auto_config(struct hda_codec *codec)
15525{
15526 struct alc_spec *spec = codec->spec;
15527 int err;
15528 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
15529
f12ab1e0
TI
15530 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15531 alc861_ignore);
15532 if (err < 0)
df694daa 15533 return err;
f12ab1e0 15534 if (!spec->autocfg.line_outs)
df694daa
KY
15535 return 0; /* can't find valid BIOS pin config */
15536
1c20930a 15537 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
15538 if (err < 0)
15539 return err;
1c20930a 15540 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
15541 if (err < 0)
15542 return err;
1c20930a 15543 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
15544 if (err < 0)
15545 return err;
05f5f477 15546 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 15547 if (err < 0)
df694daa
KY
15548 return err;
15549
15550 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15551
757899ac 15552 alc_auto_parse_digital(codec);
df694daa 15553
603c4019 15554 if (spec->kctls.list)
d88897ea 15555 add_mixer(spec, spec->kctls.list);
df694daa 15556
d88897ea 15557 add_verb(spec, alc861_auto_init_verbs);
df694daa 15558
a1e8d2da 15559 spec->num_mux_defs = 1;
61b9b9b1 15560 spec->input_mux = &spec->private_imux[0];
df694daa
KY
15561
15562 spec->adc_nids = alc861_adc_nids;
15563 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 15564 set_capture_mixer(codec);
df694daa 15565
6227cdce 15566 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 15567
df694daa
KY
15568 return 1;
15569}
15570
ae6b813a
TI
15571/* additional initialization for auto-configuration model */
15572static void alc861_auto_init(struct hda_codec *codec)
df694daa 15573{
f6c7e546 15574 struct alc_spec *spec = codec->spec;
df694daa
KY
15575 alc861_auto_init_multi_out(codec);
15576 alc861_auto_init_hp_out(codec);
15577 alc861_auto_init_analog_input(codec);
757899ac 15578 alc_auto_init_digital(codec);
f6c7e546 15579 if (spec->unsol_event)
7fb0d78f 15580 alc_inithook(codec);
df694daa
KY
15581}
15582
cb53c626
TI
15583#ifdef CONFIG_SND_HDA_POWER_SAVE
15584static struct hda_amp_list alc861_loopbacks[] = {
15585 { 0x15, HDA_INPUT, 0 },
15586 { 0x15, HDA_INPUT, 1 },
15587 { 0x15, HDA_INPUT, 2 },
15588 { 0x15, HDA_INPUT, 3 },
15589 { } /* end */
15590};
15591#endif
15592
df694daa
KY
15593
15594/*
15595 * configuration and preset
15596 */
f5fcc13c
TI
15597static const char *alc861_models[ALC861_MODEL_LAST] = {
15598 [ALC861_3ST] = "3stack",
15599 [ALC660_3ST] = "3stack-660",
15600 [ALC861_3ST_DIG] = "3stack-dig",
15601 [ALC861_6ST_DIG] = "6stack-dig",
15602 [ALC861_UNIWILL_M31] = "uniwill-m31",
15603 [ALC861_TOSHIBA] = "toshiba",
15604 [ALC861_ASUS] = "asus",
15605 [ALC861_ASUS_LAPTOP] = "asus-laptop",
15606 [ALC861_AUTO] = "auto",
15607};
15608
15609static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 15610 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
15611 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15612 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15613 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 15614 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 15615 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 15616 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
15617 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
15618 * Any other models that need this preset?
15619 */
15620 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
15621 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
15622 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 15623 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
15624 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
15625 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
15626 /* FIXME: the below seems conflict */
15627 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 15628 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 15629 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
15630 {}
15631};
15632
15633static struct alc_config_preset alc861_presets[] = {
15634 [ALC861_3ST] = {
15635 .mixers = { alc861_3ST_mixer },
15636 .init_verbs = { alc861_threestack_init_verbs },
15637 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15638 .dac_nids = alc861_dac_nids,
15639 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15640 .channel_mode = alc861_threestack_modes,
4e195a7b 15641 .need_dac_fix = 1,
df694daa
KY
15642 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15643 .adc_nids = alc861_adc_nids,
15644 .input_mux = &alc861_capture_source,
15645 },
15646 [ALC861_3ST_DIG] = {
15647 .mixers = { alc861_base_mixer },
15648 .init_verbs = { alc861_threestack_init_verbs },
15649 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15650 .dac_nids = alc861_dac_nids,
15651 .dig_out_nid = ALC861_DIGOUT_NID,
15652 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15653 .channel_mode = alc861_threestack_modes,
4e195a7b 15654 .need_dac_fix = 1,
df694daa
KY
15655 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15656 .adc_nids = alc861_adc_nids,
15657 .input_mux = &alc861_capture_source,
15658 },
15659 [ALC861_6ST_DIG] = {
15660 .mixers = { alc861_base_mixer },
15661 .init_verbs = { alc861_base_init_verbs },
15662 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15663 .dac_nids = alc861_dac_nids,
15664 .dig_out_nid = ALC861_DIGOUT_NID,
15665 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
15666 .channel_mode = alc861_8ch_modes,
15667 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15668 .adc_nids = alc861_adc_nids,
15669 .input_mux = &alc861_capture_source,
15670 },
9c7f852e
TI
15671 [ALC660_3ST] = {
15672 .mixers = { alc861_3ST_mixer },
15673 .init_verbs = { alc861_threestack_init_verbs },
15674 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
15675 .dac_nids = alc660_dac_nids,
15676 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15677 .channel_mode = alc861_threestack_modes,
4e195a7b 15678 .need_dac_fix = 1,
9c7f852e
TI
15679 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15680 .adc_nids = alc861_adc_nids,
15681 .input_mux = &alc861_capture_source,
15682 },
22309c3e
TI
15683 [ALC861_UNIWILL_M31] = {
15684 .mixers = { alc861_uniwill_m31_mixer },
15685 .init_verbs = { alc861_uniwill_m31_init_verbs },
15686 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15687 .dac_nids = alc861_dac_nids,
15688 .dig_out_nid = ALC861_DIGOUT_NID,
15689 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
15690 .channel_mode = alc861_uniwill_m31_modes,
15691 .need_dac_fix = 1,
15692 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15693 .adc_nids = alc861_adc_nids,
15694 .input_mux = &alc861_capture_source,
15695 },
a53d1aec
TD
15696 [ALC861_TOSHIBA] = {
15697 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
15698 .init_verbs = { alc861_base_init_verbs,
15699 alc861_toshiba_init_verbs },
a53d1aec
TD
15700 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15701 .dac_nids = alc861_dac_nids,
15702 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15703 .channel_mode = alc883_3ST_2ch_modes,
15704 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15705 .adc_nids = alc861_adc_nids,
15706 .input_mux = &alc861_capture_source,
15707 .unsol_event = alc861_toshiba_unsol_event,
15708 .init_hook = alc861_toshiba_automute,
15709 },
7cdbff94
MD
15710 [ALC861_ASUS] = {
15711 .mixers = { alc861_asus_mixer },
15712 .init_verbs = { alc861_asus_init_verbs },
15713 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15714 .dac_nids = alc861_dac_nids,
15715 .dig_out_nid = ALC861_DIGOUT_NID,
15716 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
15717 .channel_mode = alc861_asus_modes,
15718 .need_dac_fix = 1,
15719 .hp_nid = 0x06,
15720 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15721 .adc_nids = alc861_adc_nids,
15722 .input_mux = &alc861_capture_source,
15723 },
56bb0cab
TI
15724 [ALC861_ASUS_LAPTOP] = {
15725 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
15726 .init_verbs = { alc861_asus_init_verbs,
15727 alc861_asus_laptop_init_verbs },
15728 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15729 .dac_nids = alc861_dac_nids,
15730 .dig_out_nid = ALC861_DIGOUT_NID,
15731 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15732 .channel_mode = alc883_3ST_2ch_modes,
15733 .need_dac_fix = 1,
15734 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15735 .adc_nids = alc861_adc_nids,
15736 .input_mux = &alc861_capture_source,
15737 },
15738};
df694daa 15739
cfc9b06f
TI
15740/* Pin config fixes */
15741enum {
15742 PINFIX_FSC_AMILO_PI1505,
15743};
15744
15745static struct alc_pincfg alc861_fsc_amilo_pi1505_pinfix[] = {
15746 { 0x0b, 0x0221101f }, /* HP */
15747 { 0x0f, 0x90170310 }, /* speaker */
15748 { }
15749};
15750
15751static const struct alc_fixup alc861_fixups[] = {
15752 [PINFIX_FSC_AMILO_PI1505] = {
15753 .pins = alc861_fsc_amilo_pi1505_pinfix
15754 },
15755};
15756
15757static struct snd_pci_quirk alc861_fixup_tbl[] = {
15758 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
15759 {}
15760};
df694daa
KY
15761
15762static int patch_alc861(struct hda_codec *codec)
15763{
15764 struct alc_spec *spec;
15765 int board_config;
15766 int err;
15767
dc041e0b 15768 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
15769 if (spec == NULL)
15770 return -ENOMEM;
15771
f12ab1e0 15772 codec->spec = spec;
df694daa 15773
f5fcc13c
TI
15774 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
15775 alc861_models,
15776 alc861_cfg_tbl);
9c7f852e 15777
f5fcc13c 15778 if (board_config < 0) {
9a11f1aa
TI
15779 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15780 codec->chip_name);
df694daa
KY
15781 board_config = ALC861_AUTO;
15782 }
15783
7fa90e87
TI
15784 if (board_config == ALC861_AUTO)
15785 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
cfc9b06f 15786
df694daa
KY
15787 if (board_config == ALC861_AUTO) {
15788 /* automatic parse from the BIOS config */
15789 err = alc861_parse_auto_config(codec);
15790 if (err < 0) {
15791 alc_free(codec);
15792 return err;
f12ab1e0 15793 } else if (!err) {
9c7f852e
TI
15794 printk(KERN_INFO
15795 "hda_codec: Cannot set up configuration "
15796 "from BIOS. Using base mode...\n");
df694daa
KY
15797 board_config = ALC861_3ST_DIG;
15798 }
15799 }
15800
680cd536
KK
15801 err = snd_hda_attach_beep_device(codec, 0x23);
15802 if (err < 0) {
15803 alc_free(codec);
15804 return err;
15805 }
15806
df694daa 15807 if (board_config != ALC861_AUTO)
e9c364c0 15808 setup_preset(codec, &alc861_presets[board_config]);
df694daa 15809
df694daa
KY
15810 spec->stream_analog_playback = &alc861_pcm_analog_playback;
15811 spec->stream_analog_capture = &alc861_pcm_analog_capture;
15812
df694daa
KY
15813 spec->stream_digital_playback = &alc861_pcm_digital_playback;
15814 spec->stream_digital_capture = &alc861_pcm_digital_capture;
15815
c7a8eb10
TI
15816 if (!spec->cap_mixer)
15817 set_capture_mixer(codec);
45bdd1c1
TI
15818 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
15819
2134ea4f
TI
15820 spec->vmaster_nid = 0x03;
15821
7fa90e87
TI
15822 if (board_config == ALC861_AUTO)
15823 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
15824
df694daa 15825 codec->patch_ops = alc_patch_ops;
c97259df 15826 if (board_config == ALC861_AUTO) {
ae6b813a 15827 spec->init_hook = alc861_auto_init;
c97259df
DC
15828#ifdef CONFIG_SND_HDA_POWER_SAVE
15829 spec->power_hook = alc_power_eapd;
15830#endif
15831 }
cb53c626
TI
15832#ifdef CONFIG_SND_HDA_POWER_SAVE
15833 if (!spec->loopback.amplist)
15834 spec->loopback.amplist = alc861_loopbacks;
15835#endif
ea1fb29a 15836
1da177e4
LT
15837 return 0;
15838}
15839
f32610ed
JS
15840/*
15841 * ALC861-VD support
15842 *
15843 * Based on ALC882
15844 *
15845 * In addition, an independent DAC
15846 */
15847#define ALC861VD_DIGOUT_NID 0x06
15848
15849static hda_nid_t alc861vd_dac_nids[4] = {
15850 /* front, surr, clfe, side surr */
15851 0x02, 0x03, 0x04, 0x05
15852};
15853
15854/* dac_nids for ALC660vd are in a different order - according to
15855 * Realtek's driver.
def319f9 15856 * This should probably result in a different mixer for 6stack models
f32610ed
JS
15857 * of ALC660vd codecs, but for now there is only 3stack mixer
15858 * - and it is the same as in 861vd.
15859 * adc_nids in ALC660vd are (is) the same as in 861vd
15860 */
15861static hda_nid_t alc660vd_dac_nids[3] = {
15862 /* front, rear, clfe, rear_surr */
15863 0x02, 0x04, 0x03
15864};
15865
15866static hda_nid_t alc861vd_adc_nids[1] = {
15867 /* ADC0 */
15868 0x09,
15869};
15870
e1406348
TI
15871static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
15872
f32610ed
JS
15873/* input MUX */
15874/* FIXME: should be a matrix-type input source selection */
15875static struct hda_input_mux alc861vd_capture_source = {
15876 .num_items = 4,
15877 .items = {
15878 { "Mic", 0x0 },
15879 { "Front Mic", 0x1 },
15880 { "Line", 0x2 },
15881 { "CD", 0x4 },
15882 },
15883};
15884
272a527c 15885static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 15886 .num_items = 2,
272a527c 15887 .items = {
b419f346
TD
15888 { "Ext Mic", 0x0 },
15889 { "Int Mic", 0x1 },
272a527c
KY
15890 },
15891};
15892
d1a991a6
KY
15893static struct hda_input_mux alc861vd_hp_capture_source = {
15894 .num_items = 2,
15895 .items = {
15896 { "Front Mic", 0x0 },
15897 { "ATAPI Mic", 0x1 },
15898 },
15899};
15900
f32610ed
JS
15901/*
15902 * 2ch mode
15903 */
15904static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
15905 { 2, NULL }
15906};
15907
15908/*
15909 * 6ch mode
15910 */
15911static struct hda_verb alc861vd_6stack_ch6_init[] = {
15912 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15913 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15914 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15915 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15916 { } /* end */
15917};
15918
15919/*
15920 * 8ch mode
15921 */
15922static struct hda_verb alc861vd_6stack_ch8_init[] = {
15923 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15924 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15925 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15926 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15927 { } /* end */
15928};
15929
15930static struct hda_channel_mode alc861vd_6stack_modes[2] = {
15931 { 6, alc861vd_6stack_ch6_init },
15932 { 8, alc861vd_6stack_ch8_init },
15933};
15934
15935static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
15936 {
15937 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15938 .name = "Channel Mode",
15939 .info = alc_ch_mode_info,
15940 .get = alc_ch_mode_get,
15941 .put = alc_ch_mode_put,
15942 },
15943 { } /* end */
15944};
15945
f32610ed
JS
15946/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15947 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15948 */
15949static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
15950 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15951 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15952
15953 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15954 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
15955
15956 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
15957 HDA_OUTPUT),
15958 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
15959 HDA_OUTPUT),
15960 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
15961 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
15962
15963 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
15964 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
15965
15966 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15967
15968 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15969 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15970 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15971
15972 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15973 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15974 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15975
15976 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15977 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15978
15979 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15980 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15981
f32610ed
JS
15982 { } /* end */
15983};
15984
15985static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
15986 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15987 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15988
15989 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15990
15991 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15992 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15993 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15994
15995 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15996 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15997 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15998
15999 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16000 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16001
16002 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16003 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16004
f32610ed
JS
16005 { } /* end */
16006};
16007
bdd148a3
KY
16008static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16009 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16010 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16011 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16012
16013 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16014
16015 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
16016 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16017 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16018
16019 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
16020 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16021 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16022
16023 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16024 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16025
16026 { } /* end */
16027};
16028
b419f346
TD
16029/* Pin assignment: Speaker=0x14, HP = 0x15,
16030 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
16031 */
16032static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16033 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16034 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16035 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16036 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
16037 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16038 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16039 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16040 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16041 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16042 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16043 { } /* end */
16044};
16045
d1a991a6
KY
16046/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16047 * Front Mic=0x18, ATAPI Mic = 0x19,
16048 */
16049static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16050 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16051 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16052 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16053 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16054 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16055 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16056 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16057 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16058
d1a991a6
KY
16059 { } /* end */
16060};
16061
f32610ed
JS
16062/*
16063 * generic initialization of ADC, input mixers and output mixers
16064 */
16065static struct hda_verb alc861vd_volume_init_verbs[] = {
16066 /*
16067 * Unmute ADC0 and set the default input to mic-in
16068 */
16069 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16070 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16071
16072 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16073 * the analog-loopback mixer widget
16074 */
16075 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16076 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16077 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16078 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16079 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16080 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16081
16082 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16083 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16084 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16085 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16087
16088 /*
16089 * Set up output mixers (0x02 - 0x05)
16090 */
16091 /* set vol=0 to output mixers */
16092 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16093 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16094 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16095 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16096
16097 /* set up input amps for analog loopback */
16098 /* Amp Indices: DAC = 0, mixer = 1 */
16099 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16100 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16101 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16102 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16103 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16104 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16105 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16106 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16107
16108 { }
16109};
16110
16111/*
16112 * 3-stack pin configuration:
16113 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16114 */
16115static struct hda_verb alc861vd_3stack_init_verbs[] = {
16116 /*
16117 * Set pin mode and muting
16118 */
16119 /* set front pin widgets 0x14 for output */
16120 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16121 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16122 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16123
16124 /* Mic (rear) pin: input vref at 80% */
16125 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16126 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16127 /* Front Mic pin: input vref at 80% */
16128 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16129 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16130 /* Line In pin: input */
16131 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16132 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16133 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16134 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16135 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16136 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16137 /* CD pin widget for input */
16138 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16139
16140 { }
16141};
16142
16143/*
16144 * 6-stack pin configuration:
16145 */
16146static struct hda_verb alc861vd_6stack_init_verbs[] = {
16147 /*
16148 * Set pin mode and muting
16149 */
16150 /* set front pin widgets 0x14 for output */
16151 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16152 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16153 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16154
16155 /* Rear Pin: output 1 (0x0d) */
16156 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16157 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16158 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16159 /* CLFE Pin: output 2 (0x0e) */
16160 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16161 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16162 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16163 /* Side Pin: output 3 (0x0f) */
16164 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16165 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16166 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16167
16168 /* Mic (rear) pin: input vref at 80% */
16169 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16170 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16171 /* Front Mic pin: input vref at 80% */
16172 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16173 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16174 /* Line In pin: input */
16175 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16176 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16177 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16178 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16179 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16180 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16181 /* CD pin widget for input */
16182 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16183
16184 { }
16185};
16186
bdd148a3
KY
16187static struct hda_verb alc861vd_eapd_verbs[] = {
16188 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16189 { }
16190};
16191
f9423e7a
KY
16192static struct hda_verb alc660vd_eapd_verbs[] = {
16193 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16194 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16195 { }
16196};
16197
bdd148a3
KY
16198static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16199 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16200 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16201 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16202 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16203 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16204 {}
16205};
16206
bdd148a3
KY
16207static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
16208{
16209 unsigned int present;
16210 unsigned char bits;
16211
864f92be 16212 present = snd_hda_jack_detect(codec, 0x18);
47fd830a 16213 bits = present ? HDA_AMP_MUTE : 0;
864f92be 16214
47fd830a
TI
16215 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
16216 HDA_AMP_MUTE, bits);
bdd148a3
KY
16217}
16218
4f5d1706 16219static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16220{
a9fd4f3f 16221 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16222 spec->autocfg.hp_pins[0] = 0x1b;
16223 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
16224}
16225
16226static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16227{
a9fd4f3f 16228 alc_automute_amp(codec);
bdd148a3
KY
16229 alc861vd_lenovo_mic_automute(codec);
16230}
16231
16232static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16233 unsigned int res)
16234{
16235 switch (res >> 26) {
bdd148a3
KY
16236 case ALC880_MIC_EVENT:
16237 alc861vd_lenovo_mic_automute(codec);
16238 break;
a9fd4f3f
TI
16239 default:
16240 alc_automute_amp_unsol_event(codec, res);
16241 break;
bdd148a3
KY
16242 }
16243}
16244
272a527c
KY
16245static struct hda_verb alc861vd_dallas_verbs[] = {
16246 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16247 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16248 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16249 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16250
16251 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16252 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16253 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16254 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16255 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16256 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16257 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16258 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16259
272a527c
KY
16260 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16261 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16262 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16263 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16264 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16265 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16266 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16267 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16268
16269 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16270 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16271 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16272 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16273 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16274 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16275 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16276 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16277
16278 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16279 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16280 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16281 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16282
16283 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16284 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16285 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16286
16287 { } /* end */
16288};
16289
16290/* toggle speaker-output according to the hp-jack state */
4f5d1706 16291static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16292{
a9fd4f3f 16293 struct alc_spec *spec = codec->spec;
272a527c 16294
a9fd4f3f
TI
16295 spec->autocfg.hp_pins[0] = 0x15;
16296 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
16297}
16298
cb53c626
TI
16299#ifdef CONFIG_SND_HDA_POWER_SAVE
16300#define alc861vd_loopbacks alc880_loopbacks
16301#endif
16302
def319f9 16303/* pcm configuration: identical with ALC880 */
f32610ed
JS
16304#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16305#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16306#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16307#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16308
16309/*
16310 * configuration and preset
16311 */
16312static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
16313 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16314 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16315 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16316 [ALC861VD_3ST] = "3stack",
16317 [ALC861VD_3ST_DIG] = "3stack-digout",
16318 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16319 [ALC861VD_LENOVO] = "lenovo",
272a527c 16320 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16321 [ALC861VD_HP] = "hp",
f32610ed
JS
16322 [ALC861VD_AUTO] = "auto",
16323};
16324
16325static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16326 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16327 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16328 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16329 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16330 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16331 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16332 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16333 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16334 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16335 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16336 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16337 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16338 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16339 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16340 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16341 {}
16342};
16343
16344static struct alc_config_preset alc861vd_presets[] = {
16345 [ALC660VD_3ST] = {
16346 .mixers = { alc861vd_3st_mixer },
16347 .init_verbs = { alc861vd_volume_init_verbs,
16348 alc861vd_3stack_init_verbs },
16349 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16350 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16351 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16352 .channel_mode = alc861vd_3stack_2ch_modes,
16353 .input_mux = &alc861vd_capture_source,
16354 },
6963f84c
MC
16355 [ALC660VD_3ST_DIG] = {
16356 .mixers = { alc861vd_3st_mixer },
16357 .init_verbs = { alc861vd_volume_init_verbs,
16358 alc861vd_3stack_init_verbs },
16359 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16360 .dac_nids = alc660vd_dac_nids,
16361 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16362 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16363 .channel_mode = alc861vd_3stack_2ch_modes,
16364 .input_mux = &alc861vd_capture_source,
16365 },
f32610ed
JS
16366 [ALC861VD_3ST] = {
16367 .mixers = { alc861vd_3st_mixer },
16368 .init_verbs = { alc861vd_volume_init_verbs,
16369 alc861vd_3stack_init_verbs },
16370 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16371 .dac_nids = alc861vd_dac_nids,
16372 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16373 .channel_mode = alc861vd_3stack_2ch_modes,
16374 .input_mux = &alc861vd_capture_source,
16375 },
16376 [ALC861VD_3ST_DIG] = {
16377 .mixers = { alc861vd_3st_mixer },
16378 .init_verbs = { alc861vd_volume_init_verbs,
16379 alc861vd_3stack_init_verbs },
16380 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16381 .dac_nids = alc861vd_dac_nids,
16382 .dig_out_nid = ALC861VD_DIGOUT_NID,
16383 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16384 .channel_mode = alc861vd_3stack_2ch_modes,
16385 .input_mux = &alc861vd_capture_source,
16386 },
16387 [ALC861VD_6ST_DIG] = {
16388 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16389 .init_verbs = { alc861vd_volume_init_verbs,
16390 alc861vd_6stack_init_verbs },
16391 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16392 .dac_nids = alc861vd_dac_nids,
16393 .dig_out_nid = ALC861VD_DIGOUT_NID,
16394 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16395 .channel_mode = alc861vd_6stack_modes,
16396 .input_mux = &alc861vd_capture_source,
16397 },
bdd148a3
KY
16398 [ALC861VD_LENOVO] = {
16399 .mixers = { alc861vd_lenovo_mixer },
16400 .init_verbs = { alc861vd_volume_init_verbs,
16401 alc861vd_3stack_init_verbs,
16402 alc861vd_eapd_verbs,
16403 alc861vd_lenovo_unsol_verbs },
16404 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16405 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16406 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16407 .channel_mode = alc861vd_3stack_2ch_modes,
16408 .input_mux = &alc861vd_capture_source,
16409 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16410 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16411 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16412 },
272a527c
KY
16413 [ALC861VD_DALLAS] = {
16414 .mixers = { alc861vd_dallas_mixer },
16415 .init_verbs = { alc861vd_dallas_verbs },
16416 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16417 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16418 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16419 .channel_mode = alc861vd_3stack_2ch_modes,
16420 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 16421 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16422 .setup = alc861vd_dallas_setup,
16423 .init_hook = alc_automute_amp,
d1a991a6
KY
16424 },
16425 [ALC861VD_HP] = {
16426 .mixers = { alc861vd_hp_mixer },
16427 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16428 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16429 .dac_nids = alc861vd_dac_nids,
d1a991a6 16430 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
16431 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16432 .channel_mode = alc861vd_3stack_2ch_modes,
16433 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 16434 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16435 .setup = alc861vd_dallas_setup,
16436 .init_hook = alc_automute_amp,
ea1fb29a 16437 },
13c94744
TI
16438 [ALC660VD_ASUS_V1S] = {
16439 .mixers = { alc861vd_lenovo_mixer },
16440 .init_verbs = { alc861vd_volume_init_verbs,
16441 alc861vd_3stack_init_verbs,
16442 alc861vd_eapd_verbs,
16443 alc861vd_lenovo_unsol_verbs },
16444 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16445 .dac_nids = alc660vd_dac_nids,
16446 .dig_out_nid = ALC861VD_DIGOUT_NID,
16447 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16448 .channel_mode = alc861vd_3stack_2ch_modes,
16449 .input_mux = &alc861vd_capture_source,
16450 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16451 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16452 .init_hook = alc861vd_lenovo_init_hook,
13c94744 16453 },
f32610ed
JS
16454};
16455
16456/*
16457 * BIOS auto configuration
16458 */
05f5f477
TI
16459static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16460 const struct auto_pin_cfg *cfg)
16461{
6227cdce 16462 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
05f5f477
TI
16463}
16464
16465
f32610ed
JS
16466static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
16467 hda_nid_t nid, int pin_type, int dac_idx)
16468{
f6c7e546 16469 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
16470}
16471
16472static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
16473{
16474 struct alc_spec *spec = codec->spec;
16475 int i;
16476
16477 for (i = 0; i <= HDA_SIDE; i++) {
16478 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16479 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
16480 if (nid)
16481 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 16482 pin_type, i);
f32610ed
JS
16483 }
16484}
16485
16486
16487static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
16488{
16489 struct alc_spec *spec = codec->spec;
16490 hda_nid_t pin;
16491
16492 pin = spec->autocfg.hp_pins[0];
def319f9 16493 if (pin) /* connect to front and use dac 0 */
f32610ed 16494 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
16495 pin = spec->autocfg.speaker_pins[0];
16496 if (pin)
16497 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
16498}
16499
f32610ed
JS
16500#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
16501
16502static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
16503{
16504 struct alc_spec *spec = codec->spec;
16505 int i;
16506
16507 for (i = 0; i < AUTO_PIN_LAST; i++) {
16508 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 16509 if (alc_is_input_pin(codec, nid)) {
23f0c048 16510 alc_set_input_pin(codec, nid, i);
e82c025b
TI
16511 if (nid != ALC861VD_PIN_CD_NID &&
16512 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
16513 snd_hda_codec_write(codec, nid, 0,
16514 AC_VERB_SET_AMP_GAIN_MUTE,
16515 AMP_OUT_MUTE);
16516 }
16517 }
16518}
16519
f511b01c
TI
16520#define alc861vd_auto_init_input_src alc882_auto_init_input_src
16521
f32610ed
JS
16522#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16523#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16524
16525/* add playback controls from the parsed DAC table */
16526/* Based on ALC880 version. But ALC861VD has separate,
16527 * different NIDs for mute/unmute switch and volume control */
16528static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16529 const struct auto_pin_cfg *cfg)
16530{
f32610ed
JS
16531 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
16532 hda_nid_t nid_v, nid_s;
16533 int i, err;
16534
16535 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 16536 if (!spec->multiout.dac_nids[i])
f32610ed
JS
16537 continue;
16538 nid_v = alc861vd_idx_to_mixer_vol(
16539 alc880_dac_to_idx(
16540 spec->multiout.dac_nids[i]));
16541 nid_s = alc861vd_idx_to_mixer_switch(
16542 alc880_dac_to_idx(
16543 spec->multiout.dac_nids[i]));
16544
16545 if (i == 2) {
16546 /* Center/LFE */
0afe5f89
TI
16547 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16548 "Center",
f12ab1e0
TI
16549 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16550 HDA_OUTPUT));
16551 if (err < 0)
f32610ed 16552 return err;
0afe5f89
TI
16553 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16554 "LFE",
f12ab1e0
TI
16555 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16556 HDA_OUTPUT));
16557 if (err < 0)
f32610ed 16558 return err;
0afe5f89
TI
16559 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16560 "Center",
f12ab1e0
TI
16561 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
16562 HDA_INPUT));
16563 if (err < 0)
f32610ed 16564 return err;
0afe5f89
TI
16565 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16566 "LFE",
f12ab1e0
TI
16567 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
16568 HDA_INPUT));
16569 if (err < 0)
f32610ed
JS
16570 return err;
16571 } else {
a4fcd491
TI
16572 const char *pfx;
16573 if (cfg->line_outs == 1 &&
16574 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
16575 if (!cfg->hp_pins)
16576 pfx = "Speaker";
16577 else
16578 pfx = "PCM";
16579 } else
16580 pfx = chname[i];
0afe5f89 16581 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16582 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16583 HDA_OUTPUT));
16584 if (err < 0)
f32610ed 16585 return err;
a4fcd491
TI
16586 if (cfg->line_outs == 1 &&
16587 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
16588 pfx = "Speaker";
0afe5f89 16589 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
bdd148a3 16590 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
16591 HDA_INPUT));
16592 if (err < 0)
f32610ed
JS
16593 return err;
16594 }
16595 }
16596 return 0;
16597}
16598
16599/* add playback controls for speaker and HP outputs */
16600/* Based on ALC880 version. But ALC861VD has separate,
16601 * different NIDs for mute/unmute switch and volume control */
16602static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16603 hda_nid_t pin, const char *pfx)
16604{
16605 hda_nid_t nid_v, nid_s;
16606 int err;
f32610ed 16607
f12ab1e0 16608 if (!pin)
f32610ed
JS
16609 return 0;
16610
16611 if (alc880_is_fixed_pin(pin)) {
16612 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16613 /* specify the DAC as the extra output */
f12ab1e0 16614 if (!spec->multiout.hp_nid)
f32610ed
JS
16615 spec->multiout.hp_nid = nid_v;
16616 else
16617 spec->multiout.extra_out_nid[0] = nid_v;
16618 /* control HP volume/switch on the output mixer amp */
16619 nid_v = alc861vd_idx_to_mixer_vol(
16620 alc880_fixed_pin_idx(pin));
16621 nid_s = alc861vd_idx_to_mixer_switch(
16622 alc880_fixed_pin_idx(pin));
16623
0afe5f89 16624 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16625 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
16626 if (err < 0)
f32610ed 16627 return err;
0afe5f89 16628 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
16629 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
16630 if (err < 0)
f32610ed
JS
16631 return err;
16632 } else if (alc880_is_multi_pin(pin)) {
16633 /* set manual connection */
16634 /* we have only a switch on HP-out PIN */
0afe5f89 16635 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
16636 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16637 if (err < 0)
f32610ed
JS
16638 return err;
16639 }
16640 return 0;
16641}
16642
16643/* parse the BIOS configuration and set up the alc_spec
16644 * return 1 if successful, 0 if the proper config is not found,
16645 * or a negative error code
16646 * Based on ALC880 version - had to change it to override
16647 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
16648static int alc861vd_parse_auto_config(struct hda_codec *codec)
16649{
16650 struct alc_spec *spec = codec->spec;
16651 int err;
16652 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
16653
f12ab1e0
TI
16654 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16655 alc861vd_ignore);
16656 if (err < 0)
f32610ed 16657 return err;
f12ab1e0 16658 if (!spec->autocfg.line_outs)
f32610ed
JS
16659 return 0; /* can't find valid BIOS pin config */
16660
f12ab1e0
TI
16661 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16662 if (err < 0)
16663 return err;
16664 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
16665 if (err < 0)
16666 return err;
16667 err = alc861vd_auto_create_extra_out(spec,
16668 spec->autocfg.speaker_pins[0],
16669 "Speaker");
16670 if (err < 0)
16671 return err;
16672 err = alc861vd_auto_create_extra_out(spec,
16673 spec->autocfg.hp_pins[0],
16674 "Headphone");
16675 if (err < 0)
16676 return err;
05f5f477 16677 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16678 if (err < 0)
f32610ed
JS
16679 return err;
16680
16681 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16682
757899ac 16683 alc_auto_parse_digital(codec);
f32610ed 16684
603c4019 16685 if (spec->kctls.list)
d88897ea 16686 add_mixer(spec, spec->kctls.list);
f32610ed 16687
d88897ea 16688 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
16689
16690 spec->num_mux_defs = 1;
61b9b9b1 16691 spec->input_mux = &spec->private_imux[0];
f32610ed 16692
776e184e
TI
16693 err = alc_auto_add_mic_boost(codec);
16694 if (err < 0)
16695 return err;
16696
6227cdce 16697 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 16698
f32610ed
JS
16699 return 1;
16700}
16701
16702/* additional initialization for auto-configuration model */
16703static void alc861vd_auto_init(struct hda_codec *codec)
16704{
f6c7e546 16705 struct alc_spec *spec = codec->spec;
f32610ed
JS
16706 alc861vd_auto_init_multi_out(codec);
16707 alc861vd_auto_init_hp_out(codec);
16708 alc861vd_auto_init_analog_input(codec);
f511b01c 16709 alc861vd_auto_init_input_src(codec);
757899ac 16710 alc_auto_init_digital(codec);
f6c7e546 16711 if (spec->unsol_event)
7fb0d78f 16712 alc_inithook(codec);
f32610ed
JS
16713}
16714
f8f25ba3
TI
16715enum {
16716 ALC660VD_FIX_ASUS_GPIO1
16717};
16718
16719/* reset GPIO1 */
16720static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
16721 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
16722 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
16723 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
16724 { }
16725};
16726
16727static const struct alc_fixup alc861vd_fixups[] = {
16728 [ALC660VD_FIX_ASUS_GPIO1] = {
16729 .verbs = alc660vd_fix_asus_gpio1_verbs,
16730 },
16731};
16732
16733static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
16734 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
16735 {}
16736};
16737
f32610ed
JS
16738static int patch_alc861vd(struct hda_codec *codec)
16739{
16740 struct alc_spec *spec;
16741 int err, board_config;
16742
16743 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16744 if (spec == NULL)
16745 return -ENOMEM;
16746
16747 codec->spec = spec;
16748
16749 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
16750 alc861vd_models,
16751 alc861vd_cfg_tbl);
16752
16753 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
16754 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16755 codec->chip_name);
f32610ed
JS
16756 board_config = ALC861VD_AUTO;
16757 }
16758
7fa90e87
TI
16759 if (board_config == ALC861VD_AUTO)
16760 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
f8f25ba3 16761
f32610ed
JS
16762 if (board_config == ALC861VD_AUTO) {
16763 /* automatic parse from the BIOS config */
16764 err = alc861vd_parse_auto_config(codec);
16765 if (err < 0) {
16766 alc_free(codec);
16767 return err;
f12ab1e0 16768 } else if (!err) {
f32610ed
JS
16769 printk(KERN_INFO
16770 "hda_codec: Cannot set up configuration "
16771 "from BIOS. Using base mode...\n");
16772 board_config = ALC861VD_3ST;
16773 }
16774 }
16775
680cd536
KK
16776 err = snd_hda_attach_beep_device(codec, 0x23);
16777 if (err < 0) {
16778 alc_free(codec);
16779 return err;
16780 }
16781
f32610ed 16782 if (board_config != ALC861VD_AUTO)
e9c364c0 16783 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 16784
2f893286 16785 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 16786 /* always turn on EAPD */
d88897ea 16787 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
16788 }
16789
f32610ed
JS
16790 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
16791 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
16792
f32610ed
JS
16793 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
16794 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
16795
dd704698
TI
16796 if (!spec->adc_nids) {
16797 spec->adc_nids = alc861vd_adc_nids;
16798 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
16799 }
16800 if (!spec->capsrc_nids)
16801 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 16802
b59bdf3b 16803 set_capture_mixer(codec);
45bdd1c1 16804 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 16805
2134ea4f
TI
16806 spec->vmaster_nid = 0x02;
16807
7fa90e87
TI
16808 if (board_config == ALC861VD_AUTO)
16809 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
16810
f32610ed
JS
16811 codec->patch_ops = alc_patch_ops;
16812
16813 if (board_config == ALC861VD_AUTO)
16814 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
16815#ifdef CONFIG_SND_HDA_POWER_SAVE
16816 if (!spec->loopback.amplist)
16817 spec->loopback.amplist = alc861vd_loopbacks;
16818#endif
f32610ed
JS
16819
16820 return 0;
16821}
16822
bc9f98a9
KY
16823/*
16824 * ALC662 support
16825 *
16826 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
16827 * configuration. Each pin widget can choose any input DACs and a mixer.
16828 * Each ADC is connected from a mixer of all inputs. This makes possible
16829 * 6-channel independent captures.
16830 *
16831 * In addition, an independent DAC for the multi-playback (not used in this
16832 * driver yet).
16833 */
16834#define ALC662_DIGOUT_NID 0x06
16835#define ALC662_DIGIN_NID 0x0a
16836
16837static hda_nid_t alc662_dac_nids[4] = {
16838 /* front, rear, clfe, rear_surr */
16839 0x02, 0x03, 0x04
16840};
16841
622e84cd
KY
16842static hda_nid_t alc272_dac_nids[2] = {
16843 0x02, 0x03
16844};
16845
b59bdf3b 16846static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 16847 /* ADC1-2 */
b59bdf3b 16848 0x09, 0x08
bc9f98a9 16849};
e1406348 16850
622e84cd
KY
16851static hda_nid_t alc272_adc_nids[1] = {
16852 /* ADC1-2 */
16853 0x08,
16854};
16855
b59bdf3b 16856static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
16857static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
16858
e1406348 16859
bc9f98a9
KY
16860/* input MUX */
16861/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
16862static struct hda_input_mux alc662_capture_source = {
16863 .num_items = 4,
16864 .items = {
16865 { "Mic", 0x0 },
16866 { "Front Mic", 0x1 },
16867 { "Line", 0x2 },
16868 { "CD", 0x4 },
16869 },
16870};
16871
16872static struct hda_input_mux alc662_lenovo_101e_capture_source = {
16873 .num_items = 2,
16874 .items = {
16875 { "Mic", 0x1 },
16876 { "Line", 0x2 },
16877 },
16878};
291702f0 16879
6dda9f4a
KY
16880static struct hda_input_mux alc663_capture_source = {
16881 .num_items = 3,
16882 .items = {
16883 { "Mic", 0x0 },
16884 { "Front Mic", 0x1 },
16885 { "Line", 0x2 },
16886 },
16887};
16888
4f5d1706 16889#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
16890static struct hda_input_mux alc272_nc10_capture_source = {
16891 .num_items = 16,
16892 .items = {
16893 { "Autoselect Mic", 0x0 },
16894 { "Internal Mic", 0x1 },
16895 { "In-0x02", 0x2 },
16896 { "In-0x03", 0x3 },
16897 { "In-0x04", 0x4 },
16898 { "In-0x05", 0x5 },
16899 { "In-0x06", 0x6 },
16900 { "In-0x07", 0x7 },
16901 { "In-0x08", 0x8 },
16902 { "In-0x09", 0x9 },
16903 { "In-0x0a", 0x0a },
16904 { "In-0x0b", 0x0b },
16905 { "In-0x0c", 0x0c },
16906 { "In-0x0d", 0x0d },
16907 { "In-0x0e", 0x0e },
16908 { "In-0x0f", 0x0f },
16909 },
16910};
16911#endif
16912
bc9f98a9
KY
16913/*
16914 * 2ch mode
16915 */
16916static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
16917 { 2, NULL }
16918};
16919
16920/*
16921 * 2ch mode
16922 */
16923static struct hda_verb alc662_3ST_ch2_init[] = {
16924 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
16925 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16926 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
16927 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16928 { } /* end */
16929};
16930
16931/*
16932 * 6ch mode
16933 */
16934static struct hda_verb alc662_3ST_ch6_init[] = {
16935 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16936 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16937 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
16938 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16939 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16940 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
16941 { } /* end */
16942};
16943
16944static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
16945 { 2, alc662_3ST_ch2_init },
16946 { 6, alc662_3ST_ch6_init },
16947};
16948
16949/*
16950 * 2ch mode
16951 */
16952static struct hda_verb alc662_sixstack_ch6_init[] = {
16953 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16954 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16955 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16956 { } /* end */
16957};
16958
16959/*
16960 * 6ch mode
16961 */
16962static struct hda_verb alc662_sixstack_ch8_init[] = {
16963 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16964 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16965 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16966 { } /* end */
16967};
16968
16969static struct hda_channel_mode alc662_5stack_modes[2] = {
16970 { 2, alc662_sixstack_ch6_init },
16971 { 6, alc662_sixstack_ch8_init },
16972};
16973
16974/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16975 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16976 */
16977
16978static struct snd_kcontrol_new alc662_base_mixer[] = {
16979 /* output mixer control */
16980 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 16981 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 16982 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 16983 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
16984 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16985 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
16986 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16987 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
16988 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16989
16990 /*Input mixer control */
16991 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
16992 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
16993 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
16994 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
16995 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
16996 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
16997 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
16998 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
16999 { } /* end */
17000};
17001
17002static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17003 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17004 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17005 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17006 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17007 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17008 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17009 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17010 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17011 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17012 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17013 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17014 { } /* end */
17015};
17016
17017static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17018 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17019 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17020 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17021 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17022 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17023 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17024 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17025 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17026 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17027 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17028 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17029 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17030 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17031 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17032 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17033 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17034 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17035 { } /* end */
17036};
17037
17038static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17039 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17040 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17041 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17042 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17043 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17044 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17045 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17046 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17047 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17048 { } /* end */
17049};
17050
291702f0 17051static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17052 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17053 ALC262_HIPPO_MASTER_SWITCH,
291702f0
KY
17054
17055 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
17056 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17057 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17058
17059 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
17060 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17061 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17062 { } /* end */
17063};
17064
8c427226 17065static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17066 ALC262_HIPPO_MASTER_SWITCH,
17067 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17068 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17069 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17070 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17071 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17072 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17073 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17074 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17075 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17076 { } /* end */
17077};
17078
f1d4e28b
KY
17079static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17080 .ops = &snd_hda_bind_vol,
17081 .values = {
17082 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17083 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17084 0
17085 },
17086};
17087
17088static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17089 .ops = &snd_hda_bind_sw,
17090 .values = {
17091 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17092 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17093 0
17094 },
17095};
17096
6dda9f4a 17097static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17098 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17099 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17100 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17101 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17102 { } /* end */
17103};
17104
17105static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17106 .ops = &snd_hda_bind_sw,
17107 .values = {
17108 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17109 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17110 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17111 0
17112 },
17113};
17114
17115static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17116 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17117 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17118 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17119 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17120 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17121 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17122
17123 { } /* end */
17124};
17125
17126static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17127 .ops = &snd_hda_bind_sw,
17128 .values = {
17129 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17130 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17131 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17132 0
17133 },
17134};
17135
17136static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17137 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17138 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17139 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17140 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17141 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17142 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17143 { } /* end */
17144};
17145
17146static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17147 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17148 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17149 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17150 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17151 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17152 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17153 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17154 { } /* end */
17155};
17156
17157static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17158 .ops = &snd_hda_bind_vol,
17159 .values = {
17160 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17161 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17162 0
17163 },
17164};
17165
17166static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17167 .ops = &snd_hda_bind_sw,
17168 .values = {
17169 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17170 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17171 0
17172 },
17173};
17174
17175static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17176 HDA_BIND_VOL("Master Playback Volume",
17177 &alc663_asus_two_bind_master_vol),
17178 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17179 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17180 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17181 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17182 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17183 { } /* end */
17184};
17185
17186static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17187 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17188 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17189 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17190 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17191 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17192 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17193 { } /* end */
17194};
17195
17196static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17197 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17198 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17199 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17200 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17201 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17202
17203 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17204 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17205 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17206 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17207 { } /* end */
17208};
17209
17210static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17211 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17212 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17213 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17214
17215 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17216 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17217 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17218 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17219 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17220 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17221 { } /* end */
17222};
17223
ebb83eeb
KY
17224static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17225 .ops = &snd_hda_bind_sw,
17226 .values = {
17227 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17228 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17229 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17230 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17231 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17232 0
17233 },
17234};
17235
17236static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17237 .ops = &snd_hda_bind_sw,
17238 .values = {
17239 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17240 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17241 0
17242 },
17243};
17244
17245static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17246 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17247 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17248 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17249 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17250 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17251 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17252 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17253 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17254 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17255 { } /* end */
17256};
17257
17258static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17259 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17260 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17261 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17262 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17263 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17264 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17265 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17266 { } /* end */
17267};
17268
17269
bc9f98a9
KY
17270static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17271 {
17272 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17273 .name = "Channel Mode",
17274 .info = alc_ch_mode_info,
17275 .get = alc_ch_mode_get,
17276 .put = alc_ch_mode_put,
17277 },
17278 { } /* end */
17279};
17280
17281static struct hda_verb alc662_init_verbs[] = {
17282 /* ADC: mute amp left and right */
17283 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17284 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17285
b60dd394
KY
17286 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17287 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17288 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17289 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17290 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17291 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17292
17293 /* Front Pin: output 0 (0x0c) */
17294 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17295 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17296
17297 /* Rear Pin: output 1 (0x0d) */
17298 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17299 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17300
17301 /* CLFE Pin: output 2 (0x0e) */
17302 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17303 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17304
17305 /* Mic (rear) pin: input vref at 80% */
17306 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17307 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17308 /* Front Mic pin: input vref at 80% */
17309 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17310 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17311 /* Line In pin: input */
17312 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17313 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17314 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17315 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17316 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17317 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17318 /* CD pin widget for input */
17319 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17320
17321 /* FIXME: use matrix-type input source selection */
17322 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17323 /* Input mixer */
17324 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17325 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
17326
17327 /* always trun on EAPD */
17328 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17329 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17330
bc9f98a9
KY
17331 { }
17332};
17333
cec27c89
KY
17334static struct hda_verb alc663_init_verbs[] = {
17335 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17336 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17337 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17338 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17339 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17340 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17341 { }
17342};
17343
17344static struct hda_verb alc272_init_verbs[] = {
17345 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17346 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17347 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17348 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17349 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17350 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17351 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17352 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17353 { }
17354};
17355
bc9f98a9
KY
17356static struct hda_verb alc662_sue_init_verbs[] = {
17357 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17358 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17359 {}
17360};
17361
17362static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17363 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17364 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17365 {}
bc9f98a9
KY
17366};
17367
8c427226
KY
17368/* Set Unsolicited Event*/
17369static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17370 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17371 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17372 {}
17373};
17374
6dda9f4a 17375static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17376 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17377 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17378 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17379 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17380 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17381 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17382 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17383 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17384 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17385 {}
17386};
17387
17388static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17389 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17390 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17391 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17392 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17393 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17394 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17395 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17396 {}
17397};
17398
17399static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17400 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17401 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17402 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17403 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17404 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17405 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17406 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17407 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17408 {}
17409};
6dda9f4a 17410
f1d4e28b
KY
17411static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17412 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17413 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17414 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17415 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17416 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17417 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17418 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17419 {}
17420};
6dda9f4a 17421
f1d4e28b
KY
17422static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17423 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17424 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17425 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17426 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17427 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17428 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17429 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17430 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17431 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
17432 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17433 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
17434 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17435 {}
17436};
17437
17438static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17439 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17440 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17441 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17442 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17443 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17444 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17445 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17446 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17447 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17448 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17449 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17450 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
17451 {}
17452};
17453
17454static struct hda_verb alc663_g71v_init_verbs[] = {
17455 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17456 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17457 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17458
17459 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17460 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17461 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17462
17463 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17464 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17465 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17466 {}
17467};
17468
17469static struct hda_verb alc663_g50v_init_verbs[] = {
17470 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17471 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17472 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17473
17474 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17475 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17476 {}
17477};
17478
f1d4e28b
KY
17479static struct hda_verb alc662_ecs_init_verbs[] = {
17480 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17481 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17482 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17483 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17484 {}
17485};
17486
622e84cd
KY
17487static struct hda_verb alc272_dell_zm1_init_verbs[] = {
17488 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17489 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17490 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17491 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17492 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17493 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17494 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17495 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17496 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17497 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17498 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17499 {}
17500};
17501
17502static struct hda_verb alc272_dell_init_verbs[] = {
17503 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17504 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17505 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17506 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17507 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17508 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17509 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17510 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17511 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17512 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17513 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17514 {}
17515};
17516
ebb83eeb
KY
17517static struct hda_verb alc663_mode7_init_verbs[] = {
17518 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17519 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17520 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17521 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17522 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17523 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17524 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17525 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17526 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17527 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17528 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17529 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17530 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17531 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17532 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17533 {}
17534};
17535
17536static struct hda_verb alc663_mode8_init_verbs[] = {
17537 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17538 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17539 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17540 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17541 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17542 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17543 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17544 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17545 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17546 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17547 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17548 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17549 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17550 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17551 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17552 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17553 {}
17554};
17555
f1d4e28b
KY
17556static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17557 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17558 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17559 { } /* end */
17560};
17561
622e84cd
KY
17562static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17563 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17564 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17565 { } /* end */
17566};
17567
bc9f98a9
KY
17568static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
17569{
17570 unsigned int present;
f12ab1e0 17571 unsigned char bits;
bc9f98a9 17572
864f92be 17573 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 17574 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17575
47fd830a
TI
17576 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17577 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17578}
17579
17580static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
17581{
17582 unsigned int present;
f12ab1e0 17583 unsigned char bits;
bc9f98a9 17584
864f92be 17585 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 17586 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17587
47fd830a
TI
17588 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17589 HDA_AMP_MUTE, bits);
17590 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17591 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17592}
17593
17594static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
17595 unsigned int res)
17596{
17597 if ((res >> 26) == ALC880_HP_EVENT)
17598 alc662_lenovo_101e_all_automute(codec);
17599 if ((res >> 26) == ALC880_FRONT_EVENT)
17600 alc662_lenovo_101e_ispeaker_automute(codec);
17601}
17602
291702f0
KY
17603/* unsolicited event for HP jack sensing */
17604static void alc662_eeepc_unsol_event(struct hda_codec *codec,
17605 unsigned int res)
17606{
291702f0 17607 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 17608 alc_mic_automute(codec);
42171c17
TI
17609 else
17610 alc262_hippo_unsol_event(codec, res);
291702f0
KY
17611}
17612
4f5d1706
TI
17613static void alc662_eeepc_setup(struct hda_codec *codec)
17614{
17615 struct alc_spec *spec = codec->spec;
17616
17617 alc262_hippo1_setup(codec);
17618 spec->ext_mic.pin = 0x18;
17619 spec->ext_mic.mux_idx = 0;
17620 spec->int_mic.pin = 0x19;
17621 spec->int_mic.mux_idx = 1;
17622 spec->auto_mic = 1;
17623}
17624
291702f0
KY
17625static void alc662_eeepc_inithook(struct hda_codec *codec)
17626{
4f5d1706
TI
17627 alc262_hippo_automute(codec);
17628 alc_mic_automute(codec);
291702f0
KY
17629}
17630
4f5d1706 17631static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 17632{
42171c17
TI
17633 struct alc_spec *spec = codec->spec;
17634
17635 spec->autocfg.hp_pins[0] = 0x14;
17636 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
17637}
17638
4f5d1706
TI
17639#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
17640
6dda9f4a
KY
17641static void alc663_m51va_speaker_automute(struct hda_codec *codec)
17642{
17643 unsigned int present;
17644 unsigned char bits;
17645
864f92be 17646 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 17647 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 17648 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17649 HDA_AMP_MUTE, bits);
f1d4e28b 17650 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17651 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17652}
17653
17654static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
17655{
17656 unsigned int present;
17657 unsigned char bits;
17658
864f92be 17659 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
17660 bits = present ? HDA_AMP_MUTE : 0;
17661 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17662 HDA_AMP_MUTE, bits);
f1d4e28b 17663 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17664 HDA_AMP_MUTE, bits);
f1d4e28b 17665 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 17666 HDA_AMP_MUTE, bits);
f1d4e28b 17667 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 17668 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17669}
17670
17671static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
17672{
17673 unsigned int present;
17674 unsigned char bits;
17675
864f92be 17676 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17677 bits = present ? HDA_AMP_MUTE : 0;
17678 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17679 HDA_AMP_MUTE, bits);
f1d4e28b 17680 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17681 HDA_AMP_MUTE, bits);
f1d4e28b 17682 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 17683 HDA_AMP_MUTE, bits);
f1d4e28b 17684 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 17685 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17686}
17687
17688static void alc662_f5z_speaker_automute(struct hda_codec *codec)
17689{
17690 unsigned int present;
17691 unsigned char bits;
17692
864f92be 17693 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
17694 bits = present ? 0 : PIN_OUT;
17695 snd_hda_codec_write(codec, 0x14, 0,
17696 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
17697}
17698
17699static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
17700{
17701 unsigned int present1, present2;
17702
864f92be
WF
17703 present1 = snd_hda_jack_detect(codec, 0x21);
17704 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17705
17706 if (present1 || present2) {
17707 snd_hda_codec_write_cache(codec, 0x14, 0,
17708 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17709 } else {
17710 snd_hda_codec_write_cache(codec, 0x14, 0,
17711 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17712 }
17713}
17714
17715static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
17716{
17717 unsigned int present1, present2;
17718
864f92be
WF
17719 present1 = snd_hda_jack_detect(codec, 0x1b);
17720 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17721
17722 if (present1 || present2) {
17723 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17724 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 17725 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17726 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
17727 } else {
17728 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17729 HDA_AMP_MUTE, 0);
f1d4e28b 17730 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17731 HDA_AMP_MUTE, 0);
f1d4e28b 17732 }
6dda9f4a
KY
17733}
17734
ebb83eeb
KY
17735static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
17736{
17737 unsigned int present1, present2;
17738
17739 present1 = snd_hda_codec_read(codec, 0x1b, 0,
17740 AC_VERB_GET_PIN_SENSE, 0)
17741 & AC_PINSENSE_PRESENCE;
17742 present2 = snd_hda_codec_read(codec, 0x21, 0,
17743 AC_VERB_GET_PIN_SENSE, 0)
17744 & AC_PINSENSE_PRESENCE;
17745
17746 if (present1 || present2) {
17747 snd_hda_codec_write_cache(codec, 0x14, 0,
17748 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17749 snd_hda_codec_write_cache(codec, 0x17, 0,
17750 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17751 } else {
17752 snd_hda_codec_write_cache(codec, 0x14, 0,
17753 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17754 snd_hda_codec_write_cache(codec, 0x17, 0,
17755 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17756 }
17757}
17758
17759static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
17760{
17761 unsigned int present1, present2;
17762
17763 present1 = snd_hda_codec_read(codec, 0x21, 0,
17764 AC_VERB_GET_PIN_SENSE, 0)
17765 & AC_PINSENSE_PRESENCE;
17766 present2 = snd_hda_codec_read(codec, 0x15, 0,
17767 AC_VERB_GET_PIN_SENSE, 0)
17768 & AC_PINSENSE_PRESENCE;
17769
17770 if (present1 || present2) {
17771 snd_hda_codec_write_cache(codec, 0x14, 0,
17772 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17773 snd_hda_codec_write_cache(codec, 0x17, 0,
17774 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17775 } else {
17776 snd_hda_codec_write_cache(codec, 0x14, 0,
17777 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17778 snd_hda_codec_write_cache(codec, 0x17, 0,
17779 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17780 }
17781}
17782
6dda9f4a
KY
17783static void alc663_m51va_unsol_event(struct hda_codec *codec,
17784 unsigned int res)
17785{
17786 switch (res >> 26) {
17787 case ALC880_HP_EVENT:
17788 alc663_m51va_speaker_automute(codec);
17789 break;
17790 case ALC880_MIC_EVENT:
4f5d1706 17791 alc_mic_automute(codec);
6dda9f4a
KY
17792 break;
17793 }
17794}
17795
4f5d1706
TI
17796static void alc663_m51va_setup(struct hda_codec *codec)
17797{
17798 struct alc_spec *spec = codec->spec;
17799 spec->ext_mic.pin = 0x18;
17800 spec->ext_mic.mux_idx = 0;
17801 spec->int_mic.pin = 0x12;
ebb83eeb 17802 spec->int_mic.mux_idx = 9;
4f5d1706
TI
17803 spec->auto_mic = 1;
17804}
17805
6dda9f4a
KY
17806static void alc663_m51va_inithook(struct hda_codec *codec)
17807{
17808 alc663_m51va_speaker_automute(codec);
4f5d1706 17809 alc_mic_automute(codec);
6dda9f4a
KY
17810}
17811
f1d4e28b 17812/* ***************** Mode1 ******************************/
4f5d1706 17813#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
17814
17815static void alc663_mode1_setup(struct hda_codec *codec)
17816{
17817 struct alc_spec *spec = codec->spec;
17818 spec->ext_mic.pin = 0x18;
17819 spec->ext_mic.mux_idx = 0;
17820 spec->int_mic.pin = 0x19;
17821 spec->int_mic.mux_idx = 1;
17822 spec->auto_mic = 1;
17823}
17824
4f5d1706 17825#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 17826
f1d4e28b
KY
17827/* ***************** Mode2 ******************************/
17828static void alc662_mode2_unsol_event(struct hda_codec *codec,
17829 unsigned int res)
17830{
17831 switch (res >> 26) {
17832 case ALC880_HP_EVENT:
17833 alc662_f5z_speaker_automute(codec);
17834 break;
17835 case ALC880_MIC_EVENT:
4f5d1706 17836 alc_mic_automute(codec);
f1d4e28b
KY
17837 break;
17838 }
17839}
17840
ebb83eeb 17841#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 17842
f1d4e28b
KY
17843static void alc662_mode2_inithook(struct hda_codec *codec)
17844{
17845 alc662_f5z_speaker_automute(codec);
4f5d1706 17846 alc_mic_automute(codec);
f1d4e28b
KY
17847}
17848/* ***************** Mode3 ******************************/
17849static void alc663_mode3_unsol_event(struct hda_codec *codec,
17850 unsigned int res)
17851{
17852 switch (res >> 26) {
17853 case ALC880_HP_EVENT:
17854 alc663_two_hp_m1_speaker_automute(codec);
17855 break;
17856 case ALC880_MIC_EVENT:
4f5d1706 17857 alc_mic_automute(codec);
f1d4e28b
KY
17858 break;
17859 }
17860}
17861
ebb83eeb 17862#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 17863
f1d4e28b
KY
17864static void alc663_mode3_inithook(struct hda_codec *codec)
17865{
17866 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 17867 alc_mic_automute(codec);
f1d4e28b
KY
17868}
17869/* ***************** Mode4 ******************************/
17870static void alc663_mode4_unsol_event(struct hda_codec *codec,
17871 unsigned int res)
17872{
17873 switch (res >> 26) {
17874 case ALC880_HP_EVENT:
17875 alc663_21jd_two_speaker_automute(codec);
17876 break;
17877 case ALC880_MIC_EVENT:
4f5d1706 17878 alc_mic_automute(codec);
f1d4e28b
KY
17879 break;
17880 }
17881}
17882
ebb83eeb 17883#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 17884
f1d4e28b
KY
17885static void alc663_mode4_inithook(struct hda_codec *codec)
17886{
17887 alc663_21jd_two_speaker_automute(codec);
4f5d1706 17888 alc_mic_automute(codec);
f1d4e28b
KY
17889}
17890/* ***************** Mode5 ******************************/
17891static void alc663_mode5_unsol_event(struct hda_codec *codec,
17892 unsigned int res)
17893{
17894 switch (res >> 26) {
17895 case ALC880_HP_EVENT:
17896 alc663_15jd_two_speaker_automute(codec);
17897 break;
17898 case ALC880_MIC_EVENT:
4f5d1706 17899 alc_mic_automute(codec);
f1d4e28b
KY
17900 break;
17901 }
17902}
17903
ebb83eeb 17904#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 17905
f1d4e28b
KY
17906static void alc663_mode5_inithook(struct hda_codec *codec)
17907{
17908 alc663_15jd_two_speaker_automute(codec);
4f5d1706 17909 alc_mic_automute(codec);
f1d4e28b
KY
17910}
17911/* ***************** Mode6 ******************************/
17912static void alc663_mode6_unsol_event(struct hda_codec *codec,
17913 unsigned int res)
17914{
17915 switch (res >> 26) {
17916 case ALC880_HP_EVENT:
17917 alc663_two_hp_m2_speaker_automute(codec);
17918 break;
17919 case ALC880_MIC_EVENT:
4f5d1706 17920 alc_mic_automute(codec);
f1d4e28b
KY
17921 break;
17922 }
17923}
17924
ebb83eeb 17925#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 17926
f1d4e28b
KY
17927static void alc663_mode6_inithook(struct hda_codec *codec)
17928{
17929 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 17930 alc_mic_automute(codec);
f1d4e28b
KY
17931}
17932
ebb83eeb
KY
17933/* ***************** Mode7 ******************************/
17934static void alc663_mode7_unsol_event(struct hda_codec *codec,
17935 unsigned int res)
17936{
17937 switch (res >> 26) {
17938 case ALC880_HP_EVENT:
17939 alc663_two_hp_m7_speaker_automute(codec);
17940 break;
17941 case ALC880_MIC_EVENT:
17942 alc_mic_automute(codec);
17943 break;
17944 }
17945}
17946
17947#define alc663_mode7_setup alc663_mode1_setup
17948
17949static void alc663_mode7_inithook(struct hda_codec *codec)
17950{
17951 alc663_two_hp_m7_speaker_automute(codec);
17952 alc_mic_automute(codec);
17953}
17954
17955/* ***************** Mode8 ******************************/
17956static void alc663_mode8_unsol_event(struct hda_codec *codec,
17957 unsigned int res)
17958{
17959 switch (res >> 26) {
17960 case ALC880_HP_EVENT:
17961 alc663_two_hp_m8_speaker_automute(codec);
17962 break;
17963 case ALC880_MIC_EVENT:
17964 alc_mic_automute(codec);
17965 break;
17966 }
17967}
17968
17969#define alc663_mode8_setup alc663_m51va_setup
17970
17971static void alc663_mode8_inithook(struct hda_codec *codec)
17972{
17973 alc663_two_hp_m8_speaker_automute(codec);
17974 alc_mic_automute(codec);
17975}
17976
6dda9f4a
KY
17977static void alc663_g71v_hp_automute(struct hda_codec *codec)
17978{
17979 unsigned int present;
17980 unsigned char bits;
17981
864f92be 17982 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
17983 bits = present ? HDA_AMP_MUTE : 0;
17984 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17985 HDA_AMP_MUTE, bits);
17986 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17987 HDA_AMP_MUTE, bits);
17988}
17989
17990static void alc663_g71v_front_automute(struct hda_codec *codec)
17991{
17992 unsigned int present;
17993 unsigned char bits;
17994
864f92be 17995 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
17996 bits = present ? HDA_AMP_MUTE : 0;
17997 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17998 HDA_AMP_MUTE, bits);
17999}
18000
18001static void alc663_g71v_unsol_event(struct hda_codec *codec,
18002 unsigned int res)
18003{
18004 switch (res >> 26) {
18005 case ALC880_HP_EVENT:
18006 alc663_g71v_hp_automute(codec);
18007 break;
18008 case ALC880_FRONT_EVENT:
18009 alc663_g71v_front_automute(codec);
18010 break;
18011 case ALC880_MIC_EVENT:
4f5d1706 18012 alc_mic_automute(codec);
6dda9f4a
KY
18013 break;
18014 }
18015}
18016
4f5d1706
TI
18017#define alc663_g71v_setup alc663_m51va_setup
18018
6dda9f4a
KY
18019static void alc663_g71v_inithook(struct hda_codec *codec)
18020{
18021 alc663_g71v_front_automute(codec);
18022 alc663_g71v_hp_automute(codec);
4f5d1706 18023 alc_mic_automute(codec);
6dda9f4a
KY
18024}
18025
18026static void alc663_g50v_unsol_event(struct hda_codec *codec,
18027 unsigned int res)
18028{
18029 switch (res >> 26) {
18030 case ALC880_HP_EVENT:
18031 alc663_m51va_speaker_automute(codec);
18032 break;
18033 case ALC880_MIC_EVENT:
4f5d1706 18034 alc_mic_automute(codec);
6dda9f4a
KY
18035 break;
18036 }
18037}
18038
4f5d1706
TI
18039#define alc663_g50v_setup alc663_m51va_setup
18040
6dda9f4a
KY
18041static void alc663_g50v_inithook(struct hda_codec *codec)
18042{
18043 alc663_m51va_speaker_automute(codec);
4f5d1706 18044 alc_mic_automute(codec);
6dda9f4a
KY
18045}
18046
f1d4e28b
KY
18047static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18048 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18049 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b
KY
18050
18051 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
18052 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18053 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18054
18055 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
18056 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18057 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18058 { } /* end */
18059};
18060
9541ba1d
CP
18061static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18062 /* Master Playback automatically created from Speaker and Headphone */
18063 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18064 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18065 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18066 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18067
18068 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18069 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18070 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
18071
18072 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18073 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18074 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
18075 { } /* end */
18076};
18077
cb53c626
TI
18078#ifdef CONFIG_SND_HDA_POWER_SAVE
18079#define alc662_loopbacks alc880_loopbacks
18080#endif
18081
bc9f98a9 18082
def319f9 18083/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18084#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18085#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18086#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18087#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18088
18089/*
18090 * configuration and preset
18091 */
18092static const char *alc662_models[ALC662_MODEL_LAST] = {
18093 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18094 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18095 [ALC662_3ST_6ch] = "3stack-6ch",
18096 [ALC662_5ST_DIG] = "6stack-dig",
18097 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18098 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18099 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18100 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18101 [ALC663_ASUS_M51VA] = "m51va",
18102 [ALC663_ASUS_G71V] = "g71v",
18103 [ALC663_ASUS_H13] = "h13",
18104 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18105 [ALC663_ASUS_MODE1] = "asus-mode1",
18106 [ALC662_ASUS_MODE2] = "asus-mode2",
18107 [ALC663_ASUS_MODE3] = "asus-mode3",
18108 [ALC663_ASUS_MODE4] = "asus-mode4",
18109 [ALC663_ASUS_MODE5] = "asus-mode5",
18110 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18111 [ALC663_ASUS_MODE7] = "asus-mode7",
18112 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18113 [ALC272_DELL] = "dell",
18114 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18115 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18116 [ALC662_AUTO] = "auto",
18117};
18118
18119static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18120 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18121 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18122 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18123 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18124 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18125 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18126 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18127 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18128 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18129 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18130 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18131 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18132 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18133 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18134 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18135 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18136 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18137 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18138 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18139 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18140 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18141 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18142 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18143 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18144 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18145 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18146 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18147 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18148 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18149 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18150 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18151 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18152 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18153 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18154 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18155 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18156 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18157 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18158 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18159 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18160 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18161 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18162 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18163 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18164 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18165 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18166 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18167 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18168 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18169 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18170 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18171 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18172 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18173 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18174 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18175 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18176 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18177 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18178 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18179 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18180 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18181 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18182 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18183 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18184 ALC662_3ST_6ch_DIG),
4dee8baa 18185 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18186 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
18187 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18188 ALC662_3ST_6ch_DIG),
6227cdce 18189 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18190 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18191 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18192 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18193 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18194 ALC662_3ST_6ch_DIG),
dea0a509
TI
18195 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18196 ALC663_ASUS_H13),
bc9f98a9
KY
18197 {}
18198};
18199
18200static struct alc_config_preset alc662_presets[] = {
18201 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18202 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
18203 .init_verbs = { alc662_init_verbs },
18204 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18205 .dac_nids = alc662_dac_nids,
18206 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18207 .dig_in_nid = ALC662_DIGIN_NID,
18208 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18209 .channel_mode = alc662_3ST_2ch_modes,
18210 .input_mux = &alc662_capture_source,
18211 },
18212 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18213 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18214 .init_verbs = { alc662_init_verbs },
18215 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18216 .dac_nids = alc662_dac_nids,
18217 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18218 .dig_in_nid = ALC662_DIGIN_NID,
18219 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18220 .channel_mode = alc662_3ST_6ch_modes,
18221 .need_dac_fix = 1,
18222 .input_mux = &alc662_capture_source,
f12ab1e0 18223 },
bc9f98a9 18224 [ALC662_3ST_6ch] = {
f9e336f6 18225 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18226 .init_verbs = { alc662_init_verbs },
18227 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18228 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18229 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18230 .channel_mode = alc662_3ST_6ch_modes,
18231 .need_dac_fix = 1,
18232 .input_mux = &alc662_capture_source,
f12ab1e0 18233 },
bc9f98a9 18234 [ALC662_5ST_DIG] = {
f9e336f6 18235 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18236 .init_verbs = { alc662_init_verbs },
18237 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18238 .dac_nids = alc662_dac_nids,
18239 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18240 .dig_in_nid = ALC662_DIGIN_NID,
18241 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18242 .channel_mode = alc662_5stack_modes,
18243 .input_mux = &alc662_capture_source,
18244 },
18245 [ALC662_LENOVO_101E] = {
f9e336f6 18246 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
18247 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18248 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18249 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18250 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18251 .channel_mode = alc662_3ST_2ch_modes,
18252 .input_mux = &alc662_lenovo_101e_capture_source,
18253 .unsol_event = alc662_lenovo_101e_unsol_event,
18254 .init_hook = alc662_lenovo_101e_all_automute,
18255 },
291702f0 18256 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18257 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
18258 .init_verbs = { alc662_init_verbs,
18259 alc662_eeepc_sue_init_verbs },
18260 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18261 .dac_nids = alc662_dac_nids,
291702f0
KY
18262 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18263 .channel_mode = alc662_3ST_2ch_modes,
291702f0 18264 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18265 .setup = alc662_eeepc_setup,
291702f0
KY
18266 .init_hook = alc662_eeepc_inithook,
18267 },
8c427226 18268 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18269 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18270 alc662_chmode_mixer },
18271 .init_verbs = { alc662_init_verbs,
18272 alc662_eeepc_ep20_sue_init_verbs },
18273 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18274 .dac_nids = alc662_dac_nids,
8c427226
KY
18275 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18276 .channel_mode = alc662_3ST_6ch_modes,
18277 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 18278 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18279 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
18280 .init_hook = alc662_eeepc_ep20_inithook,
18281 },
f1d4e28b 18282 [ALC662_ECS] = {
f9e336f6 18283 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
18284 .init_verbs = { alc662_init_verbs,
18285 alc662_ecs_init_verbs },
18286 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18287 .dac_nids = alc662_dac_nids,
18288 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18289 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18290 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18291 .setup = alc662_eeepc_setup,
f1d4e28b
KY
18292 .init_hook = alc662_eeepc_inithook,
18293 },
6dda9f4a 18294 [ALC663_ASUS_M51VA] = {
f9e336f6 18295 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18296 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18297 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18298 .dac_nids = alc662_dac_nids,
18299 .dig_out_nid = ALC662_DIGOUT_NID,
18300 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18301 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18302 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18303 .setup = alc663_m51va_setup,
6dda9f4a
KY
18304 .init_hook = alc663_m51va_inithook,
18305 },
18306 [ALC663_ASUS_G71V] = {
f9e336f6 18307 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
18308 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18309 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18310 .dac_nids = alc662_dac_nids,
18311 .dig_out_nid = ALC662_DIGOUT_NID,
18312 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18313 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18314 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 18315 .setup = alc663_g71v_setup,
6dda9f4a
KY
18316 .init_hook = alc663_g71v_inithook,
18317 },
18318 [ALC663_ASUS_H13] = {
f9e336f6 18319 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18320 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18321 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18322 .dac_nids = alc662_dac_nids,
18323 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18324 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
18325 .unsol_event = alc663_m51va_unsol_event,
18326 .init_hook = alc663_m51va_inithook,
18327 },
18328 [ALC663_ASUS_G50V] = {
f9e336f6 18329 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
18330 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18331 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18332 .dac_nids = alc662_dac_nids,
18333 .dig_out_nid = ALC662_DIGOUT_NID,
18334 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18335 .channel_mode = alc662_3ST_6ch_modes,
18336 .input_mux = &alc663_capture_source,
18337 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 18338 .setup = alc663_g50v_setup,
6dda9f4a
KY
18339 .init_hook = alc663_g50v_inithook,
18340 },
f1d4e28b 18341 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18342 .mixers = { alc663_m51va_mixer },
18343 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18344 .init_verbs = { alc662_init_verbs,
18345 alc663_21jd_amic_init_verbs },
18346 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18347 .hp_nid = 0x03,
18348 .dac_nids = alc662_dac_nids,
18349 .dig_out_nid = ALC662_DIGOUT_NID,
18350 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18351 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18352 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18353 .setup = alc663_mode1_setup,
f1d4e28b
KY
18354 .init_hook = alc663_mode1_inithook,
18355 },
18356 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18357 .mixers = { alc662_1bjd_mixer },
18358 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18359 .init_verbs = { alc662_init_verbs,
18360 alc662_1bjd_amic_init_verbs },
18361 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18362 .dac_nids = alc662_dac_nids,
18363 .dig_out_nid = ALC662_DIGOUT_NID,
18364 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18365 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18366 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18367 .setup = alc662_mode2_setup,
f1d4e28b
KY
18368 .init_hook = alc662_mode2_inithook,
18369 },
18370 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18371 .mixers = { alc663_two_hp_m1_mixer },
18372 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18373 .init_verbs = { alc662_init_verbs,
18374 alc663_two_hp_amic_m1_init_verbs },
18375 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18376 .hp_nid = 0x03,
18377 .dac_nids = alc662_dac_nids,
18378 .dig_out_nid = ALC662_DIGOUT_NID,
18379 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18380 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18381 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 18382 .setup = alc663_mode3_setup,
f1d4e28b
KY
18383 .init_hook = alc663_mode3_inithook,
18384 },
18385 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18386 .mixers = { alc663_asus_21jd_clfe_mixer },
18387 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18388 .init_verbs = { alc662_init_verbs,
18389 alc663_21jd_amic_init_verbs},
18390 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18391 .hp_nid = 0x03,
18392 .dac_nids = alc662_dac_nids,
18393 .dig_out_nid = ALC662_DIGOUT_NID,
18394 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18395 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18396 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18397 .setup = alc663_mode4_setup,
f1d4e28b
KY
18398 .init_hook = alc663_mode4_inithook,
18399 },
18400 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18401 .mixers = { alc663_asus_15jd_clfe_mixer },
18402 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18403 .init_verbs = { alc662_init_verbs,
18404 alc663_15jd_amic_init_verbs },
18405 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18406 .hp_nid = 0x03,
18407 .dac_nids = alc662_dac_nids,
18408 .dig_out_nid = ALC662_DIGOUT_NID,
18409 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18410 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18411 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 18412 .setup = alc663_mode5_setup,
f1d4e28b
KY
18413 .init_hook = alc663_mode5_inithook,
18414 },
18415 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18416 .mixers = { alc663_two_hp_m2_mixer },
18417 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18418 .init_verbs = { alc662_init_verbs,
18419 alc663_two_hp_amic_m2_init_verbs },
18420 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18421 .hp_nid = 0x03,
18422 .dac_nids = alc662_dac_nids,
18423 .dig_out_nid = ALC662_DIGOUT_NID,
18424 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18425 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18426 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 18427 .setup = alc663_mode6_setup,
f1d4e28b
KY
18428 .init_hook = alc663_mode6_inithook,
18429 },
ebb83eeb
KY
18430 [ALC663_ASUS_MODE7] = {
18431 .mixers = { alc663_mode7_mixer },
18432 .cap_mixer = alc662_auto_capture_mixer,
18433 .init_verbs = { alc662_init_verbs,
18434 alc663_mode7_init_verbs },
18435 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18436 .hp_nid = 0x03,
18437 .dac_nids = alc662_dac_nids,
18438 .dig_out_nid = ALC662_DIGOUT_NID,
18439 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18440 .channel_mode = alc662_3ST_2ch_modes,
18441 .unsol_event = alc663_mode7_unsol_event,
18442 .setup = alc663_mode7_setup,
18443 .init_hook = alc663_mode7_inithook,
18444 },
18445 [ALC663_ASUS_MODE8] = {
18446 .mixers = { alc663_mode8_mixer },
18447 .cap_mixer = alc662_auto_capture_mixer,
18448 .init_verbs = { alc662_init_verbs,
18449 alc663_mode8_init_verbs },
18450 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18451 .hp_nid = 0x03,
18452 .dac_nids = alc662_dac_nids,
18453 .dig_out_nid = ALC662_DIGOUT_NID,
18454 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18455 .channel_mode = alc662_3ST_2ch_modes,
18456 .unsol_event = alc663_mode8_unsol_event,
18457 .setup = alc663_mode8_setup,
18458 .init_hook = alc663_mode8_inithook,
18459 },
622e84cd
KY
18460 [ALC272_DELL] = {
18461 .mixers = { alc663_m51va_mixer },
18462 .cap_mixer = alc272_auto_capture_mixer,
18463 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
18464 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18465 .dac_nids = alc662_dac_nids,
18466 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18467 .adc_nids = alc272_adc_nids,
18468 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18469 .capsrc_nids = alc272_capsrc_nids,
18470 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18471 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18472 .setup = alc663_m51va_setup,
622e84cd
KY
18473 .init_hook = alc663_m51va_inithook,
18474 },
18475 [ALC272_DELL_ZM1] = {
18476 .mixers = { alc663_m51va_mixer },
18477 .cap_mixer = alc662_auto_capture_mixer,
18478 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
18479 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18480 .dac_nids = alc662_dac_nids,
18481 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18482 .adc_nids = alc662_adc_nids,
b59bdf3b 18483 .num_adc_nids = 1,
622e84cd
KY
18484 .capsrc_nids = alc662_capsrc_nids,
18485 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18486 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18487 .setup = alc663_m51va_setup,
622e84cd
KY
18488 .init_hook = alc663_m51va_inithook,
18489 },
9541ba1d
CP
18490 [ALC272_SAMSUNG_NC10] = {
18491 .mixers = { alc272_nc10_mixer },
18492 .init_verbs = { alc662_init_verbs,
18493 alc663_21jd_amic_init_verbs },
18494 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18495 .dac_nids = alc272_dac_nids,
18496 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18497 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18498 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 18499 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18500 .setup = alc663_mode4_setup,
9541ba1d
CP
18501 .init_hook = alc663_mode4_inithook,
18502 },
bc9f98a9
KY
18503};
18504
18505
18506/*
18507 * BIOS auto configuration
18508 */
18509
7085ec12
TI
18510/* convert from MIX nid to DAC */
18511static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
18512{
18513 if (nid == 0x0f)
18514 return 0x02;
18515 else if (nid >= 0x0c && nid <= 0x0e)
18516 return nid - 0x0c + 0x02;
18517 else
18518 return 0;
18519}
18520
18521/* get MIX nid connected to the given pin targeted to DAC */
18522static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18523 hda_nid_t dac)
18524{
18525 hda_nid_t mix[4];
18526 int i, num;
18527
18528 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18529 for (i = 0; i < num; i++) {
18530 if (alc662_mix_to_dac(mix[i]) == dac)
18531 return mix[i];
18532 }
18533 return 0;
18534}
18535
18536/* look for an empty DAC slot */
18537static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18538{
18539 struct alc_spec *spec = codec->spec;
18540 hda_nid_t srcs[5];
18541 int i, j, num;
18542
18543 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18544 if (num < 0)
18545 return 0;
18546 for (i = 0; i < num; i++) {
18547 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
18548 if (!nid)
18549 continue;
18550 for (j = 0; j < spec->multiout.num_dacs; j++)
18551 if (spec->multiout.dac_nids[j] == nid)
18552 break;
18553 if (j >= spec->multiout.num_dacs)
18554 return nid;
18555 }
18556 return 0;
18557}
18558
18559/* fill in the dac_nids table from the parsed pin configuration */
18560static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18561 const struct auto_pin_cfg *cfg)
18562{
18563 struct alc_spec *spec = codec->spec;
18564 int i;
18565 hda_nid_t dac;
18566
18567 spec->multiout.dac_nids = spec->private_dac_nids;
18568 for (i = 0; i < cfg->line_outs; i++) {
18569 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
18570 if (!dac)
18571 continue;
18572 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
18573 }
18574 return 0;
18575}
18576
0afe5f89 18577static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18578 hda_nid_t nid, unsigned int chs)
18579{
0afe5f89 18580 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
7085ec12
TI
18581 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18582}
18583
0afe5f89 18584static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18585 hda_nid_t nid, unsigned int chs)
18586{
0afe5f89 18587 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12
TI
18588 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18589}
18590
18591#define alc662_add_stereo_vol(spec, pfx, nid) \
18592 alc662_add_vol_ctl(spec, pfx, nid, 3)
18593#define alc662_add_stereo_sw(spec, pfx, nid) \
18594 alc662_add_sw_ctl(spec, pfx, nid, 3)
18595
bc9f98a9 18596/* add playback controls from the parsed DAC table */
7085ec12 18597static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
18598 const struct auto_pin_cfg *cfg)
18599{
7085ec12 18600 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18601 static const char *chname[4] = {
18602 "Front", "Surround", NULL /*CLFE*/, "Side"
18603 };
7085ec12 18604 hda_nid_t nid, mix;
bc9f98a9
KY
18605 int i, err;
18606
18607 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
18608 nid = spec->multiout.dac_nids[i];
18609 if (!nid)
18610 continue;
18611 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
18612 if (!mix)
bc9f98a9 18613 continue;
bc9f98a9
KY
18614 if (i == 2) {
18615 /* Center/LFE */
7085ec12 18616 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
18617 if (err < 0)
18618 return err;
7085ec12 18619 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
18620 if (err < 0)
18621 return err;
7085ec12 18622 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
18623 if (err < 0)
18624 return err;
7085ec12 18625 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
18626 if (err < 0)
18627 return err;
18628 } else {
0d884cb9
TI
18629 const char *pfx;
18630 if (cfg->line_outs == 1 &&
18631 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
7085ec12 18632 if (cfg->hp_outs)
0d884cb9
TI
18633 pfx = "Speaker";
18634 else
18635 pfx = "PCM";
18636 } else
18637 pfx = chname[i];
7085ec12 18638 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
bc9f98a9
KY
18639 if (err < 0)
18640 return err;
0d884cb9
TI
18641 if (cfg->line_outs == 1 &&
18642 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
18643 pfx = "Speaker";
7085ec12 18644 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
bc9f98a9
KY
18645 if (err < 0)
18646 return err;
18647 }
18648 }
18649 return 0;
18650}
18651
18652/* add playback controls for speaker and HP outputs */
7085ec12
TI
18653/* return DAC nid if any new DAC is assigned */
18654static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
18655 const char *pfx)
18656{
7085ec12
TI
18657 struct alc_spec *spec = codec->spec;
18658 hda_nid_t nid, mix;
bc9f98a9 18659 int err;
bc9f98a9
KY
18660
18661 if (!pin)
18662 return 0;
7085ec12
TI
18663 nid = alc662_look_for_dac(codec, pin);
18664 if (!nid) {
7085ec12
TI
18665 /* the corresponding DAC is already occupied */
18666 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18667 return 0; /* no way */
18668 /* create a switch only */
0afe5f89 18669 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 18670 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
18671 }
18672
7085ec12
TI
18673 mix = alc662_dac_to_mix(codec, pin, nid);
18674 if (!mix)
18675 return 0;
18676 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
18677 if (err < 0)
18678 return err;
18679 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
18680 if (err < 0)
18681 return err;
18682 return nid;
bc9f98a9
KY
18683}
18684
18685/* create playback/capture controls for input pins */
05f5f477 18686#define alc662_auto_create_input_ctls \
4b7348a1 18687 alc882_auto_create_input_ctls
bc9f98a9
KY
18688
18689static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
18690 hda_nid_t nid, int pin_type,
7085ec12 18691 hda_nid_t dac)
bc9f98a9 18692{
7085ec12 18693 int i, num;
ce503f38 18694 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 18695
f6c7e546 18696 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 18697 /* need the manual connection? */
7085ec12
TI
18698 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
18699 if (num <= 1)
18700 return;
18701 for (i = 0; i < num; i++) {
18702 if (alc662_mix_to_dac(srcs[i]) != dac)
18703 continue;
18704 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
18705 return;
bc9f98a9
KY
18706 }
18707}
18708
18709static void alc662_auto_init_multi_out(struct hda_codec *codec)
18710{
18711 struct alc_spec *spec = codec->spec;
7085ec12 18712 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
18713 int i;
18714
18715 for (i = 0; i <= HDA_SIDE; i++) {
18716 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18717 if (nid)
baba8ee9 18718 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 18719 spec->multiout.dac_nids[i]);
bc9f98a9
KY
18720 }
18721}
18722
18723static void alc662_auto_init_hp_out(struct hda_codec *codec)
18724{
18725 struct alc_spec *spec = codec->spec;
18726 hda_nid_t pin;
18727
18728 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
18729 if (pin)
18730 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
18731 spec->multiout.hp_nid);
f6c7e546
TI
18732 pin = spec->autocfg.speaker_pins[0];
18733 if (pin)
7085ec12
TI
18734 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
18735 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
18736}
18737
bc9f98a9
KY
18738#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
18739
18740static void alc662_auto_init_analog_input(struct hda_codec *codec)
18741{
18742 struct alc_spec *spec = codec->spec;
18743 int i;
18744
18745 for (i = 0; i < AUTO_PIN_LAST; i++) {
18746 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 18747 if (alc_is_input_pin(codec, nid)) {
23f0c048 18748 alc_set_input_pin(codec, nid, i);
52ca15b7 18749 if (nid != ALC662_PIN_CD_NID &&
e82c025b 18750 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
18751 snd_hda_codec_write(codec, nid, 0,
18752 AC_VERB_SET_AMP_GAIN_MUTE,
18753 AMP_OUT_MUTE);
18754 }
18755 }
18756}
18757
f511b01c
TI
18758#define alc662_auto_init_input_src alc882_auto_init_input_src
18759
bc9f98a9
KY
18760static int alc662_parse_auto_config(struct hda_codec *codec)
18761{
18762 struct alc_spec *spec = codec->spec;
18763 int err;
18764 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
18765
18766 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
18767 alc662_ignore);
18768 if (err < 0)
18769 return err;
18770 if (!spec->autocfg.line_outs)
18771 return 0; /* can't find valid BIOS pin config */
18772
7085ec12 18773 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
18774 if (err < 0)
18775 return err;
7085ec12 18776 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
18777 if (err < 0)
18778 return err;
7085ec12 18779 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
18780 spec->autocfg.speaker_pins[0],
18781 "Speaker");
18782 if (err < 0)
18783 return err;
7085ec12
TI
18784 if (err)
18785 spec->multiout.extra_out_nid[0] = err;
18786 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
18787 "Headphone");
18788 if (err < 0)
18789 return err;
7085ec12
TI
18790 if (err)
18791 spec->multiout.hp_nid = err;
05f5f477 18792 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 18793 if (err < 0)
bc9f98a9
KY
18794 return err;
18795
18796 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
18797
757899ac 18798 alc_auto_parse_digital(codec);
bc9f98a9 18799
603c4019 18800 if (spec->kctls.list)
d88897ea 18801 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
18802
18803 spec->num_mux_defs = 1;
61b9b9b1 18804 spec->input_mux = &spec->private_imux[0];
ea1fb29a 18805
cec27c89
KY
18806 add_verb(spec, alc662_init_verbs);
18807 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
d1eb57f4 18808 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
cec27c89
KY
18809 add_verb(spec, alc663_init_verbs);
18810
18811 if (codec->vendor_id == 0x10ec0272)
18812 add_verb(spec, alc272_init_verbs);
ee979a14
TI
18813
18814 err = alc_auto_add_mic_boost(codec);
18815 if (err < 0)
18816 return err;
18817
6227cdce
KY
18818 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18819 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18820 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18821 else
18822 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 18823
8c87286f 18824 return 1;
bc9f98a9
KY
18825}
18826
18827/* additional initialization for auto-configuration model */
18828static void alc662_auto_init(struct hda_codec *codec)
18829{
f6c7e546 18830 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18831 alc662_auto_init_multi_out(codec);
18832 alc662_auto_init_hp_out(codec);
18833 alc662_auto_init_analog_input(codec);
f511b01c 18834 alc662_auto_init_input_src(codec);
757899ac 18835 alc_auto_init_digital(codec);
f6c7e546 18836 if (spec->unsol_event)
7fb0d78f 18837 alc_inithook(codec);
bc9f98a9
KY
18838}
18839
18840static int patch_alc662(struct hda_codec *codec)
18841{
18842 struct alc_spec *spec;
18843 int err, board_config;
18844
18845 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
18846 if (!spec)
18847 return -ENOMEM;
18848
18849 codec->spec = spec;
18850
da00c244
KY
18851 alc_auto_parse_customize_define(codec);
18852
2c3bf9ab
TI
18853 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18854
c027ddcd
KY
18855 if (alc_read_coef_idx(codec, 0) == 0x8020)
18856 alc_codec_rename(codec, "ALC661");
18857 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) &&
18858 codec->bus->pci->subsystem_vendor == 0x1025 &&
18859 spec->cdefine.platform_type == 1)
18860 alc_codec_rename(codec, "ALC272X");
274693f3 18861
bc9f98a9
KY
18862 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
18863 alc662_models,
18864 alc662_cfg_tbl);
18865 if (board_config < 0) {
9a11f1aa
TI
18866 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
18867 codec->chip_name);
bc9f98a9
KY
18868 board_config = ALC662_AUTO;
18869 }
18870
18871 if (board_config == ALC662_AUTO) {
18872 /* automatic parse from the BIOS config */
18873 err = alc662_parse_auto_config(codec);
18874 if (err < 0) {
18875 alc_free(codec);
18876 return err;
8c87286f 18877 } else if (!err) {
bc9f98a9
KY
18878 printk(KERN_INFO
18879 "hda_codec: Cannot set up configuration "
18880 "from BIOS. Using base mode...\n");
18881 board_config = ALC662_3ST_2ch_DIG;
18882 }
18883 }
18884
dc1eae25 18885 if (has_cdefine_beep(codec)) {
8af2591d
TI
18886 err = snd_hda_attach_beep_device(codec, 0x1);
18887 if (err < 0) {
18888 alc_free(codec);
18889 return err;
18890 }
680cd536
KK
18891 }
18892
bc9f98a9 18893 if (board_config != ALC662_AUTO)
e9c364c0 18894 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 18895
bc9f98a9
KY
18896 spec->stream_analog_playback = &alc662_pcm_analog_playback;
18897 spec->stream_analog_capture = &alc662_pcm_analog_capture;
18898
bc9f98a9
KY
18899 spec->stream_digital_playback = &alc662_pcm_digital_playback;
18900 spec->stream_digital_capture = &alc662_pcm_digital_capture;
18901
dd704698
TI
18902 if (!spec->adc_nids) {
18903 spec->adc_nids = alc662_adc_nids;
18904 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
18905 }
18906 if (!spec->capsrc_nids)
18907 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 18908
f9e336f6 18909 if (!spec->cap_mixer)
b59bdf3b 18910 set_capture_mixer(codec);
cec27c89 18911
dc1eae25 18912 if (has_cdefine_beep(codec)) {
da00c244
KY
18913 switch (codec->vendor_id) {
18914 case 0x10ec0662:
18915 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18916 break;
18917 case 0x10ec0272:
18918 case 0x10ec0663:
18919 case 0x10ec0665:
18920 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18921 break;
18922 case 0x10ec0273:
18923 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18924 break;
18925 }
cec27c89 18926 }
2134ea4f
TI
18927 spec->vmaster_nid = 0x02;
18928
bc9f98a9
KY
18929 codec->patch_ops = alc_patch_ops;
18930 if (board_config == ALC662_AUTO)
18931 spec->init_hook = alc662_auto_init;
cb53c626
TI
18932#ifdef CONFIG_SND_HDA_POWER_SAVE
18933 if (!spec->loopback.amplist)
18934 spec->loopback.amplist = alc662_loopbacks;
18935#endif
bc9f98a9
KY
18936
18937 return 0;
18938}
18939
274693f3
KY
18940static int patch_alc888(struct hda_codec *codec)
18941{
18942 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
18943 kfree(codec->chip_name);
18944 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
18945 if (!codec->chip_name) {
18946 alc_free(codec);
274693f3 18947 return -ENOMEM;
ac2c92e0
TI
18948 }
18949 return patch_alc662(codec);
274693f3 18950 }
ac2c92e0 18951 return patch_alc882(codec);
274693f3
KY
18952}
18953
d1eb57f4
KY
18954/*
18955 * ALC680 support
18956 */
18957#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
18958#define alc680_modes alc260_modes
18959
18960static hda_nid_t alc680_dac_nids[3] = {
18961 /* Lout1, Lout2, hp */
18962 0x02, 0x03, 0x04
18963};
18964
18965static hda_nid_t alc680_adc_nids[3] = {
18966 /* ADC0-2 */
18967 /* DMIC, MIC, Line-in*/
18968 0x07, 0x08, 0x09
18969};
18970
18971static struct snd_kcontrol_new alc680_base_mixer[] = {
18972 /* output mixer control */
18973 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
18974 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18975 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
18976 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
18977 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
18978 { }
18979};
18980
18981static struct snd_kcontrol_new alc680_capture_mixer[] = {
18982 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
18983 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
18984 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
18985 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
18986 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
18987 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
18988 { } /* end */
18989};
18990
18991/*
18992 * generic initialization of ADC, input mixers and output mixers
18993 */
18994static struct hda_verb alc680_init_verbs[] = {
18995 /* Unmute DAC0-1 and set vol = 0 */
18996 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
18997 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
18998 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
18999
19000 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
19001 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
19002 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
19003 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
19004 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
19005
19006 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19007 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19008 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19009 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19010 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19011 { }
19012};
19013
19014/* create input playback/capture controls for the given pin */
19015static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19016 const char *ctlname, int idx)
19017{
19018 hda_nid_t dac;
19019 int err;
19020
19021 switch (nid) {
19022 case 0x14:
19023 dac = 0x02;
19024 break;
19025 case 0x15:
19026 dac = 0x03;
19027 break;
19028 case 0x16:
19029 dac = 0x04;
19030 break;
19031 default:
19032 return 0;
19033 }
19034 if (spec->multiout.dac_nids[0] != dac &&
19035 spec->multiout.dac_nids[1] != dac) {
19036 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19037 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19038 HDA_OUTPUT));
19039 if (err < 0)
19040 return err;
19041
19042 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19043 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19044
19045 if (err < 0)
19046 return err;
19047 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19048 }
19049
19050 return 0;
19051}
19052
19053/* add playback controls from the parsed DAC table */
19054static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19055 const struct auto_pin_cfg *cfg)
19056{
19057 hda_nid_t nid;
19058 int err;
19059
19060 spec->multiout.dac_nids = spec->private_dac_nids;
19061
19062 nid = cfg->line_out_pins[0];
19063 if (nid) {
19064 const char *name;
19065 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19066 name = "Speaker";
19067 else
19068 name = "Front";
19069 err = alc680_new_analog_output(spec, nid, name, 0);
19070 if (err < 0)
19071 return err;
19072 }
19073
19074 nid = cfg->speaker_pins[0];
19075 if (nid) {
19076 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19077 if (err < 0)
19078 return err;
19079 }
19080 nid = cfg->hp_pins[0];
19081 if (nid) {
19082 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19083 if (err < 0)
19084 return err;
19085 }
19086
19087 return 0;
19088}
19089
19090static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19091 hda_nid_t nid, int pin_type)
19092{
19093 alc_set_pin_output(codec, nid, pin_type);
19094}
19095
19096static void alc680_auto_init_multi_out(struct hda_codec *codec)
19097{
19098 struct alc_spec *spec = codec->spec;
19099 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19100 if (nid) {
19101 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19102 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19103 }
19104}
19105
19106static void alc680_auto_init_hp_out(struct hda_codec *codec)
19107{
19108 struct alc_spec *spec = codec->spec;
19109 hda_nid_t pin;
19110
19111 pin = spec->autocfg.hp_pins[0];
19112 if (pin)
19113 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19114 pin = spec->autocfg.speaker_pins[0];
19115 if (pin)
19116 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19117}
19118
19119/* pcm configuration: identical with ALC880 */
19120#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19121#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19122#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19123#define alc680_pcm_digital_playback alc880_pcm_digital_playback
19124
19125static struct hda_input_mux alc680_capture_source = {
19126 .num_items = 1,
19127 .items = {
19128 { "Mic", 0x0 },
19129 },
19130};
19131
19132/*
19133 * BIOS auto configuration
19134 */
19135static int alc680_parse_auto_config(struct hda_codec *codec)
19136{
19137 struct alc_spec *spec = codec->spec;
19138 int err;
19139 static hda_nid_t alc680_ignore[] = { 0 };
19140
19141 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19142 alc680_ignore);
19143 if (err < 0)
19144 return err;
19145 if (!spec->autocfg.line_outs) {
19146 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19147 spec->multiout.max_channels = 2;
19148 spec->no_analog = 1;
19149 goto dig_only;
19150 }
19151 return 0; /* can't find valid BIOS pin config */
19152 }
19153 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19154 if (err < 0)
19155 return err;
19156
19157 spec->multiout.max_channels = 2;
19158
19159 dig_only:
19160 /* digital only support output */
757899ac 19161 alc_auto_parse_digital(codec);
d1eb57f4
KY
19162 if (spec->kctls.list)
19163 add_mixer(spec, spec->kctls.list);
19164
19165 add_verb(spec, alc680_init_verbs);
19166 spec->num_mux_defs = 1;
19167 spec->input_mux = &alc680_capture_source;
19168
19169 err = alc_auto_add_mic_boost(codec);
19170 if (err < 0)
19171 return err;
19172
19173 return 1;
19174}
19175
19176#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19177
19178/* init callback for auto-configuration model -- overriding the default init */
19179static void alc680_auto_init(struct hda_codec *codec)
19180{
19181 struct alc_spec *spec = codec->spec;
19182 alc680_auto_init_multi_out(codec);
19183 alc680_auto_init_hp_out(codec);
19184 alc680_auto_init_analog_input(codec);
757899ac 19185 alc_auto_init_digital(codec);
d1eb57f4
KY
19186 if (spec->unsol_event)
19187 alc_inithook(codec);
19188}
19189
19190/*
19191 * configuration and preset
19192 */
19193static const char *alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19194 [ALC680_BASE] = "base",
19195 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19196};
19197
19198static struct snd_pci_quirk alc680_cfg_tbl[] = {
19199 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19200 {}
19201};
19202
19203static struct alc_config_preset alc680_presets[] = {
19204 [ALC680_BASE] = {
19205 .mixers = { alc680_base_mixer },
19206 .cap_mixer = alc680_capture_mixer,
19207 .init_verbs = { alc680_init_verbs },
19208 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19209 .dac_nids = alc680_dac_nids,
19210 .num_adc_nids = ARRAY_SIZE(alc680_adc_nids),
19211 .adc_nids = alc680_adc_nids,
19212 .hp_nid = 0x04,
19213 .dig_out_nid = ALC680_DIGOUT_NID,
19214 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19215 .channel_mode = alc680_modes,
19216 .input_mux = &alc680_capture_source,
19217 },
19218};
19219
19220static int patch_alc680(struct hda_codec *codec)
19221{
19222 struct alc_spec *spec;
19223 int board_config;
19224 int err;
19225
19226 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19227 if (spec == NULL)
19228 return -ENOMEM;
19229
19230 codec->spec = spec;
19231
19232 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19233 alc680_models,
19234 alc680_cfg_tbl);
19235
19236 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19237 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19238 codec->chip_name);
19239 board_config = ALC680_AUTO;
19240 }
19241
19242 if (board_config == ALC680_AUTO) {
19243 /* automatic parse from the BIOS config */
19244 err = alc680_parse_auto_config(codec);
19245 if (err < 0) {
19246 alc_free(codec);
19247 return err;
19248 } else if (!err) {
19249 printk(KERN_INFO
19250 "hda_codec: Cannot set up configuration "
19251 "from BIOS. Using base mode...\n");
19252 board_config = ALC680_BASE;
19253 }
19254 }
19255
19256 if (board_config != ALC680_AUTO)
19257 setup_preset(codec, &alc680_presets[board_config]);
19258
19259 spec->stream_analog_playback = &alc680_pcm_analog_playback;
19260 spec->stream_analog_capture = &alc680_pcm_analog_capture;
19261 spec->stream_analog_alt_capture = &alc680_pcm_analog_alt_capture;
19262 spec->stream_digital_playback = &alc680_pcm_digital_playback;
19263
19264 if (!spec->adc_nids) {
19265 spec->adc_nids = alc680_adc_nids;
19266 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19267 }
19268
19269 if (!spec->cap_mixer)
19270 set_capture_mixer(codec);
19271
19272 spec->vmaster_nid = 0x02;
19273
19274 codec->patch_ops = alc_patch_ops;
19275 if (board_config == ALC680_AUTO)
19276 spec->init_hook = alc680_auto_init;
19277
19278 return 0;
19279}
19280
1da177e4
LT
19281/*
19282 * patch entries
19283 */
1289e9e8 19284static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 19285 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 19286 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 19287 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 19288 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 19289 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 19290 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 19291 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 19292 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 19293 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 19294 .patch = patch_alc861 },
f32610ed
JS
19295 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19296 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19297 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 19298 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 19299 .patch = patch_alc882 },
bc9f98a9
KY
19300 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19301 .patch = patch_alc662 },
6dda9f4a 19302 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 19303 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 19304 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 19305 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 19306 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 19307 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 19308 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 19309 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 19310 .patch = patch_alc882 },
cb308f97 19311 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 19312 .patch = patch_alc882 },
df694daa 19313 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
4953550a 19314 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
4442608d 19315 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 19316 .patch = patch_alc882 },
274693f3 19317 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 19318 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 19319 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
19320 {} /* terminator */
19321};
1289e9e8
TI
19322
19323MODULE_ALIAS("snd-hda-codec-id:10ec*");
19324
19325MODULE_LICENSE("GPL");
19326MODULE_DESCRIPTION("Realtek HD-audio codec");
19327
19328static struct hda_codec_preset_list realtek_list = {
19329 .preset = snd_hda_preset_realtek,
19330 .owner = THIS_MODULE,
19331};
19332
19333static int __init patch_realtek_init(void)
19334{
19335 return snd_hda_add_codec_preset(&realtek_list);
19336}
19337
19338static void __exit patch_realtek_exit(void)
19339{
19340 snd_hda_delete_codec_preset(&realtek_list);
19341}
19342
19343module_init(patch_realtek_init)
19344module_exit(patch_realtek_exit)