]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Handle missing NID 0x1b on ALC259 codec
[mirror_ubuntu-focal-kernel.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
31#include "hda_codec.h"
32#include "hda_local.h"
680cd536 33#include "hda_beep.h"
1da177e4 34
ccc656ce
KY
35#define ALC880_FRONT_EVENT 0x01
36#define ALC880_DCVOL_EVENT 0x02
37#define ALC880_HP_EVENT 0x04
38#define ALC880_MIC_EVENT 0x08
1da177e4
LT
39
40/* ALC880 board config type */
41enum {
1da177e4
LT
42 ALC880_3ST,
43 ALC880_3ST_DIG,
44 ALC880_5ST,
45 ALC880_5ST_DIG,
46 ALC880_W810,
dfc0ff62 47 ALC880_Z71V,
b6482d48 48 ALC880_6ST,
16ded525
TI
49 ALC880_6ST_DIG,
50 ALC880_F1734,
51 ALC880_ASUS,
52 ALC880_ASUS_DIG,
53 ALC880_ASUS_W1V,
df694daa 54 ALC880_ASUS_DIG2,
2cf9f0fc 55 ALC880_FUJITSU,
16ded525 56 ALC880_UNIWILL_DIG,
ccc656ce
KY
57 ALC880_UNIWILL,
58 ALC880_UNIWILL_P53,
df694daa
KY
59 ALC880_CLEVO,
60 ALC880_TCL_S700,
ae6b813a 61 ALC880_LG,
d681518a 62 ALC880_LG_LW,
df99cd33 63 ALC880_MEDION_RIM,
e9edcee0
TI
64#ifdef CONFIG_SND_DEBUG
65 ALC880_TEST,
66#endif
df694daa 67 ALC880_AUTO,
16ded525
TI
68 ALC880_MODEL_LAST /* last tag */
69};
70
71/* ALC260 models */
72enum {
73 ALC260_BASIC,
74 ALC260_HP,
3f878308 75 ALC260_HP_DC7600,
df694daa
KY
76 ALC260_HP_3013,
77 ALC260_FUJITSU_S702X,
0bfc90e9 78 ALC260_ACER,
bc9f98a9
KY
79 ALC260_WILL,
80 ALC260_REPLACER_672V,
cc959489 81 ALC260_FAVORIT100,
7cf51e48
JW
82#ifdef CONFIG_SND_DEBUG
83 ALC260_TEST,
84#endif
df694daa 85 ALC260_AUTO,
16ded525 86 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
87};
88
df694daa
KY
89/* ALC262 models */
90enum {
91 ALC262_BASIC,
ccc656ce
KY
92 ALC262_HIPPO,
93 ALC262_HIPPO_1,
834be88d 94 ALC262_FUJITSU,
9c7f852e 95 ALC262_HP_BPC,
cd7509a4
KY
96 ALC262_HP_BPC_D7000_WL,
97 ALC262_HP_BPC_D7000_WF,
66d2a9d6 98 ALC262_HP_TC_T5735,
8c427226 99 ALC262_HP_RP5700,
304dcaac 100 ALC262_BENQ_ED8,
272a527c 101 ALC262_SONY_ASSAMD,
83c34218 102 ALC262_BENQ_T31,
f651b50b 103 ALC262_ULTRA,
0e31daf7 104 ALC262_LENOVO_3000,
e8f9ae2a 105 ALC262_NEC,
4e555fe5 106 ALC262_TOSHIBA_S06,
9f99a638 107 ALC262_TOSHIBA_RX1,
ba340e82 108 ALC262_TYAN,
df694daa
KY
109 ALC262_AUTO,
110 ALC262_MODEL_LAST /* last tag */
111};
112
a361d84b
KY
113/* ALC268 models */
114enum {
eb5a6621 115 ALC267_QUANTA_IL1,
a361d84b 116 ALC268_3ST,
d1a991a6 117 ALC268_TOSHIBA,
d273809e 118 ALC268_ACER,
c238b4f4 119 ALC268_ACER_DMIC,
8ef355da 120 ALC268_ACER_ASPIRE_ONE,
3866f0b0 121 ALC268_DELL,
f12462c5 122 ALC268_ZEPTO,
86c53bd2
JW
123#ifdef CONFIG_SND_DEBUG
124 ALC268_TEST,
125#endif
a361d84b
KY
126 ALC268_AUTO,
127 ALC268_MODEL_LAST /* last tag */
128};
129
f6a92248
KY
130/* ALC269 models */
131enum {
132 ALC269_BASIC,
60db6b53 133 ALC269_QUANTA_FL1,
84898e87
KY
134 ALC269_AMIC,
135 ALC269_DMIC,
136 ALC269VB_AMIC,
137 ALC269VB_DMIC,
26f5df26 138 ALC269_FUJITSU,
64154835 139 ALC269_LIFEBOOK,
f6a92248
KY
140 ALC269_AUTO,
141 ALC269_MODEL_LAST /* last tag */
142};
143
df694daa
KY
144/* ALC861 models */
145enum {
146 ALC861_3ST,
9c7f852e 147 ALC660_3ST,
df694daa
KY
148 ALC861_3ST_DIG,
149 ALC861_6ST_DIG,
22309c3e 150 ALC861_UNIWILL_M31,
a53d1aec 151 ALC861_TOSHIBA,
7cdbff94 152 ALC861_ASUS,
56bb0cab 153 ALC861_ASUS_LAPTOP,
df694daa
KY
154 ALC861_AUTO,
155 ALC861_MODEL_LAST,
156};
157
f32610ed
JS
158/* ALC861-VD models */
159enum {
160 ALC660VD_3ST,
6963f84c 161 ALC660VD_3ST_DIG,
13c94744 162 ALC660VD_ASUS_V1S,
f32610ed
JS
163 ALC861VD_3ST,
164 ALC861VD_3ST_DIG,
165 ALC861VD_6ST_DIG,
bdd148a3 166 ALC861VD_LENOVO,
272a527c 167 ALC861VD_DALLAS,
d1a991a6 168 ALC861VD_HP,
f32610ed
JS
169 ALC861VD_AUTO,
170 ALC861VD_MODEL_LAST,
171};
172
bc9f98a9
KY
173/* ALC662 models */
174enum {
175 ALC662_3ST_2ch_DIG,
176 ALC662_3ST_6ch_DIG,
177 ALC662_3ST_6ch,
178 ALC662_5ST_DIG,
179 ALC662_LENOVO_101E,
291702f0 180 ALC662_ASUS_EEEPC_P701,
8c427226 181 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
182 ALC663_ASUS_M51VA,
183 ALC663_ASUS_G71V,
184 ALC663_ASUS_H13,
185 ALC663_ASUS_G50V,
f1d4e28b
KY
186 ALC662_ECS,
187 ALC663_ASUS_MODE1,
188 ALC662_ASUS_MODE2,
189 ALC663_ASUS_MODE3,
190 ALC663_ASUS_MODE4,
191 ALC663_ASUS_MODE5,
192 ALC663_ASUS_MODE6,
ebb83eeb
KY
193 ALC663_ASUS_MODE7,
194 ALC663_ASUS_MODE8,
622e84cd
KY
195 ALC272_DELL,
196 ALC272_DELL_ZM1,
9541ba1d 197 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
198 ALC662_AUTO,
199 ALC662_MODEL_LAST,
200};
201
df694daa
KY
202/* ALC882 models */
203enum {
204 ALC882_3ST_DIG,
205 ALC882_6ST_DIG,
4b146cb0 206 ALC882_ARIMA,
bdd148a3 207 ALC882_W2JC,
272a527c
KY
208 ALC882_TARGA,
209 ALC882_ASUS_A7J,
914759b7 210 ALC882_ASUS_A7M,
9102cd1c 211 ALC885_MACPRO,
76e6f5a9 212 ALC885_MBA21,
87350ad0 213 ALC885_MBP3,
41d5545d 214 ALC885_MB5,
e458b1fa 215 ALC885_MACMINI3,
c54728d8 216 ALC885_IMAC24,
4b7e1803 217 ALC885_IMAC91,
9c7f852e
TI
218 ALC883_3ST_2ch_DIG,
219 ALC883_3ST_6ch_DIG,
220 ALC883_3ST_6ch,
221 ALC883_6ST_DIG,
ccc656ce
KY
222 ALC883_TARGA_DIG,
223 ALC883_TARGA_2ch_DIG,
64a8be74 224 ALC883_TARGA_8ch_DIG,
bab282b9 225 ALC883_ACER,
2880a867 226 ALC883_ACER_ASPIRE,
5b2d1eca 227 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 228 ALC888_ACER_ASPIRE_6530G,
3b315d70 229 ALC888_ACER_ASPIRE_8930G,
fc86f954 230 ALC888_ACER_ASPIRE_7730G,
c07584c8 231 ALC883_MEDION,
ea1fb29a 232 ALC883_MEDION_MD2,
7ad7b218 233 ALC883_MEDION_WIM2160,
b373bdeb 234 ALC883_LAPTOP_EAPD,
bc9f98a9 235 ALC883_LENOVO_101E_2ch,
272a527c 236 ALC883_LENOVO_NB0763,
189609ae 237 ALC888_LENOVO_MS7195_DIG,
e2757d5e 238 ALC888_LENOVO_SKY,
ea1fb29a 239 ALC883_HAIER_W66,
4723c022 240 ALC888_3ST_HP,
5795b9e6 241 ALC888_6ST_DELL,
a8848bd6 242 ALC883_MITAC,
a65cc60f 243 ALC883_CLEVO_M540R,
0c4cc443 244 ALC883_CLEVO_M720,
fb97dc67 245 ALC883_FUJITSU_PI2515,
ef8ef5fb 246 ALC888_FUJITSU_XA3530,
17bba1b7 247 ALC883_3ST_6ch_INTEL,
87a8c370
JK
248 ALC889A_INTEL,
249 ALC889_INTEL,
e2757d5e
KY
250 ALC888_ASUS_M90V,
251 ALC888_ASUS_EEE1601,
eb4c41d3 252 ALC889A_MB31,
3ab90935 253 ALC1200_ASUS_P5Q,
3e1647c5 254 ALC883_SONY_VAIO_TT,
4953550a
TI
255 ALC882_AUTO,
256 ALC882_MODEL_LAST,
9c7f852e
TI
257};
258
d4a86d81
TI
259/* ALC680 models */
260enum {
261 ALC680_BASE,
262 ALC680_AUTO,
263 ALC680_MODEL_LAST,
264};
265
df694daa
KY
266/* for GPIO Poll */
267#define GPIO_MASK 0x03
268
4a79ba34
TI
269/* extra amp-initialization sequence types */
270enum {
271 ALC_INIT_NONE,
272 ALC_INIT_DEFAULT,
273 ALC_INIT_GPIO1,
274 ALC_INIT_GPIO2,
275 ALC_INIT_GPIO3,
276};
277
6c819492
TI
278struct alc_mic_route {
279 hda_nid_t pin;
280 unsigned char mux_idx;
281 unsigned char amix_idx;
282};
283
284#define MUX_IDX_UNDEF ((unsigned char)-1)
285
da00c244
KY
286struct alc_customize_define {
287 unsigned int sku_cfg;
288 unsigned char port_connectivity;
289 unsigned char check_sum;
290 unsigned char customization;
291 unsigned char external_amp;
292 unsigned int enable_pcbeep:1;
293 unsigned int platform_type:1;
294 unsigned int swap:1;
295 unsigned int override:1;
296};
297
1da177e4
LT
298struct alc_spec {
299 /* codec parameterization */
df694daa 300 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 301 unsigned int num_mixers;
f9e336f6 302 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 303 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 304
2d9c6482 305 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
306 * don't forget NULL
307 * termination!
e9edcee0
TI
308 */
309 unsigned int num_init_verbs;
1da177e4 310
aa563af7 311 char stream_name_analog[32]; /* analog PCM stream */
1da177e4
LT
312 struct hda_pcm_stream *stream_analog_playback;
313 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
314 struct hda_pcm_stream *stream_analog_alt_playback;
315 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 316
aa563af7 317 char stream_name_digital[32]; /* digital PCM stream */
1da177e4
LT
318 struct hda_pcm_stream *stream_digital_playback;
319 struct hda_pcm_stream *stream_digital_capture;
320
321 /* playback */
16ded525
TI
322 struct hda_multi_out multiout; /* playback set-up
323 * max_channels, dacs must be set
324 * dig_out_nid and hp_nid are optional
325 */
6330079f 326 hda_nid_t alt_dac_nid;
6a05ac4a 327 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 328 int dig_out_type;
1da177e4
LT
329
330 /* capture */
331 unsigned int num_adc_nids;
332 hda_nid_t *adc_nids;
e1406348 333 hda_nid_t *capsrc_nids;
16ded525 334 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4 335
840b64c0
TI
336 /* capture setup for dynamic dual-adc switch */
337 unsigned int cur_adc_idx;
338 hda_nid_t cur_adc;
339 unsigned int cur_adc_stream_tag;
340 unsigned int cur_adc_format;
341
1da177e4 342 /* capture source */
a1e8d2da 343 unsigned int num_mux_defs;
1da177e4
LT
344 const struct hda_input_mux *input_mux;
345 unsigned int cur_mux[3];
6c819492
TI
346 struct alc_mic_route ext_mic;
347 struct alc_mic_route int_mic;
1da177e4
LT
348
349 /* channel model */
d2a6d7dc 350 const struct hda_channel_mode *channel_mode;
1da177e4 351 int num_channel_mode;
4e195a7b 352 int need_dac_fix;
3b315d70
HM
353 int const_channel_count;
354 int ext_channel_count;
1da177e4
LT
355
356 /* PCM information */
4c5186ed 357 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 358
e9edcee0
TI
359 /* dynamic controls, init_verbs and input_mux */
360 struct auto_pin_cfg autocfg;
da00c244 361 struct alc_customize_define cdefine;
603c4019 362 struct snd_array kctls;
61b9b9b1 363 struct hda_input_mux private_imux[3];
41923e44 364 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
365 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
366 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 367
ae6b813a
TI
368 /* hooks */
369 void (*init_hook)(struct hda_codec *codec);
370 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 371#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 372 void (*power_hook)(struct hda_codec *codec);
f5de24b0 373#endif
ae6b813a 374
834be88d
TI
375 /* for pin sensing */
376 unsigned int sense_updated: 1;
377 unsigned int jack_present: 1;
bec15c3a 378 unsigned int master_sw: 1;
6c819492 379 unsigned int auto_mic:1;
cb53c626 380
e64f14f4
TI
381 /* other flags */
382 unsigned int no_analog :1; /* digital I/O only */
840b64c0 383 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
4a79ba34 384 int init_amp;
e64f14f4 385
2134ea4f
TI
386 /* for virtual master */
387 hda_nid_t vmaster_nid;
cb53c626
TI
388#ifdef CONFIG_SND_HDA_POWER_SAVE
389 struct hda_loopback_check loopback;
390#endif
2c3bf9ab
TI
391
392 /* for PLL fix */
393 hda_nid_t pll_nid;
394 unsigned int pll_coef_idx, pll_coef_bit;
df694daa
KY
395};
396
397/*
398 * configuration template - to be copied to the spec instance
399 */
400struct alc_config_preset {
9c7f852e
TI
401 struct snd_kcontrol_new *mixers[5]; /* should be identical size
402 * with spec
403 */
f9e336f6 404 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
405 const struct hda_verb *init_verbs[5];
406 unsigned int num_dacs;
407 hda_nid_t *dac_nids;
408 hda_nid_t dig_out_nid; /* optional */
409 hda_nid_t hp_nid; /* optional */
b25c9da1 410 hda_nid_t *slave_dig_outs;
df694daa
KY
411 unsigned int num_adc_nids;
412 hda_nid_t *adc_nids;
e1406348 413 hda_nid_t *capsrc_nids;
df694daa
KY
414 hda_nid_t dig_in_nid;
415 unsigned int num_channel_mode;
416 const struct hda_channel_mode *channel_mode;
4e195a7b 417 int need_dac_fix;
3b315d70 418 int const_channel_count;
a1e8d2da 419 unsigned int num_mux_defs;
df694daa 420 const struct hda_input_mux *input_mux;
ae6b813a 421 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 422 void (*setup)(struct hda_codec *);
ae6b813a 423 void (*init_hook)(struct hda_codec *);
cb53c626
TI
424#ifdef CONFIG_SND_HDA_POWER_SAVE
425 struct hda_amp_list *loopbacks;
c97259df 426 void (*power_hook)(struct hda_codec *codec);
cb53c626 427#endif
1da177e4
LT
428};
429
1da177e4
LT
430
431/*
432 * input MUX handling
433 */
9c7f852e
TI
434static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
435 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
436{
437 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
438 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
439 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
440 if (mux_idx >= spec->num_mux_defs)
441 mux_idx = 0;
5311114d
TI
442 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
443 mux_idx = 0;
a1e8d2da 444 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
445}
446
9c7f852e
TI
447static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
448 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
449{
450 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
451 struct alc_spec *spec = codec->spec;
452 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
453
454 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
455 return 0;
456}
457
9c7f852e
TI
458static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
459 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
460{
461 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
462 struct alc_spec *spec = codec->spec;
cd896c33 463 const struct hda_input_mux *imux;
1da177e4 464 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 465 unsigned int mux_idx;
e1406348
TI
466 hda_nid_t nid = spec->capsrc_nids ?
467 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 468 unsigned int type;
1da177e4 469
cd896c33
TI
470 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
471 imux = &spec->input_mux[mux_idx];
5311114d
TI
472 if (!imux->num_items && mux_idx > 0)
473 imux = &spec->input_mux[0];
cd896c33 474
a22d543a 475 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 476 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
477 /* Matrix-mixer style (e.g. ALC882) */
478 unsigned int *cur_val = &spec->cur_mux[adc_idx];
479 unsigned int i, idx;
480
481 idx = ucontrol->value.enumerated.item[0];
482 if (idx >= imux->num_items)
483 idx = imux->num_items - 1;
484 if (*cur_val == idx)
485 return 0;
486 for (i = 0; i < imux->num_items; i++) {
487 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
488 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
489 imux->items[i].index,
490 HDA_AMP_MUTE, v);
491 }
492 *cur_val = idx;
493 return 1;
494 } else {
495 /* MUX style (e.g. ALC880) */
cd896c33 496 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
497 &spec->cur_mux[adc_idx]);
498 }
499}
e9edcee0 500
1da177e4
LT
501/*
502 * channel mode setting
503 */
9c7f852e
TI
504static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
505 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
506{
507 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
508 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
509 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
510 spec->num_channel_mode);
1da177e4
LT
511}
512
9c7f852e
TI
513static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
514 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
515{
516 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
517 struct alc_spec *spec = codec->spec;
d2a6d7dc 518 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 519 spec->num_channel_mode,
3b315d70 520 spec->ext_channel_count);
1da177e4
LT
521}
522
9c7f852e
TI
523static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
524 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
525{
526 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
527 struct alc_spec *spec = codec->spec;
4e195a7b
TI
528 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
529 spec->num_channel_mode,
3b315d70
HM
530 &spec->ext_channel_count);
531 if (err >= 0 && !spec->const_channel_count) {
532 spec->multiout.max_channels = spec->ext_channel_count;
533 if (spec->need_dac_fix)
534 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
535 }
4e195a7b 536 return err;
1da177e4
LT
537}
538
a9430dd8 539/*
4c5186ed 540 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 541 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
542 * being part of a format specifier. Maximum allowed length of a value is
543 * 63 characters plus NULL terminator.
7cf51e48
JW
544 *
545 * Note: some retasking pin complexes seem to ignore requests for input
546 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
547 * are requested. Therefore order this list so that this behaviour will not
548 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
549 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
550 * March 2006.
4c5186ed
JW
551 */
552static char *alc_pin_mode_names[] = {
7cf51e48
JW
553 "Mic 50pc bias", "Mic 80pc bias",
554 "Line in", "Line out", "Headphone out",
4c5186ed
JW
555};
556static unsigned char alc_pin_mode_values[] = {
7cf51e48 557 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
558};
559/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
560 * in the pin being assumed to be exclusively an input or an output pin. In
561 * addition, "input" pins may or may not process the mic bias option
562 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
563 * accept requests for bias as of chip versions up to March 2006) and/or
564 * wiring in the computer.
a9430dd8 565 */
a1e8d2da
JW
566#define ALC_PIN_DIR_IN 0x00
567#define ALC_PIN_DIR_OUT 0x01
568#define ALC_PIN_DIR_INOUT 0x02
569#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
570#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 571
ea1fb29a 572/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
573 * For each direction the minimum and maximum values are given.
574 */
a1e8d2da 575static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
576 { 0, 2 }, /* ALC_PIN_DIR_IN */
577 { 3, 4 }, /* ALC_PIN_DIR_OUT */
578 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
579 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
580 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
581};
582#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
583#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
584#define alc_pin_mode_n_items(_dir) \
585 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
586
9c7f852e
TI
587static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
588 struct snd_ctl_elem_info *uinfo)
a9430dd8 589{
4c5186ed
JW
590 unsigned int item_num = uinfo->value.enumerated.item;
591 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
592
593 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 594 uinfo->count = 1;
4c5186ed
JW
595 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
596
597 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
598 item_num = alc_pin_mode_min(dir);
599 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
600 return 0;
601}
602
9c7f852e
TI
603static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
604 struct snd_ctl_elem_value *ucontrol)
a9430dd8 605{
4c5186ed 606 unsigned int i;
a9430dd8
JW
607 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
608 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 609 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 610 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
611 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
612 AC_VERB_GET_PIN_WIDGET_CONTROL,
613 0x00);
a9430dd8 614
4c5186ed
JW
615 /* Find enumerated value for current pinctl setting */
616 i = alc_pin_mode_min(dir);
4b35d2ca 617 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 618 i++;
9c7f852e 619 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
620 return 0;
621}
622
9c7f852e
TI
623static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
624 struct snd_ctl_elem_value *ucontrol)
a9430dd8 625{
4c5186ed 626 signed int change;
a9430dd8
JW
627 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
628 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
629 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
630 long val = *ucontrol->value.integer.value;
9c7f852e
TI
631 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
632 AC_VERB_GET_PIN_WIDGET_CONTROL,
633 0x00);
a9430dd8 634
f12ab1e0 635 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
636 val = alc_pin_mode_min(dir);
637
638 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
639 if (change) {
640 /* Set pin mode to that requested */
82beb8fd
TI
641 snd_hda_codec_write_cache(codec, nid, 0,
642 AC_VERB_SET_PIN_WIDGET_CONTROL,
643 alc_pin_mode_values[val]);
cdcd9268 644
ea1fb29a 645 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
646 * for the requested pin mode. Enum values of 2 or less are
647 * input modes.
648 *
649 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
650 * reduces noise slightly (particularly on input) so we'll
651 * do it. However, having both input and output buffers
652 * enabled simultaneously doesn't seem to be problematic if
653 * this turns out to be necessary in the future.
cdcd9268
JW
654 */
655 if (val <= 2) {
47fd830a
TI
656 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
657 HDA_AMP_MUTE, HDA_AMP_MUTE);
658 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
659 HDA_AMP_MUTE, 0);
cdcd9268 660 } else {
47fd830a
TI
661 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
662 HDA_AMP_MUTE, HDA_AMP_MUTE);
663 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
664 HDA_AMP_MUTE, 0);
cdcd9268
JW
665 }
666 }
a9430dd8
JW
667 return change;
668}
669
4c5186ed 670#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 671 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 672 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
673 .info = alc_pin_mode_info, \
674 .get = alc_pin_mode_get, \
675 .put = alc_pin_mode_put, \
676 .private_value = nid | (dir<<16) }
df694daa 677
5c8f858d
JW
678/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
679 * together using a mask with more than one bit set. This control is
680 * currently used only by the ALC260 test model. At this stage they are not
681 * needed for any "production" models.
682 */
683#ifdef CONFIG_SND_DEBUG
a5ce8890 684#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 685
9c7f852e
TI
686static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
687 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
688{
689 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
690 hda_nid_t nid = kcontrol->private_value & 0xffff;
691 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
692 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
693 unsigned int val = snd_hda_codec_read(codec, nid, 0,
694 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
695
696 *valp = (val & mask) != 0;
697 return 0;
698}
9c7f852e
TI
699static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
700 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
701{
702 signed int change;
703 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
704 hda_nid_t nid = kcontrol->private_value & 0xffff;
705 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
706 long val = *ucontrol->value.integer.value;
9c7f852e
TI
707 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
708 AC_VERB_GET_GPIO_DATA,
709 0x00);
5c8f858d
JW
710
711 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
712 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
713 if (val == 0)
5c8f858d
JW
714 gpio_data &= ~mask;
715 else
716 gpio_data |= mask;
82beb8fd
TI
717 snd_hda_codec_write_cache(codec, nid, 0,
718 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
719
720 return change;
721}
722#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
723 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 724 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
725 .info = alc_gpio_data_info, \
726 .get = alc_gpio_data_get, \
727 .put = alc_gpio_data_put, \
728 .private_value = nid | (mask<<16) }
729#endif /* CONFIG_SND_DEBUG */
730
92621f13
JW
731/* A switch control to allow the enabling of the digital IO pins on the
732 * ALC260. This is incredibly simplistic; the intention of this control is
733 * to provide something in the test model allowing digital outputs to be
734 * identified if present. If models are found which can utilise these
735 * outputs a more complete mixer control can be devised for those models if
736 * necessary.
737 */
738#ifdef CONFIG_SND_DEBUG
a5ce8890 739#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 740
9c7f852e
TI
741static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
742 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
743{
744 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
745 hda_nid_t nid = kcontrol->private_value & 0xffff;
746 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
747 long *valp = ucontrol->value.integer.value;
9c7f852e 748 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 749 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
750
751 *valp = (val & mask) != 0;
752 return 0;
753}
9c7f852e
TI
754static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
755 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
756{
757 signed int change;
758 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
759 hda_nid_t nid = kcontrol->private_value & 0xffff;
760 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
761 long val = *ucontrol->value.integer.value;
9c7f852e 762 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 763 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 764 0x00);
92621f13
JW
765
766 /* Set/unset the masked control bit(s) as needed */
9c7f852e 767 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
768 if (val==0)
769 ctrl_data &= ~mask;
770 else
771 ctrl_data |= mask;
82beb8fd
TI
772 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
773 ctrl_data);
92621f13
JW
774
775 return change;
776}
777#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
778 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 779 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
780 .info = alc_spdif_ctrl_info, \
781 .get = alc_spdif_ctrl_get, \
782 .put = alc_spdif_ctrl_put, \
783 .private_value = nid | (mask<<16) }
784#endif /* CONFIG_SND_DEBUG */
785
f8225f6d
JW
786/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
787 * Again, this is only used in the ALC26x test models to help identify when
788 * the EAPD line must be asserted for features to work.
789 */
790#ifdef CONFIG_SND_DEBUG
791#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
792
793static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
794 struct snd_ctl_elem_value *ucontrol)
795{
796 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
797 hda_nid_t nid = kcontrol->private_value & 0xffff;
798 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
799 long *valp = ucontrol->value.integer.value;
800 unsigned int val = snd_hda_codec_read(codec, nid, 0,
801 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
802
803 *valp = (val & mask) != 0;
804 return 0;
805}
806
807static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
808 struct snd_ctl_elem_value *ucontrol)
809{
810 int change;
811 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
812 hda_nid_t nid = kcontrol->private_value & 0xffff;
813 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
814 long val = *ucontrol->value.integer.value;
815 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
816 AC_VERB_GET_EAPD_BTLENABLE,
817 0x00);
818
819 /* Set/unset the masked control bit(s) as needed */
820 change = (!val ? 0 : mask) != (ctrl_data & mask);
821 if (!val)
822 ctrl_data &= ~mask;
823 else
824 ctrl_data |= mask;
825 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
826 ctrl_data);
827
828 return change;
829}
830
831#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
832 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 833 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
834 .info = alc_eapd_ctrl_info, \
835 .get = alc_eapd_ctrl_get, \
836 .put = alc_eapd_ctrl_put, \
837 .private_value = nid | (mask<<16) }
838#endif /* CONFIG_SND_DEBUG */
839
23f0c048
TI
840/*
841 * set up the input pin config (depending on the given auto-pin type)
842 */
843static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
844 int auto_pin_type)
845{
846 unsigned int val = PIN_IN;
847
848 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
849 unsigned int pincap;
1327a32b 850 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048
TI
851 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
852 if (pincap & AC_PINCAP_VREF_80)
853 val = PIN_VREF80;
461c6c3a
TI
854 else if (pincap & AC_PINCAP_VREF_50)
855 val = PIN_VREF50;
856 else if (pincap & AC_PINCAP_VREF_100)
857 val = PIN_VREF100;
858 else if (pincap & AC_PINCAP_VREF_GRD)
859 val = PIN_VREFGRD;
23f0c048
TI
860 }
861 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
862}
863
d88897ea
TI
864/*
865 */
866static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
867{
868 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
869 return;
870 spec->mixers[spec->num_mixers++] = mix;
871}
872
873static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
874{
875 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
876 return;
877 spec->init_verbs[spec->num_init_verbs++] = verb;
878}
879
df694daa
KY
880/*
881 * set up from the preset table
882 */
e9c364c0 883static void setup_preset(struct hda_codec *codec,
9c7f852e 884 const struct alc_config_preset *preset)
df694daa 885{
e9c364c0 886 struct alc_spec *spec = codec->spec;
df694daa
KY
887 int i;
888
889 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 890 add_mixer(spec, preset->mixers[i]);
f9e336f6 891 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
892 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
893 i++)
d88897ea 894 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 895
df694daa
KY
896 spec->channel_mode = preset->channel_mode;
897 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 898 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 899 spec->const_channel_count = preset->const_channel_count;
df694daa 900
3b315d70
HM
901 if (preset->const_channel_count)
902 spec->multiout.max_channels = preset->const_channel_count;
903 else
904 spec->multiout.max_channels = spec->channel_mode[0].channels;
905 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
906
907 spec->multiout.num_dacs = preset->num_dacs;
908 spec->multiout.dac_nids = preset->dac_nids;
909 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 910 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 911 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 912
a1e8d2da 913 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 914 if (!spec->num_mux_defs)
a1e8d2da 915 spec->num_mux_defs = 1;
df694daa
KY
916 spec->input_mux = preset->input_mux;
917
918 spec->num_adc_nids = preset->num_adc_nids;
919 spec->adc_nids = preset->adc_nids;
e1406348 920 spec->capsrc_nids = preset->capsrc_nids;
df694daa 921 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
922
923 spec->unsol_event = preset->unsol_event;
924 spec->init_hook = preset->init_hook;
cb53c626 925#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 926 spec->power_hook = preset->power_hook;
cb53c626
TI
927 spec->loopback.amplist = preset->loopbacks;
928#endif
e9c364c0
TI
929
930 if (preset->setup)
931 preset->setup(codec);
df694daa
KY
932}
933
bc9f98a9
KY
934/* Enable GPIO mask and set output */
935static struct hda_verb alc_gpio1_init_verbs[] = {
936 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
937 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
938 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
939 { }
940};
941
942static struct hda_verb alc_gpio2_init_verbs[] = {
943 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
944 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
945 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
946 { }
947};
948
bdd148a3
KY
949static struct hda_verb alc_gpio3_init_verbs[] = {
950 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
951 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
952 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
953 { }
954};
955
2c3bf9ab
TI
956/*
957 * Fix hardware PLL issue
958 * On some codecs, the analog PLL gating control must be off while
959 * the default value is 1.
960 */
961static void alc_fix_pll(struct hda_codec *codec)
962{
963 struct alc_spec *spec = codec->spec;
964 unsigned int val;
965
966 if (!spec->pll_nid)
967 return;
968 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
969 spec->pll_coef_idx);
970 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
971 AC_VERB_GET_PROC_COEF, 0);
972 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
973 spec->pll_coef_idx);
974 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
975 val & ~(1 << spec->pll_coef_bit));
976}
977
978static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
979 unsigned int coef_idx, unsigned int coef_bit)
980{
981 struct alc_spec *spec = codec->spec;
982 spec->pll_nid = nid;
983 spec->pll_coef_idx = coef_idx;
984 spec->pll_coef_bit = coef_bit;
985 alc_fix_pll(codec);
986}
987
a9fd4f3f 988static void alc_automute_pin(struct hda_codec *codec)
c9b58006
KY
989{
990 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
991 unsigned int nid = spec->autocfg.hp_pins[0];
992 int i;
c9b58006 993
ad87c64f
TI
994 if (!nid)
995 return;
864f92be 996 spec->jack_present = snd_hda_jack_detect(codec, nid);
a9fd4f3f
TI
997 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
998 nid = spec->autocfg.speaker_pins[i];
999 if (!nid)
1000 break;
1001 snd_hda_codec_write(codec, nid, 0,
1002 AC_VERB_SET_PIN_WIDGET_CONTROL,
1003 spec->jack_present ? 0 : PIN_OUT);
1004 }
c9b58006
KY
1005}
1006
6c819492
TI
1007static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1008 hda_nid_t nid)
1009{
1010 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1011 int i, nums;
1012
1013 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1014 for (i = 0; i < nums; i++)
1015 if (conn[i] == nid)
1016 return i;
1017 return -1;
1018}
1019
840b64c0
TI
1020/* switch the current ADC according to the jack state */
1021static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1022{
1023 struct alc_spec *spec = codec->spec;
1024 unsigned int present;
1025 hda_nid_t new_adc;
1026
1027 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1028 if (present)
1029 spec->cur_adc_idx = 1;
1030 else
1031 spec->cur_adc_idx = 0;
1032 new_adc = spec->adc_nids[spec->cur_adc_idx];
1033 if (spec->cur_adc && spec->cur_adc != new_adc) {
1034 /* stream is running, let's swap the current ADC */
1035 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
1036 spec->cur_adc = new_adc;
1037 snd_hda_codec_setup_stream(codec, new_adc,
1038 spec->cur_adc_stream_tag, 0,
1039 spec->cur_adc_format);
1040 }
1041}
1042
7fb0d78f
KY
1043static void alc_mic_automute(struct hda_codec *codec)
1044{
1045 struct alc_spec *spec = codec->spec;
6c819492
TI
1046 struct alc_mic_route *dead, *alive;
1047 unsigned int present, type;
1048 hda_nid_t cap_nid;
1049
b59bdf3b
TI
1050 if (!spec->auto_mic)
1051 return;
6c819492
TI
1052 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1053 return;
1054 if (snd_BUG_ON(!spec->adc_nids))
1055 return;
1056
840b64c0
TI
1057 if (spec->dual_adc_switch) {
1058 alc_dual_mic_adc_auto_switch(codec);
1059 return;
1060 }
1061
6c819492
TI
1062 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1063
864f92be 1064 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1065 if (present) {
1066 alive = &spec->ext_mic;
1067 dead = &spec->int_mic;
1068 } else {
1069 alive = &spec->int_mic;
1070 dead = &spec->ext_mic;
1071 }
1072
6c819492
TI
1073 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1074 if (type == AC_WID_AUD_MIX) {
1075 /* Matrix-mixer style (e.g. ALC882) */
1076 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1077 alive->mux_idx,
1078 HDA_AMP_MUTE, 0);
1079 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1080 dead->mux_idx,
1081 HDA_AMP_MUTE, HDA_AMP_MUTE);
1082 } else {
1083 /* MUX style (e.g. ALC880) */
1084 snd_hda_codec_write_cache(codec, cap_nid, 0,
1085 AC_VERB_SET_CONNECT_SEL,
1086 alive->mux_idx);
1087 }
1088
1089 /* FIXME: analog mixer */
7fb0d78f
KY
1090}
1091
c9b58006
KY
1092/* unsolicited event for HP jack sensing */
1093static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1094{
1095 if (codec->vendor_id == 0x10ec0880)
1096 res >>= 28;
1097 else
1098 res >>= 26;
a9fd4f3f
TI
1099 switch (res) {
1100 case ALC880_HP_EVENT:
1101 alc_automute_pin(codec);
1102 break;
1103 case ALC880_MIC_EVENT:
7fb0d78f 1104 alc_mic_automute(codec);
a9fd4f3f
TI
1105 break;
1106 }
7fb0d78f
KY
1107}
1108
1109static void alc_inithook(struct hda_codec *codec)
1110{
a9fd4f3f 1111 alc_automute_pin(codec);
7fb0d78f 1112 alc_mic_automute(codec);
c9b58006
KY
1113}
1114
f9423e7a
KY
1115/* additional initialization for ALC888 variants */
1116static void alc888_coef_init(struct hda_codec *codec)
1117{
1118 unsigned int tmp;
1119
1120 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1121 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1122 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1123 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1124 /* alc888S-VC */
1125 snd_hda_codec_read(codec, 0x20, 0,
1126 AC_VERB_SET_PROC_COEF, 0x830);
1127 else
1128 /* alc888-VB */
1129 snd_hda_codec_read(codec, 0x20, 0,
1130 AC_VERB_SET_PROC_COEF, 0x3030);
1131}
1132
87a8c370
JK
1133static void alc889_coef_init(struct hda_codec *codec)
1134{
1135 unsigned int tmp;
1136
1137 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1138 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1139 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1140 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1141}
1142
3fb4a508
TI
1143/* turn on/off EAPD control (only if available) */
1144static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1145{
1146 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1147 return;
1148 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1149 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1150 on ? 2 : 0);
1151}
1152
4a79ba34 1153static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1154{
4a79ba34 1155 unsigned int tmp;
bc9f98a9 1156
4a79ba34
TI
1157 switch (type) {
1158 case ALC_INIT_GPIO1:
bc9f98a9
KY
1159 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1160 break;
4a79ba34 1161 case ALC_INIT_GPIO2:
bc9f98a9
KY
1162 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1163 break;
4a79ba34 1164 case ALC_INIT_GPIO3:
bdd148a3
KY
1165 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1166 break;
4a79ba34 1167 case ALC_INIT_DEFAULT:
bdd148a3 1168 switch (codec->vendor_id) {
c9b58006 1169 case 0x10ec0260:
3fb4a508
TI
1170 set_eapd(codec, 0x0f, 1);
1171 set_eapd(codec, 0x10, 1);
c9b58006
KY
1172 break;
1173 case 0x10ec0262:
bdd148a3
KY
1174 case 0x10ec0267:
1175 case 0x10ec0268:
c9b58006 1176 case 0x10ec0269:
3fb4a508 1177 case 0x10ec0270:
c6e8f2da 1178 case 0x10ec0272:
f9423e7a
KY
1179 case 0x10ec0660:
1180 case 0x10ec0662:
1181 case 0x10ec0663:
c9b58006 1182 case 0x10ec0862:
20a3a05d 1183 case 0x10ec0889:
3fb4a508
TI
1184 set_eapd(codec, 0x14, 1);
1185 set_eapd(codec, 0x15, 1);
c9b58006 1186 break;
bdd148a3 1187 }
c9b58006
KY
1188 switch (codec->vendor_id) {
1189 case 0x10ec0260:
1190 snd_hda_codec_write(codec, 0x1a, 0,
1191 AC_VERB_SET_COEF_INDEX, 7);
1192 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1193 AC_VERB_GET_PROC_COEF, 0);
1194 snd_hda_codec_write(codec, 0x1a, 0,
1195 AC_VERB_SET_COEF_INDEX, 7);
1196 snd_hda_codec_write(codec, 0x1a, 0,
1197 AC_VERB_SET_PROC_COEF,
1198 tmp | 0x2010);
1199 break;
1200 case 0x10ec0262:
1201 case 0x10ec0880:
1202 case 0x10ec0882:
1203 case 0x10ec0883:
1204 case 0x10ec0885:
4a5a4c56 1205 case 0x10ec0887:
20a3a05d 1206 case 0x10ec0889:
87a8c370 1207 alc889_coef_init(codec);
c9b58006 1208 break;
f9423e7a 1209 case 0x10ec0888:
4a79ba34 1210 alc888_coef_init(codec);
f9423e7a 1211 break;
0aea778e 1212#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1213 case 0x10ec0267:
1214 case 0x10ec0268:
1215 snd_hda_codec_write(codec, 0x20, 0,
1216 AC_VERB_SET_COEF_INDEX, 7);
1217 tmp = snd_hda_codec_read(codec, 0x20, 0,
1218 AC_VERB_GET_PROC_COEF, 0);
1219 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1220 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1221 snd_hda_codec_write(codec, 0x20, 0,
1222 AC_VERB_SET_PROC_COEF,
1223 tmp | 0x3000);
1224 break;
0aea778e 1225#endif /* XXX */
bc9f98a9 1226 }
4a79ba34
TI
1227 break;
1228 }
1229}
1230
1231static void alc_init_auto_hp(struct hda_codec *codec)
1232{
1233 struct alc_spec *spec = codec->spec;
1234
1235 if (!spec->autocfg.hp_pins[0])
1236 return;
1237
1238 if (!spec->autocfg.speaker_pins[0]) {
2a2ed0df
TI
1239 if (spec->autocfg.line_out_pins[0] &&
1240 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
4a79ba34
TI
1241 spec->autocfg.speaker_pins[0] =
1242 spec->autocfg.line_out_pins[0];
1243 else
1244 return;
1245 }
1246
2a2ed0df
TI
1247 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1248 spec->autocfg.hp_pins[0]);
4a79ba34
TI
1249 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1250 AC_VERB_SET_UNSOLICITED_ENABLE,
1251 AC_USRSP_EN | ALC880_HP_EVENT);
1252 spec->unsol_event = alc_sku_unsol_event;
1253}
1254
6c819492
TI
1255static void alc_init_auto_mic(struct hda_codec *codec)
1256{
1257 struct alc_spec *spec = codec->spec;
1258 struct auto_pin_cfg *cfg = &spec->autocfg;
1259 hda_nid_t fixed, ext;
1260 int i;
1261
1262 /* there must be only two mic inputs exclusively */
1263 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++)
1264 if (cfg->input_pins[i])
1265 return;
1266
1267 fixed = ext = 0;
1268 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) {
1269 hda_nid_t nid = cfg->input_pins[i];
1270 unsigned int defcfg;
1271 if (!nid)
1272 return;
1273 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1274 switch (get_defcfg_connect(defcfg)) {
1275 case AC_JACK_PORT_FIXED:
1276 if (fixed)
1277 return; /* already occupied */
1278 fixed = nid;
1279 break;
1280 case AC_JACK_PORT_COMPLEX:
1281 if (ext)
1282 return; /* already occupied */
1283 ext = nid;
1284 break;
1285 default:
1286 return; /* invalid entry */
1287 }
1288 }
eaa9b3a7
TI
1289 if (!ext || !fixed)
1290 return;
6c819492
TI
1291 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1292 return; /* no unsol support */
1293 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1294 ext, fixed);
1295 spec->ext_mic.pin = ext;
1296 spec->int_mic.pin = fixed;
1297 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1298 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1299 spec->auto_mic = 1;
1300 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1301 AC_VERB_SET_UNSOLICITED_ENABLE,
1302 AC_USRSP_EN | ALC880_MIC_EVENT);
1303 spec->unsol_event = alc_sku_unsol_event;
1304}
1305
da00c244
KY
1306static int alc_auto_parse_customize_define(struct hda_codec *codec)
1307{
1308 unsigned int ass, tmp, i;
7fb56223 1309 unsigned nid = 0;
da00c244
KY
1310 struct alc_spec *spec = codec->spec;
1311
b6cbe517
TI
1312 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1313
da00c244 1314 ass = codec->subsystem_id & 0xffff;
b6cbe517 1315 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1316 goto do_sku;
1317
1318 nid = 0x1d;
1319 if (codec->vendor_id == 0x10ec0260)
1320 nid = 0x17;
1321 ass = snd_hda_codec_get_pincfg(codec, nid);
1322
1323 if (!(ass & 1)) {
1324 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1325 codec->chip_name, ass);
1326 return -1;
1327 }
1328
1329 /* check sum */
1330 tmp = 0;
1331 for (i = 1; i < 16; i++) {
1332 if ((ass >> i) & 1)
1333 tmp++;
1334 }
1335 if (((ass >> 16) & 0xf) != tmp)
1336 return -1;
1337
1338 spec->cdefine.port_connectivity = ass >> 30;
1339 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1340 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1341 spec->cdefine.customization = ass >> 8;
1342do_sku:
1343 spec->cdefine.sku_cfg = ass;
1344 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1345 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1346 spec->cdefine.swap = (ass & 0x2) >> 1;
1347 spec->cdefine.override = ass & 0x1;
1348
1349 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1350 nid, spec->cdefine.sku_cfg);
1351 snd_printd("SKU: port_connectivity=0x%x\n",
1352 spec->cdefine.port_connectivity);
1353 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1354 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1355 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1356 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1357 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1358 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1359 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1360
1361 return 0;
1362}
1363
4a79ba34
TI
1364/* check subsystem ID and set up device-specific initialization;
1365 * return 1 if initialized, 0 if invalid SSID
1366 */
1367/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1368 * 31 ~ 16 : Manufacture ID
1369 * 15 ~ 8 : SKU ID
1370 * 7 ~ 0 : Assembly ID
1371 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1372 */
1373static int alc_subsystem_id(struct hda_codec *codec,
1374 hda_nid_t porta, hda_nid_t porte,
6227cdce 1375 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1376{
1377 unsigned int ass, tmp, i;
1378 unsigned nid;
1379 struct alc_spec *spec = codec->spec;
1380
1381 ass = codec->subsystem_id & 0xffff;
1382 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1383 goto do_sku;
1384
1385 /* invalid SSID, check the special NID pin defcfg instead */
1386 /*
def319f9 1387 * 31~30 : port connectivity
4a79ba34
TI
1388 * 29~21 : reserve
1389 * 20 : PCBEEP input
1390 * 19~16 : Check sum (15:1)
1391 * 15~1 : Custom
1392 * 0 : override
1393 */
1394 nid = 0x1d;
1395 if (codec->vendor_id == 0x10ec0260)
1396 nid = 0x17;
1397 ass = snd_hda_codec_get_pincfg(codec, nid);
1398 snd_printd("realtek: No valid SSID, "
1399 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1400 ass, nid);
6227cdce 1401 if (!(ass & 1))
4a79ba34
TI
1402 return 0;
1403 if ((ass >> 30) != 1) /* no physical connection */
1404 return 0;
1405
1406 /* check sum */
1407 tmp = 0;
1408 for (i = 1; i < 16; i++) {
1409 if ((ass >> i) & 1)
1410 tmp++;
1411 }
1412 if (((ass >> 16) & 0xf) != tmp)
1413 return 0;
1414do_sku:
1415 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1416 ass & 0xffff, codec->vendor_id);
1417 /*
1418 * 0 : override
1419 * 1 : Swap Jack
1420 * 2 : 0 --> Desktop, 1 --> Laptop
1421 * 3~5 : External Amplifier control
1422 * 7~6 : Reserved
1423 */
1424 tmp = (ass & 0x38) >> 3; /* external Amp control */
1425 switch (tmp) {
1426 case 1:
1427 spec->init_amp = ALC_INIT_GPIO1;
1428 break;
1429 case 3:
1430 spec->init_amp = ALC_INIT_GPIO2;
1431 break;
1432 case 7:
1433 spec->init_amp = ALC_INIT_GPIO3;
1434 break;
1435 case 5:
1436 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1437 break;
1438 }
ea1fb29a 1439
8c427226 1440 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1441 * when the external headphone out jack is plugged"
1442 */
8c427226 1443 if (!(ass & 0x8000))
4a79ba34 1444 return 1;
c9b58006
KY
1445 /*
1446 * 10~8 : Jack location
1447 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1448 * 14~13: Resvered
1449 * 15 : 1 --> enable the function "Mute internal speaker
1450 * when the external headphone out jack is plugged"
1451 */
c9b58006 1452 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1453 hda_nid_t nid;
c9b58006
KY
1454 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1455 if (tmp == 0)
01d4825d 1456 nid = porta;
c9b58006 1457 else if (tmp == 1)
01d4825d 1458 nid = porte;
c9b58006 1459 else if (tmp == 2)
01d4825d 1460 nid = portd;
6227cdce
KY
1461 else if (tmp == 3)
1462 nid = porti;
c9b58006 1463 else
4a79ba34 1464 return 1;
01d4825d
TI
1465 for (i = 0; i < spec->autocfg.line_outs; i++)
1466 if (spec->autocfg.line_out_pins[i] == nid)
1467 return 1;
1468 spec->autocfg.hp_pins[0] = nid;
c9b58006
KY
1469 }
1470
4a79ba34 1471 alc_init_auto_hp(codec);
6c819492 1472 alc_init_auto_mic(codec);
4a79ba34
TI
1473 return 1;
1474}
ea1fb29a 1475
4a79ba34 1476static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1477 hda_nid_t porta, hda_nid_t porte,
1478 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1479{
6227cdce 1480 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1481 struct alc_spec *spec = codec->spec;
1482 snd_printd("realtek: "
1483 "Enable default setup for auto mode as fallback\n");
1484 spec->init_amp = ALC_INIT_DEFAULT;
1485 alc_init_auto_hp(codec);
6c819492 1486 alc_init_auto_mic(codec);
4a79ba34 1487 }
bc9f98a9
KY
1488}
1489
f95474ec 1490/*
f8f25ba3 1491 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1492 */
1493
1494struct alc_pincfg {
1495 hda_nid_t nid;
1496 u32 val;
1497};
1498
f8f25ba3
TI
1499struct alc_fixup {
1500 const struct alc_pincfg *pins;
1501 const struct hda_verb *verbs;
1502};
1503
1504static void alc_pick_fixup(struct hda_codec *codec,
f95474ec 1505 const struct snd_pci_quirk *quirk,
7fa90e87
TI
1506 const struct alc_fixup *fix,
1507 int pre_init)
f95474ec
TI
1508{
1509 const struct alc_pincfg *cfg;
1510
1511 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1512 if (!quirk)
1513 return;
f8f25ba3
TI
1514 fix += quirk->value;
1515 cfg = fix->pins;
7fa90e87
TI
1516 if (pre_init && cfg) {
1517#ifdef CONFIG_SND_DEBUG_VERBOSE
1518 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
1519 codec->chip_name, quirk->name);
1520#endif
f8f25ba3
TI
1521 for (; cfg->nid; cfg++)
1522 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1523 }
7fa90e87
TI
1524 if (!pre_init && fix->verbs) {
1525#ifdef CONFIG_SND_DEBUG_VERBOSE
1526 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
1527 codec->chip_name, quirk->name);
1528#endif
f8f25ba3 1529 add_verb(codec->spec, fix->verbs);
7fa90e87 1530 }
f95474ec
TI
1531}
1532
274693f3
KY
1533static int alc_read_coef_idx(struct hda_codec *codec,
1534 unsigned int coef_idx)
1535{
1536 unsigned int val;
1537 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1538 coef_idx);
1539 val = snd_hda_codec_read(codec, 0x20, 0,
1540 AC_VERB_GET_PROC_COEF, 0);
1541 return val;
1542}
1543
757899ac
TI
1544/* set right pin controls for digital I/O */
1545static void alc_auto_init_digital(struct hda_codec *codec)
1546{
1547 struct alc_spec *spec = codec->spec;
1548 int i;
1549 hda_nid_t pin;
1550
1551 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1552 pin = spec->autocfg.dig_out_pins[i];
1553 if (pin) {
1554 snd_hda_codec_write(codec, pin, 0,
1555 AC_VERB_SET_PIN_WIDGET_CONTROL,
1556 PIN_OUT);
1557 }
1558 }
1559 pin = spec->autocfg.dig_in_pin;
1560 if (pin)
1561 snd_hda_codec_write(codec, pin, 0,
1562 AC_VERB_SET_PIN_WIDGET_CONTROL,
1563 PIN_IN);
1564}
1565
1566/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1567static void alc_auto_parse_digital(struct hda_codec *codec)
1568{
1569 struct alc_spec *spec = codec->spec;
1570 int i, err;
1571 hda_nid_t dig_nid;
1572
1573 /* support multiple SPDIFs; the secondary is set up as a slave */
1574 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1575 err = snd_hda_get_connections(codec,
1576 spec->autocfg.dig_out_pins[i],
1577 &dig_nid, 1);
1578 if (err < 0)
1579 continue;
1580 if (!i) {
1581 spec->multiout.dig_out_nid = dig_nid;
1582 spec->dig_out_type = spec->autocfg.dig_out_type[0];
1583 } else {
1584 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1585 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1586 break;
1587 spec->slave_dig_outs[i - 1] = dig_nid;
1588 }
1589 }
1590
1591 if (spec->autocfg.dig_in_pin) {
1592 hda_nid_t dig_nid;
1593 err = snd_hda_get_connections(codec,
1594 spec->autocfg.dig_in_pin,
1595 &dig_nid, 1);
1596 if (err > 0)
1597 spec->dig_in_nid = dig_nid;
1598 }
1599}
1600
ef8ef5fb
VP
1601/*
1602 * ALC888
1603 */
1604
1605/*
1606 * 2ch mode
1607 */
1608static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1609/* Mic-in jack as mic in */
1610 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1611 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1612/* Line-in jack as Line in */
1613 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1614 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1615/* Line-Out as Front */
1616 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1617 { } /* end */
1618};
1619
1620/*
1621 * 4ch mode
1622 */
1623static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1624/* Mic-in jack as mic in */
1625 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1626 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1627/* Line-in jack as Surround */
1628 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1629 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1630/* Line-Out as Front */
1631 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1632 { } /* end */
1633};
1634
1635/*
1636 * 6ch mode
1637 */
1638static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1639/* Mic-in jack as CLFE */
1640 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1641 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1642/* Line-in jack as Surround */
1643 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1644 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1645/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1646 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1647 { } /* end */
1648};
1649
1650/*
1651 * 8ch mode
1652 */
1653static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1654/* Mic-in jack as CLFE */
1655 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1656 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1657/* Line-in jack as Surround */
1658 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1659 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1660/* Line-Out as Side */
1661 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1662 { } /* end */
1663};
1664
1665static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1666 { 2, alc888_4ST_ch2_intel_init },
1667 { 4, alc888_4ST_ch4_intel_init },
1668 { 6, alc888_4ST_ch6_intel_init },
1669 { 8, alc888_4ST_ch8_intel_init },
1670};
1671
1672/*
1673 * ALC888 Fujitsu Siemens Amillo xa3530
1674 */
1675
1676static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1677/* Front Mic: set to PIN_IN (empty by default) */
1678 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1679/* Connect Internal HP to Front */
1680 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1681 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1682 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1683/* Connect Bass HP to Front */
1684 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1685 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1686 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1687/* Connect Line-Out side jack (SPDIF) to Side */
1688 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1689 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1690 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1691/* Connect Mic jack to CLFE */
1692 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1693 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1694 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1695/* Connect Line-in jack to Surround */
1696 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1697 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1698 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1699/* Connect HP out jack to Front */
1700 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1701 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1702 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1703/* Enable unsolicited event for HP jack and Line-out jack */
1704 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1705 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1706 {}
1707};
1708
a9fd4f3f 1709static void alc_automute_amp(struct hda_codec *codec)
ef8ef5fb 1710{
a9fd4f3f 1711 struct alc_spec *spec = codec->spec;
864f92be 1712 unsigned int mute;
a9fd4f3f
TI
1713 hda_nid_t nid;
1714 int i;
1715
1716 spec->jack_present = 0;
1717 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1718 nid = spec->autocfg.hp_pins[i];
1719 if (!nid)
1720 break;
864f92be 1721 if (snd_hda_jack_detect(codec, nid)) {
a9fd4f3f
TI
1722 spec->jack_present = 1;
1723 break;
1724 }
1725 }
1726
1727 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
ef8ef5fb 1728 /* Toggle internal speakers muting */
a9fd4f3f
TI
1729 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1730 nid = spec->autocfg.speaker_pins[i];
1731 if (!nid)
1732 break;
1733 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1734 HDA_AMP_MUTE, mute);
1735 }
ef8ef5fb
VP
1736}
1737
a9fd4f3f
TI
1738static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1739 unsigned int res)
ef8ef5fb 1740{
a9fd4f3f
TI
1741 if (codec->vendor_id == 0x10ec0880)
1742 res >>= 28;
1743 else
1744 res >>= 26;
1745 if (res == ALC880_HP_EVENT)
1746 alc_automute_amp(codec);
ef8ef5fb
VP
1747}
1748
4f5d1706 1749static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
1750{
1751 struct alc_spec *spec = codec->spec;
1752
1753 spec->autocfg.hp_pins[0] = 0x15;
1754 spec->autocfg.speaker_pins[0] = 0x14;
1755 spec->autocfg.speaker_pins[1] = 0x16;
1756 spec->autocfg.speaker_pins[2] = 0x17;
1757 spec->autocfg.speaker_pins[3] = 0x19;
1758 spec->autocfg.speaker_pins[4] = 0x1a;
6732bd0d
WF
1759}
1760
1761static void alc889_intel_init_hook(struct hda_codec *codec)
1762{
1763 alc889_coef_init(codec);
4f5d1706 1764 alc_automute_amp(codec);
6732bd0d
WF
1765}
1766
4f5d1706 1767static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
1768{
1769 struct alc_spec *spec = codec->spec;
1770
1771 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1772 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1773 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1774 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
a9fd4f3f 1775}
ef8ef5fb 1776
5b2d1eca
VP
1777/*
1778 * ALC888 Acer Aspire 4930G model
1779 */
1780
1781static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1782/* Front Mic: set to PIN_IN (empty by default) */
1783 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1784/* Unselect Front Mic by default in input mixer 3 */
1785 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 1786/* Enable unsolicited event for HP jack */
5b2d1eca
VP
1787 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1788/* Connect Internal HP to front */
1789 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1790 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1791 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1792/* Connect HP out to front */
1793 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1794 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1795 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1796 { }
1797};
1798
d2fd4b09
TV
1799/*
1800 * ALC888 Acer Aspire 6530G model
1801 */
1802
1803static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
1804/* Route to built-in subwoofer as well as speakers */
1805 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1806 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1807 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1808 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
1809/* Bias voltage on for external mic port */
1810 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
1811/* Front Mic: set to PIN_IN (empty by default) */
1812 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1813/* Unselect Front Mic by default in input mixer 3 */
1814 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
1815/* Enable unsolicited event for HP jack */
1816 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1817/* Enable speaker output */
1818 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1819 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 1820 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
1821/* Enable headphone output */
1822 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1823 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1824 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 1825 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
1826 { }
1827};
1828
3b315d70 1829/*
018df418 1830 * ALC889 Acer Aspire 8930G model
3b315d70
HM
1831 */
1832
018df418 1833static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
1834/* Front Mic: set to PIN_IN (empty by default) */
1835 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1836/* Unselect Front Mic by default in input mixer 3 */
1837 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1838/* Enable unsolicited event for HP jack */
1839 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1840/* Connect Internal Front to Front */
1841 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1842 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1843 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1844/* Connect Internal Rear to Rear */
1845 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1846 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1847 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1848/* Connect Internal CLFE to CLFE */
1849 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1850 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1851 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1852/* Connect HP out to Front */
018df418 1853 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
1854 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1855 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1856/* Enable all DACs */
1857/* DAC DISABLE/MUTE 1? */
1858/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1859 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1860 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1861/* DAC DISABLE/MUTE 2? */
1862/* some bit here disables the other DACs. Init=0x4900 */
1863 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1864 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
1865/* DMIC fix
1866 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1867 * which makes the stereo useless. However, either the mic or the ALC889
1868 * makes the signal become a difference/sum signal instead of standard
1869 * stereo, which is annoying. So instead we flip this bit which makes the
1870 * codec replicate the sum signal to both channels, turning it into a
1871 * normal mono mic.
1872 */
1873/* DMIC_CONTROL? Init value = 0x0001 */
1874 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1875 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
1876 { }
1877};
1878
ef8ef5fb 1879static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
1880 /* Front mic only available on one ADC */
1881 {
1882 .num_items = 4,
1883 .items = {
1884 { "Mic", 0x0 },
1885 { "Line", 0x2 },
1886 { "CD", 0x4 },
1887 { "Front Mic", 0xb },
1888 },
1889 },
1890 {
1891 .num_items = 3,
1892 .items = {
1893 { "Mic", 0x0 },
1894 { "Line", 0x2 },
1895 { "CD", 0x4 },
1896 },
1897 }
1898};
1899
d2fd4b09
TV
1900static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1901 /* Interal mic only available on one ADC */
1902 {
684a8842 1903 .num_items = 5,
d2fd4b09
TV
1904 .items = {
1905 { "Ext Mic", 0x0 },
684a8842 1906 { "Line In", 0x2 },
d2fd4b09 1907 { "CD", 0x4 },
684a8842 1908 { "Input Mix", 0xa },
d2fd4b09
TV
1909 { "Int Mic", 0xb },
1910 },
1911 },
1912 {
684a8842 1913 .num_items = 4,
d2fd4b09
TV
1914 .items = {
1915 { "Ext Mic", 0x0 },
684a8842 1916 { "Line In", 0x2 },
d2fd4b09 1917 { "CD", 0x4 },
684a8842 1918 { "Input Mix", 0xa },
d2fd4b09
TV
1919 },
1920 }
1921};
1922
018df418
HM
1923static struct hda_input_mux alc889_capture_sources[3] = {
1924 /* Digital mic only available on first "ADC" */
1925 {
1926 .num_items = 5,
1927 .items = {
1928 { "Mic", 0x0 },
1929 { "Line", 0x2 },
1930 { "CD", 0x4 },
1931 { "Front Mic", 0xb },
1932 { "Input Mix", 0xa },
1933 },
1934 },
1935 {
1936 .num_items = 4,
1937 .items = {
1938 { "Mic", 0x0 },
1939 { "Line", 0x2 },
1940 { "CD", 0x4 },
1941 { "Input Mix", 0xa },
1942 },
1943 },
1944 {
1945 .num_items = 4,
1946 .items = {
1947 { "Mic", 0x0 },
1948 { "Line", 0x2 },
1949 { "CD", 0x4 },
1950 { "Input Mix", 0xa },
1951 },
1952 }
1953};
1954
ef8ef5fb 1955static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
1956 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1957 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1958 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1959 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1960 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1961 HDA_OUTPUT),
1962 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1963 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1964 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1965 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1966 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1967 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1968 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1969 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1970 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1972 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1973 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
1974 { } /* end */
1975};
1976
556eea9a
HM
1977static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
1978 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1979 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1980 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1981 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1982 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1983 HDA_OUTPUT),
1984 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1985 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1986 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1987 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1988 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1989 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1990 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1991 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1992 { } /* end */
1993};
1994
1995
4f5d1706 1996static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 1997{
a9fd4f3f 1998 struct alc_spec *spec = codec->spec;
5b2d1eca 1999
a9fd4f3f
TI
2000 spec->autocfg.hp_pins[0] = 0x15;
2001 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2002 spec->autocfg.speaker_pins[1] = 0x16;
2003 spec->autocfg.speaker_pins[2] = 0x17;
5b2d1eca
VP
2004}
2005
4f5d1706 2006static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2007{
2008 struct alc_spec *spec = codec->spec;
2009
2010 spec->autocfg.hp_pins[0] = 0x15;
2011 spec->autocfg.speaker_pins[0] = 0x14;
2012 spec->autocfg.speaker_pins[1] = 0x16;
2013 spec->autocfg.speaker_pins[2] = 0x17;
320d5920
EL
2014}
2015
4f5d1706 2016static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2017{
2018 struct alc_spec *spec = codec->spec;
2019
2020 spec->autocfg.hp_pins[0] = 0x15;
2021 spec->autocfg.speaker_pins[0] = 0x14;
2022 spec->autocfg.speaker_pins[1] = 0x16;
2023 spec->autocfg.speaker_pins[2] = 0x1b;
3b315d70
HM
2024}
2025
1da177e4 2026/*
e9edcee0
TI
2027 * ALC880 3-stack model
2028 *
2029 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2030 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2031 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2032 */
2033
e9edcee0
TI
2034static hda_nid_t alc880_dac_nids[4] = {
2035 /* front, rear, clfe, rear_surr */
2036 0x02, 0x05, 0x04, 0x03
2037};
2038
2039static hda_nid_t alc880_adc_nids[3] = {
2040 /* ADC0-2 */
2041 0x07, 0x08, 0x09,
2042};
2043
2044/* The datasheet says the node 0x07 is connected from inputs,
2045 * but it shows zero connection in the real implementation on some devices.
df694daa 2046 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2047 */
e9edcee0
TI
2048static hda_nid_t alc880_adc_nids_alt[2] = {
2049 /* ADC1-2 */
2050 0x08, 0x09,
2051};
2052
2053#define ALC880_DIGOUT_NID 0x06
2054#define ALC880_DIGIN_NID 0x0a
2055
2056static struct hda_input_mux alc880_capture_source = {
2057 .num_items = 4,
2058 .items = {
2059 { "Mic", 0x0 },
2060 { "Front Mic", 0x3 },
2061 { "Line", 0x2 },
2062 { "CD", 0x4 },
2063 },
2064};
2065
2066/* channel source setting (2/6 channel selection for 3-stack) */
2067/* 2ch mode */
2068static struct hda_verb alc880_threestack_ch2_init[] = {
2069 /* set line-in to input, mute it */
2070 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2071 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2072 /* set mic-in to input vref 80%, mute it */
2073 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2074 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2075 { } /* end */
2076};
2077
2078/* 6ch mode */
2079static struct hda_verb alc880_threestack_ch6_init[] = {
2080 /* set line-in to output, unmute it */
2081 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2082 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2083 /* set mic-in to output, unmute it */
2084 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2085 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2086 { } /* end */
2087};
2088
d2a6d7dc 2089static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2090 { 2, alc880_threestack_ch2_init },
2091 { 6, alc880_threestack_ch6_init },
2092};
2093
c8b6bf9b 2094static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2095 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2096 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2097 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2098 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2099 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2100 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2101 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2102 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2103 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2104 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2105 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2106 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2107 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2108 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2109 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2110 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2111 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2112 {
2113 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2114 .name = "Channel Mode",
df694daa
KY
2115 .info = alc_ch_mode_info,
2116 .get = alc_ch_mode_get,
2117 .put = alc_ch_mode_put,
e9edcee0
TI
2118 },
2119 { } /* end */
2120};
2121
2122/* capture mixer elements */
f9e336f6
TI
2123static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2124 struct snd_ctl_elem_info *uinfo)
2125{
2126 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2127 struct alc_spec *spec = codec->spec;
2128 int err;
1da177e4 2129
5a9e02e9 2130 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2131 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2132 HDA_INPUT);
2133 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2134 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2135 return err;
2136}
2137
2138static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2139 unsigned int size, unsigned int __user *tlv)
2140{
2141 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2142 struct alc_spec *spec = codec->spec;
2143 int err;
1da177e4 2144
5a9e02e9 2145 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2146 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2147 HDA_INPUT);
2148 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2149 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2150 return err;
2151}
2152
2153typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2154 struct snd_ctl_elem_value *ucontrol);
2155
2156static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2157 struct snd_ctl_elem_value *ucontrol,
2158 getput_call_t func)
2159{
2160 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2161 struct alc_spec *spec = codec->spec;
2162 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2163 int err;
2164
5a9e02e9 2165 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2166 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2167 3, 0, HDA_INPUT);
2168 err = func(kcontrol, ucontrol);
5a9e02e9 2169 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2170 return err;
2171}
2172
2173static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2174 struct snd_ctl_elem_value *ucontrol)
2175{
2176 return alc_cap_getput_caller(kcontrol, ucontrol,
2177 snd_hda_mixer_amp_volume_get);
2178}
2179
2180static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2181 struct snd_ctl_elem_value *ucontrol)
2182{
2183 return alc_cap_getput_caller(kcontrol, ucontrol,
2184 snd_hda_mixer_amp_volume_put);
2185}
2186
2187/* capture mixer elements */
2188#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2189
2190static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2191 struct snd_ctl_elem_value *ucontrol)
2192{
2193 return alc_cap_getput_caller(kcontrol, ucontrol,
2194 snd_hda_mixer_amp_switch_get);
2195}
2196
2197static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2198 struct snd_ctl_elem_value *ucontrol)
2199{
2200 return alc_cap_getput_caller(kcontrol, ucontrol,
2201 snd_hda_mixer_amp_switch_put);
2202}
2203
a23b688f 2204#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2205 { \
2206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2207 .name = "Capture Switch", \
2208 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2209 .count = num, \
2210 .info = alc_cap_sw_info, \
2211 .get = alc_cap_sw_get, \
2212 .put = alc_cap_sw_put, \
2213 }, \
2214 { \
2215 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2216 .name = "Capture Volume", \
2217 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2218 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2219 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2220 .count = num, \
2221 .info = alc_cap_vol_info, \
2222 .get = alc_cap_vol_get, \
2223 .put = alc_cap_vol_put, \
2224 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2225 }
2226
2227#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2228 { \
2229 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2230 /* .name = "Capture Source", */ \
2231 .name = "Input Source", \
2232 .count = num, \
2233 .info = alc_mux_enum_info, \
2234 .get = alc_mux_enum_get, \
2235 .put = alc_mux_enum_put, \
a23b688f
TI
2236 }
2237
2238#define DEFINE_CAPMIX(num) \
2239static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2240 _DEFINE_CAPMIX(num), \
2241 _DEFINE_CAPSRC(num), \
2242 { } /* end */ \
2243}
2244
2245#define DEFINE_CAPMIX_NOSRC(num) \
2246static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2247 _DEFINE_CAPMIX(num), \
2248 { } /* end */ \
f9e336f6
TI
2249}
2250
2251/* up to three ADCs */
2252DEFINE_CAPMIX(1);
2253DEFINE_CAPMIX(2);
2254DEFINE_CAPMIX(3);
a23b688f
TI
2255DEFINE_CAPMIX_NOSRC(1);
2256DEFINE_CAPMIX_NOSRC(2);
2257DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2258
2259/*
2260 * ALC880 5-stack model
2261 *
9c7f852e
TI
2262 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2263 * Side = 0x02 (0xd)
e9edcee0
TI
2264 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2265 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2266 */
2267
2268/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 2269static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2270 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2271 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2272 { } /* end */
2273};
2274
e9edcee0
TI
2275/* channel source setting (6/8 channel selection for 5-stack) */
2276/* 6ch mode */
2277static struct hda_verb alc880_fivestack_ch6_init[] = {
2278 /* set line-in to input, mute it */
2279 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2280 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2281 { } /* end */
2282};
2283
e9edcee0
TI
2284/* 8ch mode */
2285static struct hda_verb alc880_fivestack_ch8_init[] = {
2286 /* set line-in to output, unmute it */
2287 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2288 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2289 { } /* end */
2290};
2291
d2a6d7dc 2292static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2293 { 6, alc880_fivestack_ch6_init },
2294 { 8, alc880_fivestack_ch8_init },
2295};
2296
2297
2298/*
2299 * ALC880 6-stack model
2300 *
9c7f852e
TI
2301 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2302 * Side = 0x05 (0x0f)
e9edcee0
TI
2303 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2304 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2305 */
2306
2307static hda_nid_t alc880_6st_dac_nids[4] = {
2308 /* front, rear, clfe, rear_surr */
2309 0x02, 0x03, 0x04, 0x05
f12ab1e0 2310};
e9edcee0
TI
2311
2312static struct hda_input_mux alc880_6stack_capture_source = {
2313 .num_items = 4,
2314 .items = {
2315 { "Mic", 0x0 },
2316 { "Front Mic", 0x1 },
2317 { "Line", 0x2 },
2318 { "CD", 0x4 },
2319 },
2320};
2321
2322/* fixed 8-channels */
d2a6d7dc 2323static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2324 { 8, NULL },
2325};
2326
c8b6bf9b 2327static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2328 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2329 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2330 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2331 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2332 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2333 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2334 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2335 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2336 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2337 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2338 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2339 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2340 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2341 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2342 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2343 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2344 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2345 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2346 {
2347 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2348 .name = "Channel Mode",
df694daa
KY
2349 .info = alc_ch_mode_info,
2350 .get = alc_ch_mode_get,
2351 .put = alc_ch_mode_put,
16ded525
TI
2352 },
2353 { } /* end */
2354};
2355
e9edcee0
TI
2356
2357/*
2358 * ALC880 W810 model
2359 *
2360 * W810 has rear IO for:
2361 * Front (DAC 02)
2362 * Surround (DAC 03)
2363 * Center/LFE (DAC 04)
2364 * Digital out (06)
2365 *
2366 * The system also has a pair of internal speakers, and a headphone jack.
2367 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2368 *
e9edcee0
TI
2369 * There is a variable resistor to control the speaker or headphone
2370 * volume. This is a hardware-only device without a software API.
2371 *
2372 * Plugging headphones in will disable the internal speakers. This is
2373 * implemented in hardware, not via the driver using jack sense. In
2374 * a similar fashion, plugging into the rear socket marked "front" will
2375 * disable both the speakers and headphones.
2376 *
2377 * For input, there's a microphone jack, and an "audio in" jack.
2378 * These may not do anything useful with this driver yet, because I
2379 * haven't setup any initialization verbs for these yet...
2380 */
2381
2382static hda_nid_t alc880_w810_dac_nids[3] = {
2383 /* front, rear/surround, clfe */
2384 0x02, 0x03, 0x04
16ded525
TI
2385};
2386
e9edcee0 2387/* fixed 6 channels */
d2a6d7dc 2388static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2389 { 6, NULL }
2390};
2391
2392/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 2393static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2394 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2395 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2396 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2397 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2398 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2399 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2400 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2401 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2402 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2403 { } /* end */
2404};
2405
2406
2407/*
2408 * Z710V model
2409 *
2410 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2411 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2412 * Line = 0x1a
e9edcee0
TI
2413 */
2414
2415static hda_nid_t alc880_z71v_dac_nids[1] = {
2416 0x02
2417};
2418#define ALC880_Z71V_HP_DAC 0x03
2419
2420/* fixed 2 channels */
d2a6d7dc 2421static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2422 { 2, NULL }
2423};
2424
c8b6bf9b 2425static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2426 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2427 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2428 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2429 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2430 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2431 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2432 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2433 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2434 { } /* end */
2435};
2436
e9edcee0 2437
e9edcee0
TI
2438/*
2439 * ALC880 F1734 model
2440 *
2441 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2442 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2443 */
2444
2445static hda_nid_t alc880_f1734_dac_nids[1] = {
2446 0x03
2447};
2448#define ALC880_F1734_HP_DAC 0x02
2449
c8b6bf9b 2450static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2451 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2452 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2453 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2454 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2455 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2456 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2457 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2458 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2459 { } /* end */
2460};
2461
937b4160
TI
2462static struct hda_input_mux alc880_f1734_capture_source = {
2463 .num_items = 2,
2464 .items = {
2465 { "Mic", 0x1 },
2466 { "CD", 0x4 },
2467 },
2468};
2469
e9edcee0 2470
e9edcee0
TI
2471/*
2472 * ALC880 ASUS model
2473 *
2474 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2475 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2476 * Mic = 0x18, Line = 0x1a
2477 */
2478
2479#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2480#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2481
c8b6bf9b 2482static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2483 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2484 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2485 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2486 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2487 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2488 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2489 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2490 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2491 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2492 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2493 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2494 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2495 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2496 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2497 {
2498 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2499 .name = "Channel Mode",
df694daa
KY
2500 .info = alc_ch_mode_info,
2501 .get = alc_ch_mode_get,
2502 .put = alc_ch_mode_put,
16ded525
TI
2503 },
2504 { } /* end */
2505};
e9edcee0 2506
e9edcee0
TI
2507/*
2508 * ALC880 ASUS W1V model
2509 *
2510 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2511 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2512 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2513 */
2514
2515/* additional mixers to alc880_asus_mixer */
c8b6bf9b 2516static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
2517 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2518 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2519 { } /* end */
2520};
2521
df694daa
KY
2522/* TCL S700 */
2523static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2524 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2525 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2526 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2527 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2528 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2529 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2530 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2531 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2532 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2533 { } /* end */
2534};
2535
ccc656ce
KY
2536/* Uniwill */
2537static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2538 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2539 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2540 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2541 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2542 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2543 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2544 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2545 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2546 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2547 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2548 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2549 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2550 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2551 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2552 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2553 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2554 {
2555 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2556 .name = "Channel Mode",
2557 .info = alc_ch_mode_info,
2558 .get = alc_ch_mode_get,
2559 .put = alc_ch_mode_put,
2560 },
2561 { } /* end */
2562};
2563
2cf9f0fc
TD
2564static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2565 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2566 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2567 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2568 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2569 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2570 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2571 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2572 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2573 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2574 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2575 { } /* end */
2576};
2577
ccc656ce 2578static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2579 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2580 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2581 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2582 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2583 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2584 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2585 { } /* end */
2586};
2587
2134ea4f
TI
2588/*
2589 * virtual master controls
2590 */
2591
2592/*
2593 * slave controls for virtual master
2594 */
2595static const char *alc_slave_vols[] = {
2596 "Front Playback Volume",
2597 "Surround Playback Volume",
2598 "Center Playback Volume",
2599 "LFE Playback Volume",
2600 "Side Playback Volume",
2601 "Headphone Playback Volume",
2602 "Speaker Playback Volume",
2603 "Mono Playback Volume",
2134ea4f 2604 "Line-Out Playback Volume",
26f5df26 2605 "PCM Playback Volume",
2134ea4f
TI
2606 NULL,
2607};
2608
2609static const char *alc_slave_sws[] = {
2610 "Front Playback Switch",
2611 "Surround Playback Switch",
2612 "Center Playback Switch",
2613 "LFE Playback Switch",
2614 "Side Playback Switch",
2615 "Headphone Playback Switch",
2616 "Speaker Playback Switch",
2617 "Mono Playback Switch",
edb54a55 2618 "IEC958 Playback Switch",
23033b2b
TI
2619 "Line-Out Playback Switch",
2620 "PCM Playback Switch",
2134ea4f
TI
2621 NULL,
2622};
2623
1da177e4 2624/*
e9edcee0 2625 * build control elements
1da177e4 2626 */
603c4019 2627
5b0cb1d8
JK
2628#define NID_MAPPING (-1)
2629
2630#define SUBDEV_SPEAKER_ (0 << 6)
2631#define SUBDEV_HP_ (1 << 6)
2632#define SUBDEV_LINE_ (2 << 6)
2633#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2634#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2635#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2636
603c4019
TI
2637static void alc_free_kctls(struct hda_codec *codec);
2638
67d634c0 2639#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2640/* additional beep mixers; the actual parameters are overwritten at build */
2641static struct snd_kcontrol_new alc_beep_mixer[] = {
2642 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 2643 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
2644 { } /* end */
2645};
67d634c0 2646#endif
45bdd1c1 2647
1da177e4
LT
2648static int alc_build_controls(struct hda_codec *codec)
2649{
2650 struct alc_spec *spec = codec->spec;
2f44f847 2651 struct snd_kcontrol *kctl = NULL;
5b0cb1d8
JK
2652 struct snd_kcontrol_new *knew;
2653 int i, j, err;
2654 unsigned int u;
2655 hda_nid_t nid;
1da177e4
LT
2656
2657 for (i = 0; i < spec->num_mixers; i++) {
2658 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2659 if (err < 0)
2660 return err;
2661 }
f9e336f6
TI
2662 if (spec->cap_mixer) {
2663 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2664 if (err < 0)
2665 return err;
2666 }
1da177e4 2667 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2668 err = snd_hda_create_spdif_out_ctls(codec,
2669 spec->multiout.dig_out_nid);
1da177e4
LT
2670 if (err < 0)
2671 return err;
e64f14f4
TI
2672 if (!spec->no_analog) {
2673 err = snd_hda_create_spdif_share_sw(codec,
2674 &spec->multiout);
2675 if (err < 0)
2676 return err;
2677 spec->multiout.share_spdif = 1;
2678 }
1da177e4
LT
2679 }
2680 if (spec->dig_in_nid) {
2681 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2682 if (err < 0)
2683 return err;
2684 }
2134ea4f 2685
67d634c0 2686#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2687 /* create beep controls if needed */
2688 if (spec->beep_amp) {
2689 struct snd_kcontrol_new *knew;
2690 for (knew = alc_beep_mixer; knew->name; knew++) {
2691 struct snd_kcontrol *kctl;
2692 kctl = snd_ctl_new1(knew, codec);
2693 if (!kctl)
2694 return -ENOMEM;
2695 kctl->private_value = spec->beep_amp;
5e26dfd0 2696 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
2697 if (err < 0)
2698 return err;
2699 }
2700 }
67d634c0 2701#endif
45bdd1c1 2702
2134ea4f 2703 /* if we have no master control, let's create it */
e64f14f4
TI
2704 if (!spec->no_analog &&
2705 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2706 unsigned int vmaster_tlv[4];
2134ea4f 2707 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2708 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2709 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2710 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2711 if (err < 0)
2712 return err;
2713 }
e64f14f4
TI
2714 if (!spec->no_analog &&
2715 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2716 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2717 NULL, alc_slave_sws);
2718 if (err < 0)
2719 return err;
2720 }
2721
5b0cb1d8 2722 /* assign Capture Source enums to NID */
fbe618f2
TI
2723 if (spec->capsrc_nids || spec->adc_nids) {
2724 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2725 if (!kctl)
2726 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2727 for (i = 0; kctl && i < kctl->count; i++) {
2728 hda_nid_t *nids = spec->capsrc_nids;
2729 if (!nids)
2730 nids = spec->adc_nids;
2731 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
2732 if (err < 0)
2733 return err;
2734 }
5b0cb1d8
JK
2735 }
2736 if (spec->cap_mixer) {
2737 const char *kname = kctl ? kctl->id.name : NULL;
2738 for (knew = spec->cap_mixer; knew->name; knew++) {
2739 if (kname && strcmp(knew->name, kname) == 0)
2740 continue;
2741 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2742 for (i = 0; kctl && i < kctl->count; i++) {
2743 err = snd_hda_add_nid(codec, kctl, i,
2744 spec->adc_nids[i]);
2745 if (err < 0)
2746 return err;
2747 }
2748 }
2749 }
2750
2751 /* other nid->control mapping */
2752 for (i = 0; i < spec->num_mixers; i++) {
2753 for (knew = spec->mixers[i]; knew->name; knew++) {
2754 if (knew->iface != NID_MAPPING)
2755 continue;
2756 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2757 if (kctl == NULL)
2758 continue;
2759 u = knew->subdevice;
2760 for (j = 0; j < 4; j++, u >>= 8) {
2761 nid = u & 0x3f;
2762 if (nid == 0)
2763 continue;
2764 switch (u & 0xc0) {
2765 case SUBDEV_SPEAKER_:
2766 nid = spec->autocfg.speaker_pins[nid];
2767 break;
2768 case SUBDEV_LINE_:
2769 nid = spec->autocfg.line_out_pins[nid];
2770 break;
2771 case SUBDEV_HP_:
2772 nid = spec->autocfg.hp_pins[nid];
2773 break;
2774 default:
2775 continue;
2776 }
2777 err = snd_hda_add_nid(codec, kctl, 0, nid);
2778 if (err < 0)
2779 return err;
2780 }
2781 u = knew->private_value;
2782 for (j = 0; j < 4; j++, u >>= 8) {
2783 nid = u & 0xff;
2784 if (nid == 0)
2785 continue;
2786 err = snd_hda_add_nid(codec, kctl, 0, nid);
2787 if (err < 0)
2788 return err;
2789 }
2790 }
2791 }
bae84e70
TI
2792
2793 alc_free_kctls(codec); /* no longer needed */
2794
1da177e4
LT
2795 return 0;
2796}
2797
e9edcee0 2798
1da177e4
LT
2799/*
2800 * initialize the codec volumes, etc
2801 */
2802
e9edcee0
TI
2803/*
2804 * generic initialization of ADC, input mixers and output mixers
2805 */
2806static struct hda_verb alc880_volume_init_verbs[] = {
2807 /*
2808 * Unmute ADC0-2 and set the default input to mic-in
2809 */
71fe7b82 2810 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2811 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2812 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2813 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2814 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2815 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 2816
e9edcee0
TI
2817 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2818 * mixer widget
9c7f852e
TI
2819 * Note: PASD motherboards uses the Line In 2 as the input for front
2820 * panel mic (mic 2)
1da177e4 2821 */
e9edcee0 2822 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
2823 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2824 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2825 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2826 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2827 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2828 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2829 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 2830
e9edcee0
TI
2831 /*
2832 * Set up output mixers (0x0c - 0x0f)
1da177e4 2833 */
e9edcee0
TI
2834 /* set vol=0 to output mixers */
2835 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2836 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2837 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2838 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2839 /* set up input amps for analog loopback */
2840 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
2841 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2842 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2843 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2844 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2845 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2846 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2847 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2848 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
2849
2850 { }
2851};
2852
e9edcee0
TI
2853/*
2854 * 3-stack pin configuration:
2855 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2856 */
2857static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2858 /*
2859 * preset connection lists of input pins
2860 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2861 */
2862 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2863 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2864 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2865
2866 /*
2867 * Set pin mode and muting
2868 */
2869 /* set front pin widgets 0x14 for output */
05acb863 2870 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2871 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2872 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2873 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2874 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2875 /* Mic2 (as headphone out) for HP output */
2876 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2877 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2878 /* Line In pin widget for input */
05acb863 2879 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
2880 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2881 /* Line2 (as front mic) pin widget for input and vref at 80% */
2882 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2883 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2884 /* CD pin widget for input */
05acb863 2885 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 2886
e9edcee0
TI
2887 { }
2888};
1da177e4 2889
e9edcee0
TI
2890/*
2891 * 5-stack pin configuration:
2892 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2893 * line-in/side = 0x1a, f-mic = 0x1b
2894 */
2895static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2896 /*
2897 * preset connection lists of input pins
2898 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 2899 */
e9edcee0
TI
2900 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2901 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 2902
e9edcee0
TI
2903 /*
2904 * Set pin mode and muting
1da177e4 2905 */
e9edcee0
TI
2906 /* set pin widgets 0x14-0x17 for output */
2907 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2908 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2909 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2910 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2911 /* unmute pins for output (no gain on this amp) */
2912 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2913 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2914 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2915 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2916
2917 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2918 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2919 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2920 /* Mic2 (as headphone out) for HP output */
2921 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2922 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2923 /* Line In pin widget for input */
2924 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2925 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2926 /* Line2 (as front mic) pin widget for input and vref at 80% */
2927 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2928 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2929 /* CD pin widget for input */
2930 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
2931
2932 { }
2933};
2934
e9edcee0
TI
2935/*
2936 * W810 pin configuration:
2937 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2938 */
2939static struct hda_verb alc880_pin_w810_init_verbs[] = {
2940 /* hphone/speaker input selector: front DAC */
2941 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 2942
05acb863 2943 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2944 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2945 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2946 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2947 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2948 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2949
e9edcee0 2950 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 2951 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2952
1da177e4
LT
2953 { }
2954};
2955
e9edcee0
TI
2956/*
2957 * Z71V pin configuration:
2958 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2959 */
2960static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 2961 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2962 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2963 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2964 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 2965
16ded525 2966 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2967 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 2968 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2969 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
2970
2971 { }
2972};
2973
e9edcee0
TI
2974/*
2975 * 6-stack pin configuration:
9c7f852e
TI
2976 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2977 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
2978 */
2979static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2980 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2981
16ded525 2982 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2983 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2984 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2985 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2986 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2987 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2988 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2989 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2990
16ded525 2991 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2992 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2993 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2994 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2995 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 2996 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2997 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2998 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2999 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3000
e9edcee0
TI
3001 { }
3002};
3003
ccc656ce
KY
3004/*
3005 * Uniwill pin configuration:
3006 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3007 * line = 0x1a
3008 */
3009static struct hda_verb alc880_uniwill_init_verbs[] = {
3010 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3011
3012 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3013 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3014 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3015 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3016 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3017 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3018 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3019 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3020 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3021 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3022 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3023 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3024 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3025 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3026
3027 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3028 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3029 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3030 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3031 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3032 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3033 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3034 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3035 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3036
3037 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3038 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3039
3040 { }
3041};
3042
3043/*
3044* Uniwill P53
ea1fb29a 3045* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
3046 */
3047static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3048 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3049
3050 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3051 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3052 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3053 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3054 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3055 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3056 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3057 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3058 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3059 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3060 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3061 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3062
3063 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3064 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3065 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3066 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3067 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3068 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3069
3070 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3071 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3072
3073 { }
3074};
3075
2cf9f0fc
TD
3076static struct hda_verb alc880_beep_init_verbs[] = {
3077 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3078 { }
3079};
3080
458a4fab
TI
3081/* auto-toggle front mic */
3082static void alc880_uniwill_mic_automute(struct hda_codec *codec)
3083{
3084 unsigned int present;
3085 unsigned char bits;
ccc656ce 3086
864f92be 3087 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3088 bits = present ? HDA_AMP_MUTE : 0;
3089 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3090}
3091
4f5d1706 3092static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3093{
a9fd4f3f
TI
3094 struct alc_spec *spec = codec->spec;
3095
3096 spec->autocfg.hp_pins[0] = 0x14;
3097 spec->autocfg.speaker_pins[0] = 0x15;
3098 spec->autocfg.speaker_pins[0] = 0x16;
4f5d1706
TI
3099}
3100
3101static void alc880_uniwill_init_hook(struct hda_codec *codec)
3102{
a9fd4f3f 3103 alc_automute_amp(codec);
458a4fab 3104 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
3105}
3106
3107static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3108 unsigned int res)
3109{
3110 /* Looks like the unsol event is incompatible with the standard
3111 * definition. 4bit tag is placed at 28 bit!
3112 */
458a4fab 3113 switch (res >> 28) {
458a4fab
TI
3114 case ALC880_MIC_EVENT:
3115 alc880_uniwill_mic_automute(codec);
3116 break;
a9fd4f3f
TI
3117 default:
3118 alc_automute_amp_unsol_event(codec, res);
3119 break;
458a4fab 3120 }
ccc656ce
KY
3121}
3122
4f5d1706 3123static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3124{
a9fd4f3f 3125 struct alc_spec *spec = codec->spec;
ccc656ce 3126
a9fd4f3f
TI
3127 spec->autocfg.hp_pins[0] = 0x14;
3128 spec->autocfg.speaker_pins[0] = 0x15;
ccc656ce
KY
3129}
3130
3131static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3132{
3133 unsigned int present;
ea1fb29a 3134
ccc656ce 3135 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3136 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3137 present &= HDA_AMP_VOLMASK;
3138 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3139 HDA_AMP_VOLMASK, present);
3140 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3141 HDA_AMP_VOLMASK, present);
ccc656ce 3142}
47fd830a 3143
ccc656ce
KY
3144static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3145 unsigned int res)
3146{
3147 /* Looks like the unsol event is incompatible with the standard
3148 * definition. 4bit tag is placed at 28 bit!
3149 */
f12ab1e0 3150 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3151 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
3152 else
3153 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
3154}
3155
e9edcee0
TI
3156/*
3157 * F1734 pin configuration:
3158 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3159 */
3160static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3161 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3162 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3163 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3164 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3165 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3166
e9edcee0 3167 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3168 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3169 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3170 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3171
e9edcee0
TI
3172 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3173 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3174 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3175 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3176 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3177 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3178 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3179 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3180 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3181
937b4160
TI
3182 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3183 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3184
dfc0ff62
TI
3185 { }
3186};
3187
e9edcee0
TI
3188/*
3189 * ASUS pin configuration:
3190 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3191 */
3192static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3193 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3194 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3195 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3196 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3197
3198 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3199 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3200 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3201 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3202 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3203 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3204 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3205 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3206
3207 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3208 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3209 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3210 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3211 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3212 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3213 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3214 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3215 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3216
e9edcee0
TI
3217 { }
3218};
16ded525 3219
e9edcee0 3220/* Enable GPIO mask and set output */
bc9f98a9
KY
3221#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3222#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3223#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3224
3225/* Clevo m520g init */
3226static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3227 /* headphone output */
3228 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3229 /* line-out */
3230 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3231 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3232 /* Line-in */
3233 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3234 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3235 /* CD */
3236 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3237 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3238 /* Mic1 (rear panel) */
3239 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3240 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3241 /* Mic2 (front panel) */
3242 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3243 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3244 /* headphone */
3245 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3246 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3247 /* change to EAPD mode */
3248 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3249 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3250
3251 { }
16ded525
TI
3252};
3253
df694daa 3254static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3255 /* change to EAPD mode */
3256 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3257 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3258
df694daa
KY
3259 /* Headphone output */
3260 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3261 /* Front output*/
3262 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3263 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3264
3265 /* Line In pin widget for input */
3266 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3267 /* CD pin widget for input */
3268 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3269 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3270 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3271
3272 /* change to EAPD mode */
3273 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3274 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3275
3276 { }
3277};
16ded525 3278
e9edcee0 3279/*
ae6b813a
TI
3280 * LG m1 express dual
3281 *
3282 * Pin assignment:
3283 * Rear Line-In/Out (blue): 0x14
3284 * Build-in Mic-In: 0x15
3285 * Speaker-out: 0x17
3286 * HP-Out (green): 0x1b
3287 * Mic-In/Out (red): 0x19
3288 * SPDIF-Out: 0x1e
3289 */
3290
3291/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3292static hda_nid_t alc880_lg_dac_nids[3] = {
3293 0x05, 0x02, 0x03
3294};
3295
3296/* seems analog CD is not working */
3297static struct hda_input_mux alc880_lg_capture_source = {
3298 .num_items = 3,
3299 .items = {
3300 { "Mic", 0x1 },
3301 { "Line", 0x5 },
3302 { "Internal Mic", 0x6 },
3303 },
3304};
3305
3306/* 2,4,6 channel modes */
3307static struct hda_verb alc880_lg_ch2_init[] = {
3308 /* set line-in and mic-in to input */
3309 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3310 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3311 { }
3312};
3313
3314static struct hda_verb alc880_lg_ch4_init[] = {
3315 /* set line-in to out and mic-in to input */
3316 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3317 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3318 { }
3319};
3320
3321static struct hda_verb alc880_lg_ch6_init[] = {
3322 /* set line-in and mic-in to output */
3323 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3324 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3325 { }
3326};
3327
3328static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3329 { 2, alc880_lg_ch2_init },
3330 { 4, alc880_lg_ch4_init },
3331 { 6, alc880_lg_ch6_init },
3332};
3333
3334static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3335 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3336 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3337 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3338 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3339 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3340 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3341 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3342 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3343 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3344 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3345 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3346 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3347 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3348 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3349 {
3350 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3351 .name = "Channel Mode",
3352 .info = alc_ch_mode_info,
3353 .get = alc_ch_mode_get,
3354 .put = alc_ch_mode_put,
3355 },
3356 { } /* end */
3357};
3358
3359static struct hda_verb alc880_lg_init_verbs[] = {
3360 /* set capture source to mic-in */
3361 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3362 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3363 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3364 /* mute all amp mixer inputs */
3365 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3366 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3367 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3368 /* line-in to input */
3369 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3370 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3371 /* built-in mic */
3372 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3373 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3374 /* speaker-out */
3375 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3376 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3377 /* mic-in to input */
3378 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3379 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3380 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3381 /* HP-out */
3382 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3383 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3384 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3385 /* jack sense */
a9fd4f3f 3386 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3387 { }
3388};
3389
3390/* toggle speaker-output according to the hp-jack state */
4f5d1706 3391static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3392{
a9fd4f3f 3393 struct alc_spec *spec = codec->spec;
ae6b813a 3394
a9fd4f3f
TI
3395 spec->autocfg.hp_pins[0] = 0x1b;
3396 spec->autocfg.speaker_pins[0] = 0x17;
ae6b813a
TI
3397}
3398
d681518a
TI
3399/*
3400 * LG LW20
3401 *
3402 * Pin assignment:
3403 * Speaker-out: 0x14
3404 * Mic-In: 0x18
e4f41da9
CM
3405 * Built-in Mic-In: 0x19
3406 * Line-In: 0x1b
3407 * HP-Out: 0x1a
d681518a
TI
3408 * SPDIF-Out: 0x1e
3409 */
3410
d681518a 3411static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3412 .num_items = 3,
d681518a
TI
3413 .items = {
3414 { "Mic", 0x0 },
3415 { "Internal Mic", 0x1 },
e4f41da9 3416 { "Line In", 0x2 },
d681518a
TI
3417 },
3418};
3419
0a8c5da3
CM
3420#define alc880_lg_lw_modes alc880_threestack_modes
3421
d681518a 3422static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3423 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3424 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3425 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3426 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3427 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3428 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3429 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3430 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3431 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3432 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3433 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3434 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3435 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3436 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3437 {
3438 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3439 .name = "Channel Mode",
3440 .info = alc_ch_mode_info,
3441 .get = alc_ch_mode_get,
3442 .put = alc_ch_mode_put,
3443 },
d681518a
TI
3444 { } /* end */
3445};
3446
3447static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3448 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3449 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3450 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3451
d681518a
TI
3452 /* set capture source to mic-in */
3453 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3454 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3455 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3456 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3457 /* speaker-out */
3458 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3459 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3460 /* HP-out */
d681518a
TI
3461 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3462 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3463 /* mic-in to input */
3464 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3465 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3466 /* built-in mic */
3467 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3468 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3469 /* jack sense */
a9fd4f3f 3470 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3471 { }
3472};
3473
3474/* toggle speaker-output according to the hp-jack state */
4f5d1706 3475static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3476{
a9fd4f3f 3477 struct alc_spec *spec = codec->spec;
d681518a 3478
a9fd4f3f
TI
3479 spec->autocfg.hp_pins[0] = 0x1b;
3480 spec->autocfg.speaker_pins[0] = 0x14;
d681518a
TI
3481}
3482
df99cd33
TI
3483static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3484 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3485 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3486 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3487 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3488 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3489 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3490 { } /* end */
3491};
3492
3493static struct hda_input_mux alc880_medion_rim_capture_source = {
3494 .num_items = 2,
3495 .items = {
3496 { "Mic", 0x0 },
3497 { "Internal Mic", 0x1 },
3498 },
3499};
3500
3501static struct hda_verb alc880_medion_rim_init_verbs[] = {
3502 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3503
3504 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3505 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3506
3507 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3508 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3509 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3510 /* Mic2 (as headphone out) for HP output */
3511 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3512 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3513 /* Internal Speaker */
3514 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3515 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3516
3517 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3518 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3519
3520 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3521 { }
3522};
3523
3524/* toggle speaker-output according to the hp-jack state */
3525static void alc880_medion_rim_automute(struct hda_codec *codec)
3526{
a9fd4f3f
TI
3527 struct alc_spec *spec = codec->spec;
3528 alc_automute_amp(codec);
3529 /* toggle EAPD */
3530 if (spec->jack_present)
df99cd33
TI
3531 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3532 else
3533 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3534}
3535
3536static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3537 unsigned int res)
3538{
3539 /* Looks like the unsol event is incompatible with the standard
3540 * definition. 4bit tag is placed at 28 bit!
3541 */
3542 if ((res >> 28) == ALC880_HP_EVENT)
3543 alc880_medion_rim_automute(codec);
3544}
3545
4f5d1706 3546static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
3547{
3548 struct alc_spec *spec = codec->spec;
3549
3550 spec->autocfg.hp_pins[0] = 0x14;
3551 spec->autocfg.speaker_pins[0] = 0x1b;
a9fd4f3f
TI
3552}
3553
cb53c626
TI
3554#ifdef CONFIG_SND_HDA_POWER_SAVE
3555static struct hda_amp_list alc880_loopbacks[] = {
3556 { 0x0b, HDA_INPUT, 0 },
3557 { 0x0b, HDA_INPUT, 1 },
3558 { 0x0b, HDA_INPUT, 2 },
3559 { 0x0b, HDA_INPUT, 3 },
3560 { 0x0b, HDA_INPUT, 4 },
3561 { } /* end */
3562};
3563
3564static struct hda_amp_list alc880_lg_loopbacks[] = {
3565 { 0x0b, HDA_INPUT, 1 },
3566 { 0x0b, HDA_INPUT, 6 },
3567 { 0x0b, HDA_INPUT, 7 },
3568 { } /* end */
3569};
3570#endif
3571
ae6b813a
TI
3572/*
3573 * Common callbacks
e9edcee0
TI
3574 */
3575
1da177e4
LT
3576static int alc_init(struct hda_codec *codec)
3577{
3578 struct alc_spec *spec = codec->spec;
e9edcee0
TI
3579 unsigned int i;
3580
2c3bf9ab 3581 alc_fix_pll(codec);
4a79ba34 3582 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 3583
e9edcee0
TI
3584 for (i = 0; i < spec->num_init_verbs; i++)
3585 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
3586
3587 if (spec->init_hook)
3588 spec->init_hook(codec);
3589
ad35879a
TI
3590#ifdef CONFIG_SND_HDA_POWER_SAVE
3591 if (codec->patch_ops.check_power_status)
3592 codec->patch_ops.check_power_status(codec, 0x01);
3593#endif
1da177e4
LT
3594 return 0;
3595}
3596
ae6b813a
TI
3597static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3598{
3599 struct alc_spec *spec = codec->spec;
3600
3601 if (spec->unsol_event)
3602 spec->unsol_event(codec, res);
3603}
3604
cb53c626
TI
3605#ifdef CONFIG_SND_HDA_POWER_SAVE
3606static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3607{
3608 struct alc_spec *spec = codec->spec;
3609 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3610}
3611#endif
3612
1da177e4
LT
3613/*
3614 * Analog playback callbacks
3615 */
3616static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3617 struct hda_codec *codec,
c8b6bf9b 3618 struct snd_pcm_substream *substream)
1da177e4
LT
3619{
3620 struct alc_spec *spec = codec->spec;
9a08160b
TI
3621 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3622 hinfo);
1da177e4
LT
3623}
3624
3625static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3626 struct hda_codec *codec,
3627 unsigned int stream_tag,
3628 unsigned int format,
c8b6bf9b 3629 struct snd_pcm_substream *substream)
1da177e4
LT
3630{
3631 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3632 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3633 stream_tag, format, substream);
1da177e4
LT
3634}
3635
3636static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3637 struct hda_codec *codec,
c8b6bf9b 3638 struct snd_pcm_substream *substream)
1da177e4
LT
3639{
3640 struct alc_spec *spec = codec->spec;
3641 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3642}
3643
3644/*
3645 * Digital out
3646 */
3647static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3648 struct hda_codec *codec,
c8b6bf9b 3649 struct snd_pcm_substream *substream)
1da177e4
LT
3650{
3651 struct alc_spec *spec = codec->spec;
3652 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3653}
3654
6b97eb45
TI
3655static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3656 struct hda_codec *codec,
3657 unsigned int stream_tag,
3658 unsigned int format,
3659 struct snd_pcm_substream *substream)
3660{
3661 struct alc_spec *spec = codec->spec;
3662 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3663 stream_tag, format, substream);
3664}
3665
9b5f12e5
TI
3666static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3667 struct hda_codec *codec,
3668 struct snd_pcm_substream *substream)
3669{
3670 struct alc_spec *spec = codec->spec;
3671 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3672}
3673
1da177e4
LT
3674static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3675 struct hda_codec *codec,
c8b6bf9b 3676 struct snd_pcm_substream *substream)
1da177e4
LT
3677{
3678 struct alc_spec *spec = codec->spec;
3679 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3680}
3681
3682/*
3683 * Analog capture
3684 */
6330079f 3685static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3686 struct hda_codec *codec,
3687 unsigned int stream_tag,
3688 unsigned int format,
c8b6bf9b 3689 struct snd_pcm_substream *substream)
1da177e4
LT
3690{
3691 struct alc_spec *spec = codec->spec;
3692
6330079f 3693 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3694 stream_tag, 0, format);
3695 return 0;
3696}
3697
6330079f 3698static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3699 struct hda_codec *codec,
c8b6bf9b 3700 struct snd_pcm_substream *substream)
1da177e4
LT
3701{
3702 struct alc_spec *spec = codec->spec;
3703
888afa15
TI
3704 snd_hda_codec_cleanup_stream(codec,
3705 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3706 return 0;
3707}
3708
840b64c0
TI
3709/* analog capture with dynamic dual-adc changes */
3710static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3711 struct hda_codec *codec,
3712 unsigned int stream_tag,
3713 unsigned int format,
3714 struct snd_pcm_substream *substream)
3715{
3716 struct alc_spec *spec = codec->spec;
3717 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
3718 spec->cur_adc_stream_tag = stream_tag;
3719 spec->cur_adc_format = format;
3720 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
3721 return 0;
3722}
3723
3724static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3725 struct hda_codec *codec,
3726 struct snd_pcm_substream *substream)
3727{
3728 struct alc_spec *spec = codec->spec;
3729 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
3730 spec->cur_adc = 0;
3731 return 0;
3732}
3733
3734static struct hda_pcm_stream dualmic_pcm_analog_capture = {
3735 .substreams = 1,
3736 .channels_min = 2,
3737 .channels_max = 2,
3738 .nid = 0, /* fill later */
3739 .ops = {
3740 .prepare = dualmic_capture_pcm_prepare,
3741 .cleanup = dualmic_capture_pcm_cleanup
3742 },
3743};
1da177e4
LT
3744
3745/*
3746 */
3747static struct hda_pcm_stream alc880_pcm_analog_playback = {
3748 .substreams = 1,
3749 .channels_min = 2,
3750 .channels_max = 8,
e9edcee0 3751 /* NID is set in alc_build_pcms */
1da177e4
LT
3752 .ops = {
3753 .open = alc880_playback_pcm_open,
3754 .prepare = alc880_playback_pcm_prepare,
3755 .cleanup = alc880_playback_pcm_cleanup
3756 },
3757};
3758
3759static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
3760 .substreams = 1,
3761 .channels_min = 2,
3762 .channels_max = 2,
3763 /* NID is set in alc_build_pcms */
3764};
3765
3766static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3767 .substreams = 1,
3768 .channels_min = 2,
3769 .channels_max = 2,
3770 /* NID is set in alc_build_pcms */
3771};
3772
3773static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3774 .substreams = 2, /* can be overridden */
1da177e4
LT
3775 .channels_min = 2,
3776 .channels_max = 2,
e9edcee0 3777 /* NID is set in alc_build_pcms */
1da177e4 3778 .ops = {
6330079f
TI
3779 .prepare = alc880_alt_capture_pcm_prepare,
3780 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
3781 },
3782};
3783
3784static struct hda_pcm_stream alc880_pcm_digital_playback = {
3785 .substreams = 1,
3786 .channels_min = 2,
3787 .channels_max = 2,
3788 /* NID is set in alc_build_pcms */
3789 .ops = {
3790 .open = alc880_dig_playback_pcm_open,
6b97eb45 3791 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
3792 .prepare = alc880_dig_playback_pcm_prepare,
3793 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
3794 },
3795};
3796
3797static struct hda_pcm_stream alc880_pcm_digital_capture = {
3798 .substreams = 1,
3799 .channels_min = 2,
3800 .channels_max = 2,
3801 /* NID is set in alc_build_pcms */
3802};
3803
4c5186ed 3804/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 3805static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
3806 .substreams = 0,
3807 .channels_min = 0,
3808 .channels_max = 0,
3809};
3810
1da177e4
LT
3811static int alc_build_pcms(struct hda_codec *codec)
3812{
3813 struct alc_spec *spec = codec->spec;
3814 struct hda_pcm *info = spec->pcm_rec;
3815 int i;
3816
3817 codec->num_pcms = 1;
3818 codec->pcm_info = info;
3819
e64f14f4
TI
3820 if (spec->no_analog)
3821 goto skip_analog;
3822
812a2cca
TI
3823 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3824 "%s Analog", codec->chip_name);
1da177e4 3825 info->name = spec->stream_name_analog;
274693f3 3826
4a471b7d 3827 if (spec->stream_analog_playback) {
da3cec35
TI
3828 if (snd_BUG_ON(!spec->multiout.dac_nids))
3829 return -EINVAL;
4a471b7d
TI
3830 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3831 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3832 }
3833 if (spec->stream_analog_capture) {
da3cec35
TI
3834 if (snd_BUG_ON(!spec->adc_nids))
3835 return -EINVAL;
4a471b7d
TI
3836 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3837 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3838 }
3839
3840 if (spec->channel_mode) {
3841 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3842 for (i = 0; i < spec->num_channel_mode; i++) {
3843 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3844 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3845 }
1da177e4
LT
3846 }
3847 }
3848
e64f14f4 3849 skip_analog:
e08a007d 3850 /* SPDIF for stream index #1 */
1da177e4 3851 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
3852 snprintf(spec->stream_name_digital,
3853 sizeof(spec->stream_name_digital),
3854 "%s Digital", codec->chip_name);
e08a007d 3855 codec->num_pcms = 2;
b25c9da1 3856 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 3857 info = spec->pcm_rec + 1;
1da177e4 3858 info->name = spec->stream_name_digital;
8c441982
TI
3859 if (spec->dig_out_type)
3860 info->pcm_type = spec->dig_out_type;
3861 else
3862 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
3863 if (spec->multiout.dig_out_nid &&
3864 spec->stream_digital_playback) {
1da177e4
LT
3865 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3866 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3867 }
4a471b7d
TI
3868 if (spec->dig_in_nid &&
3869 spec->stream_digital_capture) {
1da177e4
LT
3870 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3871 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3872 }
963f803f
TI
3873 /* FIXME: do we need this for all Realtek codec models? */
3874 codec->spdif_status_reset = 1;
1da177e4
LT
3875 }
3876
e64f14f4
TI
3877 if (spec->no_analog)
3878 return 0;
3879
e08a007d
TI
3880 /* If the use of more than one ADC is requested for the current
3881 * model, configure a second analog capture-only PCM.
3882 */
3883 /* Additional Analaog capture for index #2 */
6330079f
TI
3884 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3885 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 3886 codec->num_pcms = 3;
c06134d7 3887 info = spec->pcm_rec + 2;
e08a007d 3888 info->name = spec->stream_name_analog;
6330079f
TI
3889 if (spec->alt_dac_nid) {
3890 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3891 *spec->stream_analog_alt_playback;
3892 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3893 spec->alt_dac_nid;
3894 } else {
3895 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3896 alc_pcm_null_stream;
3897 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3898 }
3899 if (spec->num_adc_nids > 1) {
3900 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3901 *spec->stream_analog_alt_capture;
3902 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3903 spec->adc_nids[1];
3904 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3905 spec->num_adc_nids - 1;
3906 } else {
3907 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3908 alc_pcm_null_stream;
3909 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
3910 }
3911 }
3912
1da177e4
LT
3913 return 0;
3914}
3915
a4e09aa3
TI
3916static inline void alc_shutup(struct hda_codec *codec)
3917{
3918 snd_hda_shutup_pins(codec);
3919}
3920
603c4019
TI
3921static void alc_free_kctls(struct hda_codec *codec)
3922{
3923 struct alc_spec *spec = codec->spec;
3924
3925 if (spec->kctls.list) {
3926 struct snd_kcontrol_new *kctl = spec->kctls.list;
3927 int i;
3928 for (i = 0; i < spec->kctls.used; i++)
3929 kfree(kctl[i].name);
3930 }
3931 snd_array_free(&spec->kctls);
3932}
3933
1da177e4
LT
3934static void alc_free(struct hda_codec *codec)
3935{
e9edcee0 3936 struct alc_spec *spec = codec->spec;
e9edcee0 3937
f12ab1e0 3938 if (!spec)
e9edcee0
TI
3939 return;
3940
a4e09aa3 3941 alc_shutup(codec);
603c4019 3942 alc_free_kctls(codec);
e9edcee0 3943 kfree(spec);
680cd536 3944 snd_hda_detach_beep_device(codec);
1da177e4
LT
3945}
3946
f5de24b0 3947#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
3948static void alc_power_eapd(struct hda_codec *codec)
3949{
3950 /* We currently only handle front, HP */
3951 switch (codec->vendor_id) {
3952 case 0x10ec0260:
9e4c8496
TI
3953 set_eapd(codec, 0x0f, 0);
3954 set_eapd(codec, 0x10, 0);
c97259df
DC
3955 break;
3956 case 0x10ec0262:
3957 case 0x10ec0267:
3958 case 0x10ec0268:
3959 case 0x10ec0269:
9e4c8496 3960 case 0x10ec0270:
c97259df
DC
3961 case 0x10ec0272:
3962 case 0x10ec0660:
3963 case 0x10ec0662:
3964 case 0x10ec0663:
3965 case 0x10ec0862:
3966 case 0x10ec0889:
9e4c8496
TI
3967 set_eapd(codec, 0x14, 0);
3968 set_eapd(codec, 0x15, 0);
c97259df
DC
3969 break;
3970 }
3971}
3972
f5de24b0
HM
3973static int alc_suspend(struct hda_codec *codec, pm_message_t state)
3974{
3975 struct alc_spec *spec = codec->spec;
a4e09aa3 3976 alc_shutup(codec);
f5de24b0 3977 if (spec && spec->power_hook)
c97259df 3978 spec->power_hook(codec);
f5de24b0
HM
3979 return 0;
3980}
3981#endif
3982
e044c39a 3983#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
3984static int alc_resume(struct hda_codec *codec)
3985{
e044c39a
TI
3986 codec->patch_ops.init(codec);
3987 snd_hda_codec_resume_amp(codec);
3988 snd_hda_codec_resume_cache(codec);
ad35879a
TI
3989#ifdef CONFIG_SND_HDA_POWER_SAVE
3990 if (codec->patch_ops.check_power_status)
3991 codec->patch_ops.check_power_status(codec, 0x01);
3992#endif
e044c39a
TI
3993 return 0;
3994}
e044c39a
TI
3995#endif
3996
1da177e4
LT
3997/*
3998 */
3999static struct hda_codec_ops alc_patch_ops = {
4000 .build_controls = alc_build_controls,
4001 .build_pcms = alc_build_pcms,
4002 .init = alc_init,
4003 .free = alc_free,
ae6b813a 4004 .unsol_event = alc_unsol_event,
e044c39a
TI
4005#ifdef SND_HDA_NEEDS_RESUME
4006 .resume = alc_resume,
4007#endif
cb53c626 4008#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4009 .suspend = alc_suspend,
cb53c626
TI
4010 .check_power_status = alc_check_power_status,
4011#endif
c97259df 4012 .reboot_notify = alc_shutup,
1da177e4
LT
4013};
4014
c027ddcd
KY
4015/* replace the codec chip_name with the given string */
4016static int alc_codec_rename(struct hda_codec *codec, const char *name)
4017{
4018 kfree(codec->chip_name);
4019 codec->chip_name = kstrdup(name, GFP_KERNEL);
4020 if (!codec->chip_name) {
4021 alc_free(codec);
4022 return -ENOMEM;
4023 }
4024 return 0;
4025}
4026
2fa522be
TI
4027/*
4028 * Test configuration for debugging
4029 *
4030 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4031 * enum controls.
4032 */
4033#ifdef CONFIG_SND_DEBUG
4034static hda_nid_t alc880_test_dac_nids[4] = {
4035 0x02, 0x03, 0x04, 0x05
4036};
4037
4038static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4039 .num_items = 7,
2fa522be
TI
4040 .items = {
4041 { "In-1", 0x0 },
4042 { "In-2", 0x1 },
4043 { "In-3", 0x2 },
4044 { "In-4", 0x3 },
4045 { "CD", 0x4 },
ae6b813a
TI
4046 { "Front", 0x5 },
4047 { "Surround", 0x6 },
2fa522be
TI
4048 },
4049};
4050
d2a6d7dc 4051static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4052 { 2, NULL },
fd2c326d 4053 { 4, NULL },
2fa522be 4054 { 6, NULL },
fd2c326d 4055 { 8, NULL },
2fa522be
TI
4056};
4057
9c7f852e
TI
4058static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4059 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4060{
4061 static char *texts[] = {
4062 "N/A", "Line Out", "HP Out",
4063 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4064 };
4065 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4066 uinfo->count = 1;
4067 uinfo->value.enumerated.items = 8;
4068 if (uinfo->value.enumerated.item >= 8)
4069 uinfo->value.enumerated.item = 7;
4070 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4071 return 0;
4072}
4073
9c7f852e
TI
4074static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4075 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4076{
4077 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4078 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4079 unsigned int pin_ctl, item = 0;
4080
4081 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4082 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4083 if (pin_ctl & AC_PINCTL_OUT_EN) {
4084 if (pin_ctl & AC_PINCTL_HP_EN)
4085 item = 2;
4086 else
4087 item = 1;
4088 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4089 switch (pin_ctl & AC_PINCTL_VREFEN) {
4090 case AC_PINCTL_VREF_HIZ: item = 3; break;
4091 case AC_PINCTL_VREF_50: item = 4; break;
4092 case AC_PINCTL_VREF_GRD: item = 5; break;
4093 case AC_PINCTL_VREF_80: item = 6; break;
4094 case AC_PINCTL_VREF_100: item = 7; break;
4095 }
4096 }
4097 ucontrol->value.enumerated.item[0] = item;
4098 return 0;
4099}
4100
9c7f852e
TI
4101static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4102 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4103{
4104 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4105 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4106 static unsigned int ctls[] = {
4107 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4108 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4109 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4110 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4111 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4112 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4113 };
4114 unsigned int old_ctl, new_ctl;
4115
4116 old_ctl = snd_hda_codec_read(codec, nid, 0,
4117 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4118 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4119 if (old_ctl != new_ctl) {
82beb8fd
TI
4120 int val;
4121 snd_hda_codec_write_cache(codec, nid, 0,
4122 AC_VERB_SET_PIN_WIDGET_CONTROL,
4123 new_ctl);
47fd830a
TI
4124 val = ucontrol->value.enumerated.item[0] >= 3 ?
4125 HDA_AMP_MUTE : 0;
4126 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4127 HDA_AMP_MUTE, val);
2fa522be
TI
4128 return 1;
4129 }
4130 return 0;
4131}
4132
9c7f852e
TI
4133static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4134 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4135{
4136 static char *texts[] = {
4137 "Front", "Surround", "CLFE", "Side"
4138 };
4139 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4140 uinfo->count = 1;
4141 uinfo->value.enumerated.items = 4;
4142 if (uinfo->value.enumerated.item >= 4)
4143 uinfo->value.enumerated.item = 3;
4144 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4145 return 0;
4146}
4147
9c7f852e
TI
4148static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4149 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4150{
4151 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4152 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4153 unsigned int sel;
4154
4155 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4156 ucontrol->value.enumerated.item[0] = sel & 3;
4157 return 0;
4158}
4159
9c7f852e
TI
4160static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4161 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4162{
4163 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4164 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4165 unsigned int sel;
4166
4167 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4168 if (ucontrol->value.enumerated.item[0] != sel) {
4169 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4170 snd_hda_codec_write_cache(codec, nid, 0,
4171 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4172 return 1;
4173 }
4174 return 0;
4175}
4176
4177#define PIN_CTL_TEST(xname,nid) { \
4178 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4179 .name = xname, \
5b0cb1d8 4180 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4181 .info = alc_test_pin_ctl_info, \
4182 .get = alc_test_pin_ctl_get, \
4183 .put = alc_test_pin_ctl_put, \
4184 .private_value = nid \
4185 }
4186
4187#define PIN_SRC_TEST(xname,nid) { \
4188 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4189 .name = xname, \
5b0cb1d8 4190 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4191 .info = alc_test_pin_src_info, \
4192 .get = alc_test_pin_src_get, \
4193 .put = alc_test_pin_src_put, \
4194 .private_value = nid \
4195 }
4196
c8b6bf9b 4197static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4198 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4199 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4200 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4201 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4202 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4203 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4204 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4205 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4206 PIN_CTL_TEST("Front Pin Mode", 0x14),
4207 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4208 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4209 PIN_CTL_TEST("Side Pin Mode", 0x17),
4210 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4211 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4212 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4213 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4214 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4215 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4216 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4217 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4218 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4219 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4220 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4221 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4222 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4223 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4224 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4225 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4226 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4227 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4228 {
4229 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4230 .name = "Channel Mode",
df694daa
KY
4231 .info = alc_ch_mode_info,
4232 .get = alc_ch_mode_get,
4233 .put = alc_ch_mode_put,
2fa522be
TI
4234 },
4235 { } /* end */
4236};
4237
4238static struct hda_verb alc880_test_init_verbs[] = {
4239 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4240 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4241 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4242 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4243 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4244 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4245 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4246 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4247 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4248 /* Vol output for 0x0c-0x0f */
05acb863
TI
4249 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4250 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4251 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4252 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4253 /* Set output pins 0x14-0x17 */
05acb863
TI
4254 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4255 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4256 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4257 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4258 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4259 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4260 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4261 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4262 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4263 /* Set input pins 0x18-0x1c */
16ded525
TI
4264 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4265 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4266 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4267 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4268 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4269 /* Mute input pins 0x18-0x1b */
05acb863
TI
4270 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4271 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4272 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4273 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4274 /* ADC set up */
05acb863 4275 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4276 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4277 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4278 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4279 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4280 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4281 /* Analog input/passthru */
4282 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4283 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4284 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4285 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4286 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4287 { }
4288};
4289#endif
4290
1da177e4
LT
4291/*
4292 */
4293
f5fcc13c
TI
4294static const char *alc880_models[ALC880_MODEL_LAST] = {
4295 [ALC880_3ST] = "3stack",
4296 [ALC880_TCL_S700] = "tcl",
4297 [ALC880_3ST_DIG] = "3stack-digout",
4298 [ALC880_CLEVO] = "clevo",
4299 [ALC880_5ST] = "5stack",
4300 [ALC880_5ST_DIG] = "5stack-digout",
4301 [ALC880_W810] = "w810",
4302 [ALC880_Z71V] = "z71v",
4303 [ALC880_6ST] = "6stack",
4304 [ALC880_6ST_DIG] = "6stack-digout",
4305 [ALC880_ASUS] = "asus",
4306 [ALC880_ASUS_W1V] = "asus-w1v",
4307 [ALC880_ASUS_DIG] = "asus-dig",
4308 [ALC880_ASUS_DIG2] = "asus-dig2",
4309 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4310 [ALC880_UNIWILL_P53] = "uniwill-p53",
4311 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4312 [ALC880_F1734] = "F1734",
4313 [ALC880_LG] = "lg",
4314 [ALC880_LG_LW] = "lg-lw",
df99cd33 4315 [ALC880_MEDION_RIM] = "medion",
2fa522be 4316#ifdef CONFIG_SND_DEBUG
f5fcc13c 4317 [ALC880_TEST] = "test",
2fa522be 4318#endif
f5fcc13c
TI
4319 [ALC880_AUTO] = "auto",
4320};
4321
4322static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4323 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4324 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4325 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4326 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4327 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4328 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4329 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4330 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4331 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4332 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4333 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4334 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4335 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4336 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4337 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4338 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4339 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4340 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4341 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4342 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4343 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4344 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4345 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4346 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4347 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4348 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4349 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4350 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4351 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4352 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4353 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4354 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4355 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4356 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4357 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4358 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4359 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4360 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4361 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4362 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 4363 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
4364 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4365 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4366 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4367 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4368 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4369 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4370 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4371 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4372 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4373 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4374 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
4375 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4376 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4377 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4378 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4379 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4380 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4381 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4382 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4383 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4384 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4385 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4386 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4387 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4388 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4389 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4390 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4391 /* default Intel */
4392 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4393 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4394 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4395 {}
4396};
4397
16ded525 4398/*
df694daa 4399 * ALC880 codec presets
16ded525 4400 */
16ded525
TI
4401static struct alc_config_preset alc880_presets[] = {
4402 [ALC880_3ST] = {
e9edcee0 4403 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4404 .init_verbs = { alc880_volume_init_verbs,
4405 alc880_pin_3stack_init_verbs },
16ded525 4406 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4407 .dac_nids = alc880_dac_nids,
16ded525
TI
4408 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4409 .channel_mode = alc880_threestack_modes,
4e195a7b 4410 .need_dac_fix = 1,
16ded525
TI
4411 .input_mux = &alc880_capture_source,
4412 },
4413 [ALC880_3ST_DIG] = {
e9edcee0 4414 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4415 .init_verbs = { alc880_volume_init_verbs,
4416 alc880_pin_3stack_init_verbs },
16ded525 4417 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4418 .dac_nids = alc880_dac_nids,
4419 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4420 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4421 .channel_mode = alc880_threestack_modes,
4e195a7b 4422 .need_dac_fix = 1,
16ded525
TI
4423 .input_mux = &alc880_capture_source,
4424 },
df694daa
KY
4425 [ALC880_TCL_S700] = {
4426 .mixers = { alc880_tcl_s700_mixer },
4427 .init_verbs = { alc880_volume_init_verbs,
4428 alc880_pin_tcl_S700_init_verbs,
4429 alc880_gpio2_init_verbs },
4430 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4431 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4432 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4433 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4434 .hp_nid = 0x03,
4435 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4436 .channel_mode = alc880_2_jack_modes,
4437 .input_mux = &alc880_capture_source,
4438 },
16ded525 4439 [ALC880_5ST] = {
f12ab1e0
TI
4440 .mixers = { alc880_three_stack_mixer,
4441 alc880_five_stack_mixer},
4442 .init_verbs = { alc880_volume_init_verbs,
4443 alc880_pin_5stack_init_verbs },
16ded525
TI
4444 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4445 .dac_nids = alc880_dac_nids,
16ded525
TI
4446 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4447 .channel_mode = alc880_fivestack_modes,
4448 .input_mux = &alc880_capture_source,
4449 },
4450 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4451 .mixers = { alc880_three_stack_mixer,
4452 alc880_five_stack_mixer },
4453 .init_verbs = { alc880_volume_init_verbs,
4454 alc880_pin_5stack_init_verbs },
16ded525
TI
4455 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4456 .dac_nids = alc880_dac_nids,
4457 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4458 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4459 .channel_mode = alc880_fivestack_modes,
4460 .input_mux = &alc880_capture_source,
4461 },
b6482d48
TI
4462 [ALC880_6ST] = {
4463 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4464 .init_verbs = { alc880_volume_init_verbs,
4465 alc880_pin_6stack_init_verbs },
b6482d48
TI
4466 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4467 .dac_nids = alc880_6st_dac_nids,
4468 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4469 .channel_mode = alc880_sixstack_modes,
4470 .input_mux = &alc880_6stack_capture_source,
4471 },
16ded525 4472 [ALC880_6ST_DIG] = {
e9edcee0 4473 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4474 .init_verbs = { alc880_volume_init_verbs,
4475 alc880_pin_6stack_init_verbs },
16ded525
TI
4476 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4477 .dac_nids = alc880_6st_dac_nids,
4478 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4479 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4480 .channel_mode = alc880_sixstack_modes,
4481 .input_mux = &alc880_6stack_capture_source,
4482 },
4483 [ALC880_W810] = {
e9edcee0 4484 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4485 .init_verbs = { alc880_volume_init_verbs,
4486 alc880_pin_w810_init_verbs,
b0af0de5 4487 alc880_gpio2_init_verbs },
16ded525
TI
4488 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4489 .dac_nids = alc880_w810_dac_nids,
4490 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4491 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4492 .channel_mode = alc880_w810_modes,
4493 .input_mux = &alc880_capture_source,
4494 },
4495 [ALC880_Z71V] = {
e9edcee0 4496 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
4497 .init_verbs = { alc880_volume_init_verbs,
4498 alc880_pin_z71v_init_verbs },
16ded525
TI
4499 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4500 .dac_nids = alc880_z71v_dac_nids,
4501 .dig_out_nid = ALC880_DIGOUT_NID,
4502 .hp_nid = 0x03,
e9edcee0
TI
4503 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4504 .channel_mode = alc880_2_jack_modes,
16ded525
TI
4505 .input_mux = &alc880_capture_source,
4506 },
4507 [ALC880_F1734] = {
e9edcee0 4508 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
4509 .init_verbs = { alc880_volume_init_verbs,
4510 alc880_pin_f1734_init_verbs },
e9edcee0
TI
4511 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4512 .dac_nids = alc880_f1734_dac_nids,
4513 .hp_nid = 0x02,
4514 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4515 .channel_mode = alc880_2_jack_modes,
937b4160
TI
4516 .input_mux = &alc880_f1734_capture_source,
4517 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4518 .setup = alc880_uniwill_p53_setup,
4519 .init_hook = alc_automute_amp,
16ded525
TI
4520 },
4521 [ALC880_ASUS] = {
e9edcee0 4522 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4523 .init_verbs = { alc880_volume_init_verbs,
4524 alc880_pin_asus_init_verbs,
e9edcee0
TI
4525 alc880_gpio1_init_verbs },
4526 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4527 .dac_nids = alc880_asus_dac_nids,
4528 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4529 .channel_mode = alc880_asus_modes,
4e195a7b 4530 .need_dac_fix = 1,
16ded525
TI
4531 .input_mux = &alc880_capture_source,
4532 },
4533 [ALC880_ASUS_DIG] = {
e9edcee0 4534 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4535 .init_verbs = { alc880_volume_init_verbs,
4536 alc880_pin_asus_init_verbs,
e9edcee0
TI
4537 alc880_gpio1_init_verbs },
4538 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4539 .dac_nids = alc880_asus_dac_nids,
16ded525 4540 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4541 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4542 .channel_mode = alc880_asus_modes,
4e195a7b 4543 .need_dac_fix = 1,
16ded525
TI
4544 .input_mux = &alc880_capture_source,
4545 },
df694daa
KY
4546 [ALC880_ASUS_DIG2] = {
4547 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4548 .init_verbs = { alc880_volume_init_verbs,
4549 alc880_pin_asus_init_verbs,
df694daa
KY
4550 alc880_gpio2_init_verbs }, /* use GPIO2 */
4551 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4552 .dac_nids = alc880_asus_dac_nids,
4553 .dig_out_nid = ALC880_DIGOUT_NID,
4554 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4555 .channel_mode = alc880_asus_modes,
4e195a7b 4556 .need_dac_fix = 1,
df694daa
KY
4557 .input_mux = &alc880_capture_source,
4558 },
16ded525 4559 [ALC880_ASUS_W1V] = {
e9edcee0 4560 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
4561 .init_verbs = { alc880_volume_init_verbs,
4562 alc880_pin_asus_init_verbs,
e9edcee0
TI
4563 alc880_gpio1_init_verbs },
4564 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4565 .dac_nids = alc880_asus_dac_nids,
16ded525 4566 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4567 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4568 .channel_mode = alc880_asus_modes,
4e195a7b 4569 .need_dac_fix = 1,
16ded525
TI
4570 .input_mux = &alc880_capture_source,
4571 },
4572 [ALC880_UNIWILL_DIG] = {
45bdd1c1 4573 .mixers = { alc880_asus_mixer },
ccc656ce
KY
4574 .init_verbs = { alc880_volume_init_verbs,
4575 alc880_pin_asus_init_verbs },
e9edcee0
TI
4576 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4577 .dac_nids = alc880_asus_dac_nids,
16ded525 4578 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4579 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4580 .channel_mode = alc880_asus_modes,
4e195a7b 4581 .need_dac_fix = 1,
16ded525
TI
4582 .input_mux = &alc880_capture_source,
4583 },
ccc656ce
KY
4584 [ALC880_UNIWILL] = {
4585 .mixers = { alc880_uniwill_mixer },
4586 .init_verbs = { alc880_volume_init_verbs,
4587 alc880_uniwill_init_verbs },
4588 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4589 .dac_nids = alc880_asus_dac_nids,
4590 .dig_out_nid = ALC880_DIGOUT_NID,
4591 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4592 .channel_mode = alc880_threestack_modes,
4593 .need_dac_fix = 1,
4594 .input_mux = &alc880_capture_source,
4595 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 4596 .setup = alc880_uniwill_setup,
a9fd4f3f 4597 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
4598 },
4599 [ALC880_UNIWILL_P53] = {
4600 .mixers = { alc880_uniwill_p53_mixer },
4601 .init_verbs = { alc880_volume_init_verbs,
4602 alc880_uniwill_p53_init_verbs },
4603 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4604 .dac_nids = alc880_asus_dac_nids,
4605 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4606 .channel_mode = alc880_threestack_modes,
4607 .input_mux = &alc880_capture_source,
4608 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4609 .setup = alc880_uniwill_p53_setup,
4610 .init_hook = alc_automute_amp,
2cf9f0fc
TD
4611 },
4612 [ALC880_FUJITSU] = {
45bdd1c1 4613 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4614 .init_verbs = { alc880_volume_init_verbs,
4615 alc880_uniwill_p53_init_verbs,
4616 alc880_beep_init_verbs },
4617 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4618 .dac_nids = alc880_dac_nids,
d53d7d9e 4619 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4620 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4621 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4622 .input_mux = &alc880_capture_source,
4623 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4624 .setup = alc880_uniwill_p53_setup,
4625 .init_hook = alc_automute_amp,
ccc656ce 4626 },
df694daa
KY
4627 [ALC880_CLEVO] = {
4628 .mixers = { alc880_three_stack_mixer },
4629 .init_verbs = { alc880_volume_init_verbs,
4630 alc880_pin_clevo_init_verbs },
4631 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4632 .dac_nids = alc880_dac_nids,
4633 .hp_nid = 0x03,
4634 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4635 .channel_mode = alc880_threestack_modes,
4e195a7b 4636 .need_dac_fix = 1,
df694daa
KY
4637 .input_mux = &alc880_capture_source,
4638 },
ae6b813a
TI
4639 [ALC880_LG] = {
4640 .mixers = { alc880_lg_mixer },
4641 .init_verbs = { alc880_volume_init_verbs,
4642 alc880_lg_init_verbs },
4643 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4644 .dac_nids = alc880_lg_dac_nids,
4645 .dig_out_nid = ALC880_DIGOUT_NID,
4646 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4647 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4648 .need_dac_fix = 1,
ae6b813a 4649 .input_mux = &alc880_lg_capture_source,
a9fd4f3f 4650 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4651 .setup = alc880_lg_setup,
4652 .init_hook = alc_automute_amp,
cb53c626
TI
4653#ifdef CONFIG_SND_HDA_POWER_SAVE
4654 .loopbacks = alc880_lg_loopbacks,
4655#endif
ae6b813a 4656 },
d681518a
TI
4657 [ALC880_LG_LW] = {
4658 .mixers = { alc880_lg_lw_mixer },
4659 .init_verbs = { alc880_volume_init_verbs,
4660 alc880_lg_lw_init_verbs },
0a8c5da3 4661 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
4662 .dac_nids = alc880_dac_nids,
4663 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
4664 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4665 .channel_mode = alc880_lg_lw_modes,
d681518a 4666 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f 4667 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4668 .setup = alc880_lg_lw_setup,
4669 .init_hook = alc_automute_amp,
d681518a 4670 },
df99cd33
TI
4671 [ALC880_MEDION_RIM] = {
4672 .mixers = { alc880_medion_rim_mixer },
4673 .init_verbs = { alc880_volume_init_verbs,
4674 alc880_medion_rim_init_verbs,
4675 alc_gpio2_init_verbs },
4676 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4677 .dac_nids = alc880_dac_nids,
4678 .dig_out_nid = ALC880_DIGOUT_NID,
4679 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4680 .channel_mode = alc880_2_jack_modes,
4681 .input_mux = &alc880_medion_rim_capture_source,
4682 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
4683 .setup = alc880_medion_rim_setup,
4684 .init_hook = alc880_medion_rim_automute,
df99cd33 4685 },
16ded525
TI
4686#ifdef CONFIG_SND_DEBUG
4687 [ALC880_TEST] = {
e9edcee0
TI
4688 .mixers = { alc880_test_mixer },
4689 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
4690 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4691 .dac_nids = alc880_test_dac_nids,
4692 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4693 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4694 .channel_mode = alc880_test_modes,
4695 .input_mux = &alc880_test_capture_source,
4696 },
4697#endif
4698};
4699
e9edcee0
TI
4700/*
4701 * Automatic parse of I/O pins from the BIOS configuration
4702 */
4703
e9edcee0
TI
4704enum {
4705 ALC_CTL_WIDGET_VOL,
4706 ALC_CTL_WIDGET_MUTE,
4707 ALC_CTL_BIND_MUTE,
4708};
c8b6bf9b 4709static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
4710 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4711 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 4712 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
4713};
4714
4715/* add dynamic controls */
f12ab1e0
TI
4716static int add_control(struct alc_spec *spec, int type, const char *name,
4717 unsigned long val)
e9edcee0 4718{
c8b6bf9b 4719 struct snd_kcontrol_new *knew;
e9edcee0 4720
603c4019
TI
4721 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4722 knew = snd_array_new(&spec->kctls);
4723 if (!knew)
4724 return -ENOMEM;
e9edcee0 4725 *knew = alc880_control_templates[type];
543537bd 4726 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 4727 if (!knew->name)
e9edcee0 4728 return -ENOMEM;
4d02d1b6 4729 if (get_amp_nid_(val))
5e26dfd0 4730 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 4731 knew->private_value = val;
e9edcee0
TI
4732 return 0;
4733}
4734
0afe5f89
TI
4735static int add_control_with_pfx(struct alc_spec *spec, int type,
4736 const char *pfx, const char *dir,
4737 const char *sfx, unsigned long val)
4738{
4739 char name[32];
4740 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
4741 return add_control(spec, type, name, val);
4742}
4743
4744#define add_pb_vol_ctrl(spec, type, pfx, val) \
4745 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val)
4746#define add_pb_sw_ctrl(spec, type, pfx, val) \
4747 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val)
4748
e9edcee0
TI
4749#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4750#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4751#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4752#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
4753#define alc880_idx_to_dac(nid) ((nid) + 0x02)
4754#define alc880_dac_to_idx(nid) ((nid) - 0x02)
4755#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4756#define alc880_idx_to_selector(nid) ((nid) + 0x10)
4757#define ALC880_PIN_CD_NID 0x1c
4758
4759/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
4760static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4761 const struct auto_pin_cfg *cfg)
e9edcee0
TI
4762{
4763 hda_nid_t nid;
4764 int assigned[4];
4765 int i, j;
4766
4767 memset(assigned, 0, sizeof(assigned));
b0af0de5 4768 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
4769
4770 /* check the pins hardwired to audio widget */
4771 for (i = 0; i < cfg->line_outs; i++) {
4772 nid = cfg->line_out_pins[i];
4773 if (alc880_is_fixed_pin(nid)) {
4774 int idx = alc880_fixed_pin_idx(nid);
5014f193 4775 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
4776 assigned[idx] = 1;
4777 }
4778 }
4779 /* left pins can be connect to any audio widget */
4780 for (i = 0; i < cfg->line_outs; i++) {
4781 nid = cfg->line_out_pins[i];
4782 if (alc880_is_fixed_pin(nid))
4783 continue;
4784 /* search for an empty channel */
4785 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
4786 if (!assigned[j]) {
4787 spec->multiout.dac_nids[i] =
4788 alc880_idx_to_dac(j);
e9edcee0
TI
4789 assigned[j] = 1;
4790 break;
4791 }
4792 }
4793 }
4794 spec->multiout.num_dacs = cfg->line_outs;
4795 return 0;
4796}
4797
4798/* add playback controls from the parsed DAC table */
df694daa
KY
4799static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4800 const struct auto_pin_cfg *cfg)
e9edcee0 4801{
f12ab1e0
TI
4802 static const char *chname[4] = {
4803 "Front", "Surround", NULL /*CLFE*/, "Side"
4804 };
e9edcee0
TI
4805 hda_nid_t nid;
4806 int i, err;
4807
4808 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 4809 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
4810 continue;
4811 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4812 if (i == 2) {
4813 /* Center/LFE */
0afe5f89
TI
4814 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4815 "Center",
f12ab1e0
TI
4816 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4817 HDA_OUTPUT));
4818 if (err < 0)
e9edcee0 4819 return err;
0afe5f89
TI
4820 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4821 "LFE",
f12ab1e0
TI
4822 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4823 HDA_OUTPUT));
4824 if (err < 0)
e9edcee0 4825 return err;
0afe5f89
TI
4826 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4827 "Center",
f12ab1e0
TI
4828 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4829 HDA_INPUT));
4830 if (err < 0)
e9edcee0 4831 return err;
0afe5f89
TI
4832 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4833 "LFE",
f12ab1e0
TI
4834 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4835 HDA_INPUT));
4836 if (err < 0)
e9edcee0
TI
4837 return err;
4838 } else {
cb162b6b
TI
4839 const char *pfx;
4840 if (cfg->line_outs == 1 &&
4841 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4842 pfx = "Speaker";
4843 else
4844 pfx = chname[i];
0afe5f89 4845 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
4846 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4847 HDA_OUTPUT));
4848 if (err < 0)
e9edcee0 4849 return err;
0afe5f89 4850 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
4851 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4852 HDA_INPUT));
4853 if (err < 0)
e9edcee0
TI
4854 return err;
4855 }
4856 }
e9edcee0
TI
4857 return 0;
4858}
4859
8d88bc3d
TI
4860/* add playback controls for speaker and HP outputs */
4861static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4862 const char *pfx)
e9edcee0
TI
4863{
4864 hda_nid_t nid;
4865 int err;
4866
f12ab1e0 4867 if (!pin)
e9edcee0
TI
4868 return 0;
4869
4870 if (alc880_is_fixed_pin(pin)) {
4871 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 4872 /* specify the DAC as the extra output */
f12ab1e0 4873 if (!spec->multiout.hp_nid)
e9edcee0 4874 spec->multiout.hp_nid = nid;
82bc955f
TI
4875 else
4876 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
4877 /* control HP volume/switch on the output mixer amp */
4878 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 4879 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
4880 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4881 if (err < 0)
e9edcee0 4882 return err;
0afe5f89 4883 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
4884 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4885 if (err < 0)
e9edcee0
TI
4886 return err;
4887 } else if (alc880_is_multi_pin(pin)) {
4888 /* set manual connection */
e9edcee0 4889 /* we have only a switch on HP-out PIN */
0afe5f89 4890 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
4891 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4892 if (err < 0)
e9edcee0
TI
4893 return err;
4894 }
4895 return 0;
4896}
4897
4898/* create input playback/capture controls for the given pin */
f12ab1e0
TI
4899static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4900 const char *ctlname,
df694daa 4901 int idx, hda_nid_t mix_nid)
e9edcee0 4902{
df694daa 4903 int err;
e9edcee0 4904
0afe5f89 4905 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
f12ab1e0
TI
4906 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4907 if (err < 0)
e9edcee0 4908 return err;
0afe5f89 4909 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
f12ab1e0
TI
4910 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4911 if (err < 0)
e9edcee0
TI
4912 return err;
4913 return 0;
4914}
4915
05f5f477
TI
4916static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
4917{
4918 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
4919 return (pincap & AC_PINCAP_IN) != 0;
4920}
4921
e9edcee0 4922/* create playback/capture controls for input pins */
05f5f477
TI
4923static int alc_auto_create_input_ctls(struct hda_codec *codec,
4924 const struct auto_pin_cfg *cfg,
4925 hda_nid_t mixer,
4926 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 4927{
05f5f477 4928 struct alc_spec *spec = codec->spec;
61b9b9b1 4929 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa 4930 int i, err, idx;
e9edcee0
TI
4931
4932 for (i = 0; i < AUTO_PIN_LAST; i++) {
05f5f477
TI
4933 hda_nid_t pin;
4934
4935 pin = cfg->input_pins[i];
4936 if (!alc_is_input_pin(codec, pin))
4937 continue;
4938
4939 if (mixer) {
4940 idx = get_connection_index(codec, mixer, pin);
4941 if (idx >= 0) {
4942 err = new_analog_input(spec, pin,
4943 auto_pin_cfg_labels[i],
4944 idx, mixer);
4945 if (err < 0)
4946 return err;
4947 }
4948 }
4949
4950 if (!cap1)
4951 continue;
4952 idx = get_connection_index(codec, cap1, pin);
4953 if (idx < 0 && cap2)
4954 idx = get_connection_index(codec, cap2, pin);
4955 if (idx >= 0) {
f12ab1e0
TI
4956 imux->items[imux->num_items].label =
4957 auto_pin_cfg_labels[i];
05f5f477 4958 imux->items[imux->num_items].index = idx;
e9edcee0
TI
4959 imux->num_items++;
4960 }
4961 }
4962 return 0;
4963}
4964
05f5f477
TI
4965static int alc880_auto_create_input_ctls(struct hda_codec *codec,
4966 const struct auto_pin_cfg *cfg)
4967{
4968 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
4969}
4970
f6c7e546
TI
4971static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4972 unsigned int pin_type)
4973{
4974 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4975 pin_type);
4976 /* unmute pin */
d260cdf6
TI
4977 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4978 AMP_OUT_UNMUTE);
f6c7e546
TI
4979}
4980
df694daa
KY
4981static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4982 hda_nid_t nid, int pin_type,
e9edcee0
TI
4983 int dac_idx)
4984{
f6c7e546 4985 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
4986 /* need the manual connection? */
4987 if (alc880_is_multi_pin(nid)) {
4988 struct alc_spec *spec = codec->spec;
4989 int idx = alc880_multi_pin_idx(nid);
4990 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4991 AC_VERB_SET_CONNECT_SEL,
4992 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4993 }
4994}
4995
baba8ee9
TI
4996static int get_pin_type(int line_out_type)
4997{
4998 if (line_out_type == AUTO_PIN_HP_OUT)
4999 return PIN_HP;
5000 else
5001 return PIN_OUT;
5002}
5003
e9edcee0
TI
5004static void alc880_auto_init_multi_out(struct hda_codec *codec)
5005{
5006 struct alc_spec *spec = codec->spec;
5007 int i;
ea1fb29a 5008
e9edcee0
TI
5009 for (i = 0; i < spec->autocfg.line_outs; i++) {
5010 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5011 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5012 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5013 }
5014}
5015
8d88bc3d 5016static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5017{
5018 struct alc_spec *spec = codec->spec;
5019 hda_nid_t pin;
5020
82bc955f 5021 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5022 if (pin) /* connect to front */
5023 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5024 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5025 if (pin) /* connect to front */
5026 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5027}
5028
5029static void alc880_auto_init_analog_input(struct hda_codec *codec)
5030{
5031 struct alc_spec *spec = codec->spec;
5032 int i;
5033
5034 for (i = 0; i < AUTO_PIN_LAST; i++) {
5035 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 5036 if (alc_is_input_pin(codec, nid)) {
23f0c048 5037 alc_set_input_pin(codec, nid, i);
e82c025b
TI
5038 if (nid != ALC880_PIN_CD_NID &&
5039 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5040 snd_hda_codec_write(codec, nid, 0,
5041 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5042 AMP_OUT_MUTE);
5043 }
5044 }
5045}
5046
7f311a46
TI
5047static void alc880_auto_init_input_src(struct hda_codec *codec)
5048{
5049 struct alc_spec *spec = codec->spec;
5050 int c;
5051
5052 for (c = 0; c < spec->num_adc_nids; c++) {
5053 unsigned int mux_idx;
5054 const struct hda_input_mux *imux;
5055 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5056 imux = &spec->input_mux[mux_idx];
5057 if (!imux->num_items && mux_idx > 0)
5058 imux = &spec->input_mux[0];
5059 if (imux)
5060 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5061 AC_VERB_SET_CONNECT_SEL,
5062 imux->items[0].index);
5063 }
5064}
5065
e9edcee0 5066/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5067/* return 1 if successful, 0 if the proper config is not found,
5068 * or a negative error code
5069 */
e9edcee0
TI
5070static int alc880_parse_auto_config(struct hda_codec *codec)
5071{
5072 struct alc_spec *spec = codec->spec;
757899ac 5073 int err;
df694daa 5074 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5075
f12ab1e0
TI
5076 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5077 alc880_ignore);
5078 if (err < 0)
e9edcee0 5079 return err;
f12ab1e0 5080 if (!spec->autocfg.line_outs)
e9edcee0 5081 return 0; /* can't find valid BIOS pin config */
df694daa 5082
f12ab1e0
TI
5083 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5084 if (err < 0)
5085 return err;
5086 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5087 if (err < 0)
5088 return err;
5089 err = alc880_auto_create_extra_out(spec,
5090 spec->autocfg.speaker_pins[0],
5091 "Speaker");
5092 if (err < 0)
5093 return err;
5094 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5095 "Headphone");
5096 if (err < 0)
5097 return err;
05f5f477 5098 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5099 if (err < 0)
e9edcee0
TI
5100 return err;
5101
5102 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5103
757899ac 5104 alc_auto_parse_digital(codec);
e9edcee0 5105
603c4019 5106 if (spec->kctls.list)
d88897ea 5107 add_mixer(spec, spec->kctls.list);
e9edcee0 5108
d88897ea 5109 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5110
a1e8d2da 5111 spec->num_mux_defs = 1;
61b9b9b1 5112 spec->input_mux = &spec->private_imux[0];
e9edcee0 5113
6227cdce 5114 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5115
e9edcee0
TI
5116 return 1;
5117}
5118
ae6b813a
TI
5119/* additional initialization for auto-configuration model */
5120static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5121{
f6c7e546 5122 struct alc_spec *spec = codec->spec;
e9edcee0 5123 alc880_auto_init_multi_out(codec);
8d88bc3d 5124 alc880_auto_init_extra_out(codec);
e9edcee0 5125 alc880_auto_init_analog_input(codec);
7f311a46 5126 alc880_auto_init_input_src(codec);
757899ac 5127 alc_auto_init_digital(codec);
f6c7e546 5128 if (spec->unsol_event)
7fb0d78f 5129 alc_inithook(codec);
e9edcee0
TI
5130}
5131
b59bdf3b
TI
5132/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5133 * one of two digital mic pins, e.g. on ALC272
5134 */
5135static void fixup_automic_adc(struct hda_codec *codec)
5136{
5137 struct alc_spec *spec = codec->spec;
5138 int i;
5139
5140 for (i = 0; i < spec->num_adc_nids; i++) {
5141 hda_nid_t cap = spec->capsrc_nids ?
5142 spec->capsrc_nids[i] : spec->adc_nids[i];
5143 int iidx, eidx;
5144
5145 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5146 if (iidx < 0)
5147 continue;
5148 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5149 if (eidx < 0)
5150 continue;
5151 spec->int_mic.mux_idx = iidx;
5152 spec->ext_mic.mux_idx = eidx;
5153 if (spec->capsrc_nids)
5154 spec->capsrc_nids += i;
5155 spec->adc_nids += i;
5156 spec->num_adc_nids = 1;
5157 return;
5158 }
5159 snd_printd(KERN_INFO "hda_codec: %s: "
5160 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5161 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5162 spec->auto_mic = 0; /* disable auto-mic to be sure */
5163}
5164
840b64c0
TI
5165/* set the default connection to that pin */
5166static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5167{
5168 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5169 int i;
5170
eaa9b3a7
TI
5171 for (i = 0; i < spec->num_adc_nids; i++) {
5172 hda_nid_t cap = spec->capsrc_nids ?
5173 spec->capsrc_nids[i] : spec->adc_nids[i];
5174 int idx;
5175
5176 idx = get_connection_index(codec, cap, pin);
5177 if (idx < 0)
5178 continue;
eaa9b3a7
TI
5179 /* select or unmute this route */
5180 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5181 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5182 HDA_AMP_MUTE, 0);
5183 } else {
5184 snd_hda_codec_write_cache(codec, cap, 0,
5185 AC_VERB_SET_CONNECT_SEL, idx);
5186 }
840b64c0
TI
5187 return i; /* return the found index */
5188 }
5189 return -1; /* not found */
5190}
5191
5192/* choose the ADC/MUX containing the input pin and initialize the setup */
5193static void fixup_single_adc(struct hda_codec *codec)
5194{
5195 struct alc_spec *spec = codec->spec;
5196 hda_nid_t pin = 0;
5197 int i;
5198
5199 /* search for the input pin; there must be only one */
5200 for (i = 0; i < AUTO_PIN_LAST; i++) {
5201 if (spec->autocfg.input_pins[i]) {
5202 pin = spec->autocfg.input_pins[i];
5203 break;
5204 }
5205 }
5206 if (!pin)
eaa9b3a7 5207 return;
840b64c0
TI
5208 i = init_capsrc_for_pin(codec, pin);
5209 if (i >= 0) {
5210 /* use only this ADC */
5211 if (spec->capsrc_nids)
5212 spec->capsrc_nids += i;
5213 spec->adc_nids += i;
5214 spec->num_adc_nids = 1;
eaa9b3a7
TI
5215 }
5216}
5217
840b64c0
TI
5218/* initialize dual adcs */
5219static void fixup_dual_adc_switch(struct hda_codec *codec)
5220{
5221 struct alc_spec *spec = codec->spec;
5222 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5223 init_capsrc_for_pin(codec, spec->int_mic.pin);
5224}
5225
b59bdf3b 5226static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5227{
b59bdf3b 5228 struct alc_spec *spec = codec->spec;
a23b688f
TI
5229 static struct snd_kcontrol_new *caps[2][3] = {
5230 { alc_capture_mixer_nosrc1,
5231 alc_capture_mixer_nosrc2,
5232 alc_capture_mixer_nosrc3 },
5233 { alc_capture_mixer1,
5234 alc_capture_mixer2,
5235 alc_capture_mixer3 },
f9e336f6 5236 };
a23b688f 5237 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5238 int mux = 0;
840b64c0
TI
5239 int num_adcs = spec->num_adc_nids;
5240 if (spec->dual_adc_switch)
5241 fixup_dual_adc_switch(codec);
5242 else if (spec->auto_mic)
b59bdf3b 5243 fixup_automic_adc(codec);
eaa9b3a7
TI
5244 else if (spec->input_mux) {
5245 if (spec->input_mux->num_items > 1)
5246 mux = 1;
5247 else if (spec->input_mux->num_items == 1)
5248 fixup_single_adc(codec);
5249 }
840b64c0
TI
5250 if (spec->dual_adc_switch)
5251 num_adcs = 1;
5252 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5253 }
f9e336f6
TI
5254}
5255
6694635d
TI
5256/* fill adc_nids (and capsrc_nids) containing all active input pins */
5257static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5258 int num_nids)
5259{
5260 struct alc_spec *spec = codec->spec;
5261 int n;
5262 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5263
5264 for (n = 0; n < num_nids; n++) {
5265 hda_nid_t adc, cap;
5266 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5267 int nconns, i, j;
5268
5269 adc = nids[n];
5270 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5271 continue;
5272 cap = adc;
5273 nconns = snd_hda_get_connections(codec, cap, conn,
5274 ARRAY_SIZE(conn));
5275 if (nconns == 1) {
5276 cap = conn[0];
5277 nconns = snd_hda_get_connections(codec, cap, conn,
5278 ARRAY_SIZE(conn));
5279 }
5280 if (nconns <= 0)
5281 continue;
5282 if (!fallback_adc) {
5283 fallback_adc = adc;
5284 fallback_cap = cap;
5285 }
5286 for (i = 0; i < AUTO_PIN_LAST; i++) {
5287 hda_nid_t nid = spec->autocfg.input_pins[i];
5288 if (!nid)
5289 continue;
5290 for (j = 0; j < nconns; j++) {
5291 if (conn[j] == nid)
5292 break;
5293 }
5294 if (j >= nconns)
5295 break;
5296 }
5297 if (i >= AUTO_PIN_LAST) {
5298 int num_adcs = spec->num_adc_nids;
5299 spec->private_adc_nids[num_adcs] = adc;
5300 spec->private_capsrc_nids[num_adcs] = cap;
5301 spec->num_adc_nids++;
5302 spec->adc_nids = spec->private_adc_nids;
5303 if (adc != cap)
5304 spec->capsrc_nids = spec->private_capsrc_nids;
5305 }
5306 }
5307 if (!spec->num_adc_nids) {
5308 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5309 " using fallback 0x%x\n",
5310 codec->chip_name, fallback_adc);
6694635d
TI
5311 spec->private_adc_nids[0] = fallback_adc;
5312 spec->adc_nids = spec->private_adc_nids;
5313 if (fallback_adc != fallback_cap) {
5314 spec->private_capsrc_nids[0] = fallback_cap;
5315 spec->capsrc_nids = spec->private_adc_nids;
5316 }
5317 }
5318}
5319
67d634c0 5320#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5321#define set_beep_amp(spec, nid, idx, dir) \
5322 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25
TI
5323
5324static struct snd_pci_quirk beep_white_list[] = {
5325 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5326 {}
5327};
5328
5329static inline int has_cdefine_beep(struct hda_codec *codec)
5330{
5331 struct alc_spec *spec = codec->spec;
5332 const struct snd_pci_quirk *q;
5333 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5334 if (q)
5335 return q->value;
5336 return spec->cdefine.enable_pcbeep;
5337}
67d634c0
TI
5338#else
5339#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5340#define has_cdefine_beep(codec) 0
67d634c0 5341#endif
45bdd1c1
TI
5342
5343/*
5344 * OK, here we have finally the patch for ALC880
5345 */
5346
1da177e4
LT
5347static int patch_alc880(struct hda_codec *codec)
5348{
5349 struct alc_spec *spec;
5350 int board_config;
df694daa 5351 int err;
1da177e4 5352
e560d8d8 5353 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5354 if (spec == NULL)
5355 return -ENOMEM;
5356
5357 codec->spec = spec;
5358
f5fcc13c
TI
5359 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5360 alc880_models,
5361 alc880_cfg_tbl);
5362 if (board_config < 0) {
9a11f1aa
TI
5363 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5364 codec->chip_name);
e9edcee0 5365 board_config = ALC880_AUTO;
1da177e4 5366 }
1da177e4 5367
e9edcee0
TI
5368 if (board_config == ALC880_AUTO) {
5369 /* automatic parse from the BIOS config */
5370 err = alc880_parse_auto_config(codec);
5371 if (err < 0) {
5372 alc_free(codec);
5373 return err;
f12ab1e0 5374 } else if (!err) {
9c7f852e
TI
5375 printk(KERN_INFO
5376 "hda_codec: Cannot set up configuration "
5377 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5378 board_config = ALC880_3ST;
5379 }
1da177e4
LT
5380 }
5381
680cd536
KK
5382 err = snd_hda_attach_beep_device(codec, 0x1);
5383 if (err < 0) {
5384 alc_free(codec);
5385 return err;
5386 }
5387
df694daa 5388 if (board_config != ALC880_AUTO)
e9c364c0 5389 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5390
1da177e4
LT
5391 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5392 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5393 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5394
1da177e4
LT
5395 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5396 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5397
f12ab1e0 5398 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5399 /* check whether NID 0x07 is valid */
54d17403 5400 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5401 /* get type */
a22d543a 5402 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5403 if (wcap != AC_WID_AUD_IN) {
5404 spec->adc_nids = alc880_adc_nids_alt;
5405 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5406 } else {
5407 spec->adc_nids = alc880_adc_nids;
5408 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5409 }
5410 }
b59bdf3b 5411 set_capture_mixer(codec);
45bdd1c1 5412 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5413
2134ea4f
TI
5414 spec->vmaster_nid = 0x0c;
5415
1da177e4 5416 codec->patch_ops = alc_patch_ops;
e9edcee0 5417 if (board_config == ALC880_AUTO)
ae6b813a 5418 spec->init_hook = alc880_auto_init;
cb53c626
TI
5419#ifdef CONFIG_SND_HDA_POWER_SAVE
5420 if (!spec->loopback.amplist)
5421 spec->loopback.amplist = alc880_loopbacks;
5422#endif
1da177e4
LT
5423
5424 return 0;
5425}
5426
e9edcee0 5427
1da177e4
LT
5428/*
5429 * ALC260 support
5430 */
5431
e9edcee0
TI
5432static hda_nid_t alc260_dac_nids[1] = {
5433 /* front */
5434 0x02,
5435};
5436
5437static hda_nid_t alc260_adc_nids[1] = {
5438 /* ADC0 */
5439 0x04,
5440};
5441
df694daa 5442static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5443 /* ADC1 */
5444 0x05,
5445};
5446
d57fdac0
JW
5447/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5448 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5449 */
5450static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5451 /* ADC0, ADC1 */
5452 0x04, 0x05
5453};
5454
e9edcee0
TI
5455#define ALC260_DIGOUT_NID 0x03
5456#define ALC260_DIGIN_NID 0x06
5457
5458static struct hda_input_mux alc260_capture_source = {
5459 .num_items = 4,
5460 .items = {
5461 { "Mic", 0x0 },
5462 { "Front Mic", 0x1 },
5463 { "Line", 0x2 },
5464 { "CD", 0x4 },
5465 },
5466};
5467
17e7aec6 5468/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5469 * headphone jack and the internal CD lines since these are the only pins at
5470 * which audio can appear. For flexibility, also allow the option of
5471 * recording the mixer output on the second ADC (ADC0 doesn't have a
5472 * connection to the mixer output).
a9430dd8 5473 */
a1e8d2da
JW
5474static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5475 {
5476 .num_items = 3,
5477 .items = {
5478 { "Mic/Line", 0x0 },
5479 { "CD", 0x4 },
5480 { "Headphone", 0x2 },
5481 },
a9430dd8 5482 },
a1e8d2da
JW
5483 {
5484 .num_items = 4,
5485 .items = {
5486 { "Mic/Line", 0x0 },
5487 { "CD", 0x4 },
5488 { "Headphone", 0x2 },
5489 { "Mixer", 0x5 },
5490 },
5491 },
5492
a9430dd8
JW
5493};
5494
a1e8d2da
JW
5495/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5496 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5497 */
a1e8d2da
JW
5498static struct hda_input_mux alc260_acer_capture_sources[2] = {
5499 {
5500 .num_items = 4,
5501 .items = {
5502 { "Mic", 0x0 },
5503 { "Line", 0x2 },
5504 { "CD", 0x4 },
5505 { "Headphone", 0x5 },
5506 },
5507 },
5508 {
5509 .num_items = 5,
5510 .items = {
5511 { "Mic", 0x0 },
5512 { "Line", 0x2 },
5513 { "CD", 0x4 },
5514 { "Headphone", 0x6 },
5515 { "Mixer", 0x5 },
5516 },
0bfc90e9
JW
5517 },
5518};
cc959489
MS
5519
5520/* Maxdata Favorit 100XS */
5521static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5522 {
5523 .num_items = 2,
5524 .items = {
5525 { "Line/Mic", 0x0 },
5526 { "CD", 0x4 },
5527 },
5528 },
5529 {
5530 .num_items = 3,
5531 .items = {
5532 { "Line/Mic", 0x0 },
5533 { "CD", 0x4 },
5534 { "Mixer", 0x5 },
5535 },
5536 },
5537};
5538
1da177e4
LT
5539/*
5540 * This is just place-holder, so there's something for alc_build_pcms to look
5541 * at when it calculates the maximum number of channels. ALC260 has no mixer
5542 * element which allows changing the channel mode, so the verb list is
5543 * never used.
5544 */
d2a6d7dc 5545static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5546 { 2, NULL },
5547};
5548
df694daa
KY
5549
5550/* Mixer combinations
5551 *
5552 * basic: base_output + input + pc_beep + capture
5553 * HP: base_output + input + capture_alt
5554 * HP_3013: hp_3013 + input + capture
5555 * fujitsu: fujitsu + capture
0bfc90e9 5556 * acer: acer + capture
df694daa
KY
5557 */
5558
5559static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5560 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5561 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5562 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5563 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5564 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5565 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5566 { } /* end */
f12ab1e0 5567};
1da177e4 5568
df694daa 5569static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5570 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5571 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5572 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5573 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5574 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5575 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5576 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5577 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5578 { } /* end */
5579};
5580
bec15c3a
TI
5581/* update HP, line and mono out pins according to the master switch */
5582static void alc260_hp_master_update(struct hda_codec *codec,
5583 hda_nid_t hp, hda_nid_t line,
5584 hda_nid_t mono)
5585{
5586 struct alc_spec *spec = codec->spec;
5587 unsigned int val = spec->master_sw ? PIN_HP : 0;
5588 /* change HP and line-out pins */
30cde0aa 5589 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5590 val);
30cde0aa 5591 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5592 val);
5593 /* mono (speaker) depending on the HP jack sense */
5594 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5595 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5596 val);
5597}
5598
5599static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5600 struct snd_ctl_elem_value *ucontrol)
5601{
5602 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5603 struct alc_spec *spec = codec->spec;
5604 *ucontrol->value.integer.value = spec->master_sw;
5605 return 0;
5606}
5607
5608static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5609 struct snd_ctl_elem_value *ucontrol)
5610{
5611 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5612 struct alc_spec *spec = codec->spec;
5613 int val = !!*ucontrol->value.integer.value;
5614 hda_nid_t hp, line, mono;
5615
5616 if (val == spec->master_sw)
5617 return 0;
5618 spec->master_sw = val;
5619 hp = (kcontrol->private_value >> 16) & 0xff;
5620 line = (kcontrol->private_value >> 8) & 0xff;
5621 mono = kcontrol->private_value & 0xff;
5622 alc260_hp_master_update(codec, hp, line, mono);
5623 return 1;
5624}
5625
5626static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5627 {
5628 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5629 .name = "Master Playback Switch",
5b0cb1d8 5630 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5631 .info = snd_ctl_boolean_mono_info,
5632 .get = alc260_hp_master_sw_get,
5633 .put = alc260_hp_master_sw_put,
5634 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5635 },
5636 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5637 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5638 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5639 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5640 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5641 HDA_OUTPUT),
5642 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5643 { } /* end */
5644};
5645
5646static struct hda_verb alc260_hp_unsol_verbs[] = {
5647 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5648 {},
5649};
5650
5651static void alc260_hp_automute(struct hda_codec *codec)
5652{
5653 struct alc_spec *spec = codec->spec;
bec15c3a 5654
864f92be 5655 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5656 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5657}
5658
5659static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5660{
5661 if ((res >> 26) == ALC880_HP_EVENT)
5662 alc260_hp_automute(codec);
5663}
5664
df694daa 5665static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5666 {
5667 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5668 .name = "Master Playback Switch",
5b0cb1d8 5669 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5670 .info = snd_ctl_boolean_mono_info,
5671 .get = alc260_hp_master_sw_get,
5672 .put = alc260_hp_master_sw_put,
30cde0aa 5673 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5674 },
df694daa
KY
5675 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5676 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5677 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5678 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5679 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5680 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
5681 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5682 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
5683 { } /* end */
5684};
5685
3f878308
KY
5686static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5687 .ops = &snd_hda_bind_vol,
5688 .values = {
5689 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5690 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5691 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5692 0
5693 },
5694};
5695
5696static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5697 .ops = &snd_hda_bind_sw,
5698 .values = {
5699 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5700 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5701 0
5702 },
5703};
5704
5705static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5706 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5707 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5708 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5709 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5710 { } /* end */
5711};
5712
bec15c3a
TI
5713static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5714 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5715 {},
5716};
5717
5718static void alc260_hp_3013_automute(struct hda_codec *codec)
5719{
5720 struct alc_spec *spec = codec->spec;
bec15c3a 5721
864f92be 5722 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 5723 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
5724}
5725
5726static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5727 unsigned int res)
5728{
5729 if ((res >> 26) == ALC880_HP_EVENT)
5730 alc260_hp_3013_automute(codec);
5731}
5732
3f878308
KY
5733static void alc260_hp_3012_automute(struct hda_codec *codec)
5734{
864f92be 5735 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 5736
3f878308
KY
5737 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5738 bits);
5739 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5740 bits);
5741 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5742 bits);
5743}
5744
5745static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5746 unsigned int res)
5747{
5748 if ((res >> 26) == ALC880_HP_EVENT)
5749 alc260_hp_3012_automute(codec);
5750}
5751
5752/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
5753 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5754 */
c8b6bf9b 5755static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 5756 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5757 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 5758 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
5759 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5760 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5761 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5762 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 5763 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
5764 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5765 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
5766 { } /* end */
5767};
5768
a1e8d2da
JW
5769/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5770 * versions of the ALC260 don't act on requests to enable mic bias from NID
5771 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5772 * datasheet doesn't mention this restriction. At this stage it's not clear
5773 * whether this behaviour is intentional or is a hardware bug in chip
5774 * revisions available in early 2006. Therefore for now allow the
5775 * "Headphone Jack Mode" control to span all choices, but if it turns out
5776 * that the lack of mic bias for this NID is intentional we could change the
5777 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5778 *
5779 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5780 * don't appear to make the mic bias available from the "line" jack, even
5781 * though the NID used for this jack (0x14) can supply it. The theory is
5782 * that perhaps Acer have included blocking capacitors between the ALC260
5783 * and the output jack. If this turns out to be the case for all such
5784 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5785 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
5786 *
5787 * The C20x Tablet series have a mono internal speaker which is controlled
5788 * via the chip's Mono sum widget and pin complex, so include the necessary
5789 * controls for such models. On models without a "mono speaker" the control
5790 * won't do anything.
a1e8d2da 5791 */
0bfc90e9
JW
5792static struct snd_kcontrol_new alc260_acer_mixer[] = {
5793 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5794 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 5795 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 5796 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 5797 HDA_OUTPUT),
31bffaa9 5798 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 5799 HDA_INPUT),
0bfc90e9
JW
5800 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5801 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5802 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5803 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5804 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5805 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5806 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5807 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
5808 { } /* end */
5809};
5810
cc959489
MS
5811/* Maxdata Favorit 100XS: one output and one input (0x12) jack
5812 */
5813static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5814 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5815 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5816 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5817 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5818 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5819 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5820 { } /* end */
5821};
5822
bc9f98a9
KY
5823/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5824 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5825 */
5826static struct snd_kcontrol_new alc260_will_mixer[] = {
5827 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5828 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5829 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5830 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5831 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5832 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5833 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5834 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5835 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5836 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
5837 { } /* end */
5838};
5839
5840/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5841 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5842 */
5843static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5844 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5845 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5846 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5847 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5848 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5849 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5850 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5851 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5852 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5853 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5854 { } /* end */
5855};
5856
df694daa
KY
5857/*
5858 * initialization verbs
5859 */
1da177e4
LT
5860static struct hda_verb alc260_init_verbs[] = {
5861 /* Line In pin widget for input */
05acb863 5862 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5863 /* CD pin widget for input */
05acb863 5864 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5865 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 5866 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5867 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 5868 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5869 /* LINE-2 is used for line-out in rear */
05acb863 5870 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5871 /* select line-out */
fd56f2db 5872 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5873 /* LINE-OUT pin */
05acb863 5874 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5875 /* enable HP */
05acb863 5876 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 5877 /* enable Mono */
05acb863
TI
5878 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5879 /* mute capture amp left and right */
16ded525 5880 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
5881 /* set connection select to line in (default select for this ADC) */
5882 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
5883 /* mute capture amp left and right */
5884 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5885 /* set connection select to line in (default select for this ADC) */
5886 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
5887 /* set vol=0 Line-Out mixer amp left and right */
5888 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5889 /* unmute pin widget amp left and right (no gain on this amp) */
5890 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5891 /* set vol=0 HP mixer amp left and right */
5892 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5893 /* unmute pin widget amp left and right (no gain on this amp) */
5894 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5895 /* set vol=0 Mono mixer amp left and right */
5896 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5897 /* unmute pin widget amp left and right (no gain on this amp) */
5898 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5899 /* unmute LINE-2 out pin */
5900 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
5901 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5902 * Line In 2 = 0x03
5903 */
cb53c626
TI
5904 /* mute analog inputs */
5905 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5906 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5907 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5908 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5909 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5910 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
5911 /* mute Front out path */
5912 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5913 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5914 /* mute Headphone out path */
5915 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5916 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5917 /* mute Mono out path */
5918 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5919 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
5920 { }
5921};
5922
474167d6 5923#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
5924static struct hda_verb alc260_hp_init_verbs[] = {
5925 /* Headphone and output */
5926 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5927 /* mono output */
5928 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5929 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5930 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5931 /* Mic2 (front panel) pin widget for input and vref at 80% */
5932 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5933 /* Line In pin widget for input */
5934 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5935 /* Line-2 pin widget for output */
5936 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5937 /* CD pin widget for input */
5938 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5939 /* unmute amp left and right */
5940 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5941 /* set connection select to line in (default select for this ADC) */
5942 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5943 /* unmute Line-Out mixer amp left and right (volume = 0) */
5944 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5945 /* mute pin widget amp left and right (no gain on this amp) */
5946 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5947 /* unmute HP mixer amp left and right (volume = 0) */
5948 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5949 /* mute pin widget amp left and right (no gain on this amp) */
5950 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5951 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5952 * Line In 2 = 0x03
5953 */
cb53c626
TI
5954 /* mute analog inputs */
5955 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5956 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5957 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5958 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5959 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5960 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5961 /* Unmute Front out path */
5962 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5963 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5964 /* Unmute Headphone out path */
5965 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5966 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5967 /* Unmute Mono out path */
5968 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5969 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5970 { }
5971};
474167d6 5972#endif
df694daa
KY
5973
5974static struct hda_verb alc260_hp_3013_init_verbs[] = {
5975 /* Line out and output */
5976 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5977 /* mono output */
5978 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5979 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5980 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5981 /* Mic2 (front panel) pin widget for input and vref at 80% */
5982 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5983 /* Line In pin widget for input */
5984 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5985 /* Headphone pin widget for output */
5986 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5987 /* CD pin widget for input */
5988 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5989 /* unmute amp left and right */
5990 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5991 /* set connection select to line in (default select for this ADC) */
5992 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5993 /* unmute Line-Out mixer amp left and right (volume = 0) */
5994 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5995 /* mute pin widget amp left and right (no gain on this amp) */
5996 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5997 /* unmute HP mixer amp left and right (volume = 0) */
5998 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5999 /* mute pin widget amp left and right (no gain on this amp) */
6000 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6001 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6002 * Line In 2 = 0x03
6003 */
cb53c626
TI
6004 /* mute analog inputs */
6005 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6006 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6007 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6008 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6009 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6010 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6011 /* Unmute Front out path */
6012 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6013 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6014 /* Unmute Headphone out path */
6015 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6016 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6017 /* Unmute Mono out path */
6018 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6019 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6020 { }
6021};
6022
a9430dd8 6023/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6024 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6025 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
6026 */
6027static struct hda_verb alc260_fujitsu_init_verbs[] = {
6028 /* Disable all GPIOs */
6029 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6030 /* Internal speaker is connected to headphone pin */
6031 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6032 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6033 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6034 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6035 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6036 /* Ensure all other unused pins are disabled and muted. */
6037 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6038 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6039 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6040 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6041 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6042 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6043 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6044 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6045
6046 /* Disable digital (SPDIF) pins */
6047 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6048 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6049
ea1fb29a 6050 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6051 * when acting as an output.
6052 */
6053 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6054
f7ace40d 6055 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6056 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6057 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6058 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6059 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6060 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6061 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6062 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6063 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6064 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6065
f7ace40d
JW
6066 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6067 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6068 /* Unmute Line1 pin widget output buffer since it starts as an output.
6069 * If the pin mode is changed by the user the pin mode control will
6070 * take care of enabling the pin's input/output buffers as needed.
6071 * Therefore there's no need to enable the input buffer at this
6072 * stage.
cdcd9268 6073 */
f7ace40d 6074 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6075 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6076 * mixer ctrl)
6077 */
f7ace40d
JW
6078 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6079
6080 /* Mute capture amp left and right */
6081 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6082 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6083 * in (on mic1 pin)
6084 */
6085 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6086
6087 /* Do the same for the second ADC: mute capture input amp and
6088 * set ADC connection to line in (on mic1 pin)
6089 */
6090 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6091 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6092
6093 /* Mute all inputs to mixer widget (even unconnected ones) */
6094 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6095 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6096 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6097 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6098 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6099 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6100 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6101 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6102
6103 { }
a9430dd8
JW
6104};
6105
0bfc90e9
JW
6106/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6107 * similar laptops (adapted from Fujitsu init verbs).
6108 */
6109static struct hda_verb alc260_acer_init_verbs[] = {
6110 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6111 * the headphone jack. Turn this on and rely on the standard mute
6112 * methods whenever the user wants to turn these outputs off.
6113 */
6114 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6115 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6116 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6117 /* Internal speaker/Headphone jack is connected to Line-out pin */
6118 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6119 /* Internal microphone/Mic jack is connected to Mic1 pin */
6120 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6121 /* Line In jack is connected to Line1 pin */
6122 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6123 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6124 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6125 /* Ensure all other unused pins are disabled and muted. */
6126 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6127 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6128 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6129 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6130 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6131 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6132 /* Disable digital (SPDIF) pins */
6133 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6134 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6135
ea1fb29a 6136 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6137 * bus when acting as outputs.
6138 */
6139 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6140 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6141
6142 /* Start with output sum widgets muted and their output gains at min */
6143 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6144 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6145 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6146 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6147 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6148 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6149 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6150 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6151 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6152
f12ab1e0
TI
6153 /* Unmute Line-out pin widget amp left and right
6154 * (no equiv mixer ctrl)
6155 */
0bfc90e9 6156 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6157 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6158 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6159 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6160 * inputs. If the pin mode is changed by the user the pin mode control
6161 * will take care of enabling the pin's input/output buffers as needed.
6162 * Therefore there's no need to enable the input buffer at this
6163 * stage.
6164 */
6165 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6166 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6167
6168 /* Mute capture amp left and right */
6169 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6170 /* Set ADC connection select to match default mixer setting - mic
6171 * (on mic1 pin)
6172 */
6173 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6174
6175 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6176 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6177 */
6178 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6179 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6180
6181 /* Mute all inputs to mixer widget (even unconnected ones) */
6182 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6183 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6184 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6185 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6186 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6187 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6188 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6189 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6190
6191 { }
6192};
6193
cc959489
MS
6194/* Initialisation sequence for Maxdata Favorit 100XS
6195 * (adapted from Acer init verbs).
6196 */
6197static struct hda_verb alc260_favorit100_init_verbs[] = {
6198 /* GPIO 0 enables the output jack.
6199 * Turn this on and rely on the standard mute
6200 * methods whenever the user wants to turn these outputs off.
6201 */
6202 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6203 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6204 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6205 /* Line/Mic input jack is connected to Mic1 pin */
6206 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6207 /* Ensure all other unused pins are disabled and muted. */
6208 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6209 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6210 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6211 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6212 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6213 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6214 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6215 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6216 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6217 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6218 /* Disable digital (SPDIF) pins */
6219 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6220 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6221
6222 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6223 * bus when acting as outputs.
6224 */
6225 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6226 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6227
6228 /* Start with output sum widgets muted and their output gains at min */
6229 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6230 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6231 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6232 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6233 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6234 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6235 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6236 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6237 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6238
6239 /* Unmute Line-out pin widget amp left and right
6240 * (no equiv mixer ctrl)
6241 */
6242 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6243 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6244 * inputs. If the pin mode is changed by the user the pin mode control
6245 * will take care of enabling the pin's input/output buffers as needed.
6246 * Therefore there's no need to enable the input buffer at this
6247 * stage.
6248 */
6249 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6250
6251 /* Mute capture amp left and right */
6252 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6253 /* Set ADC connection select to match default mixer setting - mic
6254 * (on mic1 pin)
6255 */
6256 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6257
6258 /* Do similar with the second ADC: mute capture input amp and
6259 * set ADC connection to mic to match ALSA's default state.
6260 */
6261 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6262 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6263
6264 /* Mute all inputs to mixer widget (even unconnected ones) */
6265 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6266 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6267 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6268 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6269 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6270 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6271 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6272 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6273
6274 { }
6275};
6276
bc9f98a9
KY
6277static struct hda_verb alc260_will_verbs[] = {
6278 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6279 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6280 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6281 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6282 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6283 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6284 {}
6285};
6286
6287static struct hda_verb alc260_replacer_672v_verbs[] = {
6288 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6289 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6290 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6291
6292 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6293 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6294 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6295
6296 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6297 {}
6298};
6299
6300/* toggle speaker-output according to the hp-jack state */
6301static void alc260_replacer_672v_automute(struct hda_codec *codec)
6302{
6303 unsigned int present;
6304
6305 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6306 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6307 if (present) {
82beb8fd
TI
6308 snd_hda_codec_write_cache(codec, 0x01, 0,
6309 AC_VERB_SET_GPIO_DATA, 1);
6310 snd_hda_codec_write_cache(codec, 0x0f, 0,
6311 AC_VERB_SET_PIN_WIDGET_CONTROL,
6312 PIN_HP);
bc9f98a9 6313 } else {
82beb8fd
TI
6314 snd_hda_codec_write_cache(codec, 0x01, 0,
6315 AC_VERB_SET_GPIO_DATA, 0);
6316 snd_hda_codec_write_cache(codec, 0x0f, 0,
6317 AC_VERB_SET_PIN_WIDGET_CONTROL,
6318 PIN_OUT);
bc9f98a9
KY
6319 }
6320}
6321
6322static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6323 unsigned int res)
6324{
6325 if ((res >> 26) == ALC880_HP_EVENT)
6326 alc260_replacer_672v_automute(codec);
6327}
6328
3f878308
KY
6329static struct hda_verb alc260_hp_dc7600_verbs[] = {
6330 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6331 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6332 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6333 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6334 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6335 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6336 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6337 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6338 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6339 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6340 {}
6341};
6342
7cf51e48
JW
6343/* Test configuration for debugging, modelled after the ALC880 test
6344 * configuration.
6345 */
6346#ifdef CONFIG_SND_DEBUG
6347static hda_nid_t alc260_test_dac_nids[1] = {
6348 0x02,
6349};
6350static hda_nid_t alc260_test_adc_nids[2] = {
6351 0x04, 0x05,
6352};
a1e8d2da 6353/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6354 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6355 * is NID 0x04.
17e7aec6 6356 */
a1e8d2da
JW
6357static struct hda_input_mux alc260_test_capture_sources[2] = {
6358 {
6359 .num_items = 7,
6360 .items = {
6361 { "MIC1 pin", 0x0 },
6362 { "MIC2 pin", 0x1 },
6363 { "LINE1 pin", 0x2 },
6364 { "LINE2 pin", 0x3 },
6365 { "CD pin", 0x4 },
6366 { "LINE-OUT pin", 0x5 },
6367 { "HP-OUT pin", 0x6 },
6368 },
6369 },
6370 {
6371 .num_items = 8,
6372 .items = {
6373 { "MIC1 pin", 0x0 },
6374 { "MIC2 pin", 0x1 },
6375 { "LINE1 pin", 0x2 },
6376 { "LINE2 pin", 0x3 },
6377 { "CD pin", 0x4 },
6378 { "Mixer", 0x5 },
6379 { "LINE-OUT pin", 0x6 },
6380 { "HP-OUT pin", 0x7 },
6381 },
7cf51e48
JW
6382 },
6383};
6384static struct snd_kcontrol_new alc260_test_mixer[] = {
6385 /* Output driver widgets */
6386 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6387 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6388 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6389 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6390 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6391 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6392
a1e8d2da
JW
6393 /* Modes for retasking pin widgets
6394 * Note: the ALC260 doesn't seem to act on requests to enable mic
6395 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6396 * mention this restriction. At this stage it's not clear whether
6397 * this behaviour is intentional or is a hardware bug in chip
6398 * revisions available at least up until early 2006. Therefore for
6399 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6400 * choices, but if it turns out that the lack of mic bias for these
6401 * NIDs is intentional we could change their modes from
6402 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6403 */
7cf51e48
JW
6404 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6405 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6406 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6407 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6408 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6409 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6410
6411 /* Loopback mixer controls */
6412 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6413 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6414 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6415 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6416 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6417 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6418 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6419 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6420 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6421 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6422 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6423 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6424 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6425 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6426
6427 /* Controls for GPIO pins, assuming they are configured as outputs */
6428 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6429 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6430 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6431 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6432
92621f13
JW
6433 /* Switches to allow the digital IO pins to be enabled. The datasheet
6434 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6435 * make this output available should provide clarification.
92621f13
JW
6436 */
6437 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6438 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6439
f8225f6d
JW
6440 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6441 * this output to turn on an external amplifier.
6442 */
6443 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6444 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6445
7cf51e48
JW
6446 { } /* end */
6447};
6448static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6449 /* Enable all GPIOs as outputs with an initial value of 0 */
6450 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6451 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6452 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6453
7cf51e48
JW
6454 /* Enable retasking pins as output, initially without power amp */
6455 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6456 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6457 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6458 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6459 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6460 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6461
92621f13
JW
6462 /* Disable digital (SPDIF) pins initially, but users can enable
6463 * them via a mixer switch. In the case of SPDIF-out, this initverb
6464 * payload also sets the generation to 0, output to be in "consumer"
6465 * PCM format, copyright asserted, no pre-emphasis and no validity
6466 * control.
6467 */
7cf51e48
JW
6468 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6469 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6470
ea1fb29a 6471 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6472 * OUT1 sum bus when acting as an output.
6473 */
6474 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6475 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6476 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6477 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6478
6479 /* Start with output sum widgets muted and their output gains at min */
6480 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6481 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6482 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6483 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6484 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6485 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6486 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6487 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6488 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6489
cdcd9268
JW
6490 /* Unmute retasking pin widget output buffers since the default
6491 * state appears to be output. As the pin mode is changed by the
6492 * user the pin mode control will take care of enabling the pin's
6493 * input/output buffers as needed.
6494 */
7cf51e48
JW
6495 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6496 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6497 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6498 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6499 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6500 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6501 /* Also unmute the mono-out pin widget */
6502 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6503
7cf51e48
JW
6504 /* Mute capture amp left and right */
6505 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6506 /* Set ADC connection select to match default mixer setting (mic1
6507 * pin)
7cf51e48
JW
6508 */
6509 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6510
6511 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6512 * set ADC connection to mic1 pin
7cf51e48
JW
6513 */
6514 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6515 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6516
6517 /* Mute all inputs to mixer widget (even unconnected ones) */
6518 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6519 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6520 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6521 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6522 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6523 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6524 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6525 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6526
6527 { }
6528};
6529#endif
6530
6330079f
TI
6531#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6532#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6533
a3bcba38
TI
6534#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6535#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6536
df694daa
KY
6537/*
6538 * for BIOS auto-configuration
6539 */
16ded525 6540
df694daa 6541static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6542 const char *pfx, int *vol_bits)
df694daa
KY
6543{
6544 hda_nid_t nid_vol;
6545 unsigned long vol_val, sw_val;
df694daa
KY
6546 int err;
6547
6548 if (nid >= 0x0f && nid < 0x11) {
6549 nid_vol = nid - 0x7;
6550 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6551 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6552 } else if (nid == 0x11) {
6553 nid_vol = nid - 0x7;
6554 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6555 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6556 } else if (nid >= 0x12 && nid <= 0x15) {
6557 nid_vol = 0x08;
6558 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6559 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6560 } else
6561 return 0; /* N/A */
ea1fb29a 6562
863b4518
TI
6563 if (!(*vol_bits & (1 << nid_vol))) {
6564 /* first control for the volume widget */
0afe5f89 6565 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6566 if (err < 0)
6567 return err;
6568 *vol_bits |= (1 << nid_vol);
6569 }
0afe5f89 6570 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6571 if (err < 0)
df694daa
KY
6572 return err;
6573 return 1;
6574}
6575
6576/* add playback controls from the parsed DAC table */
6577static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6578 const struct auto_pin_cfg *cfg)
6579{
6580 hda_nid_t nid;
6581 int err;
863b4518 6582 int vols = 0;
df694daa
KY
6583
6584 spec->multiout.num_dacs = 1;
6585 spec->multiout.dac_nids = spec->private_dac_nids;
6586 spec->multiout.dac_nids[0] = 0x02;
6587
6588 nid = cfg->line_out_pins[0];
6589 if (nid) {
23112d6d
TI
6590 const char *pfx;
6591 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6592 pfx = "Master";
6593 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6594 pfx = "Speaker";
6595 else
6596 pfx = "Front";
6597 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6598 if (err < 0)
6599 return err;
6600 }
6601
82bc955f 6602 nid = cfg->speaker_pins[0];
df694daa 6603 if (nid) {
863b4518 6604 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6605 if (err < 0)
6606 return err;
6607 }
6608
eb06ed8f 6609 nid = cfg->hp_pins[0];
df694daa 6610 if (nid) {
863b4518
TI
6611 err = alc260_add_playback_controls(spec, nid, "Headphone",
6612 &vols);
df694daa
KY
6613 if (err < 0)
6614 return err;
6615 }
f12ab1e0 6616 return 0;
df694daa
KY
6617}
6618
6619/* create playback/capture controls for input pins */
05f5f477 6620static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6621 const struct auto_pin_cfg *cfg)
6622{
05f5f477 6623 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6624}
6625
6626static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6627 hda_nid_t nid, int pin_type,
6628 int sel_idx)
6629{
f6c7e546 6630 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6631 /* need the manual connection? */
6632 if (nid >= 0x12) {
6633 int idx = nid - 0x12;
6634 snd_hda_codec_write(codec, idx + 0x0b, 0,
6635 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6636 }
6637}
6638
6639static void alc260_auto_init_multi_out(struct hda_codec *codec)
6640{
6641 struct alc_spec *spec = codec->spec;
6642 hda_nid_t nid;
6643
f12ab1e0 6644 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6645 if (nid) {
6646 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6647 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6648 }
ea1fb29a 6649
82bc955f 6650 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6651 if (nid)
6652 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6653
eb06ed8f 6654 nid = spec->autocfg.hp_pins[0];
df694daa 6655 if (nid)
baba8ee9 6656 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6657}
df694daa
KY
6658
6659#define ALC260_PIN_CD_NID 0x16
6660static void alc260_auto_init_analog_input(struct hda_codec *codec)
6661{
6662 struct alc_spec *spec = codec->spec;
6663 int i;
6664
6665 for (i = 0; i < AUTO_PIN_LAST; i++) {
6666 hda_nid_t nid = spec->autocfg.input_pins[i];
6667 if (nid >= 0x12) {
23f0c048 6668 alc_set_input_pin(codec, nid, i);
e82c025b
TI
6669 if (nid != ALC260_PIN_CD_NID &&
6670 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6671 snd_hda_codec_write(codec, nid, 0,
6672 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6673 AMP_OUT_MUTE);
6674 }
6675 }
6676}
6677
7f311a46
TI
6678#define alc260_auto_init_input_src alc880_auto_init_input_src
6679
df694daa
KY
6680/*
6681 * generic initialization of ADC, input mixers and output mixers
6682 */
6683static struct hda_verb alc260_volume_init_verbs[] = {
6684 /*
6685 * Unmute ADC0-1 and set the default input to mic-in
6686 */
6687 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6688 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6689 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6690 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 6691
df694daa
KY
6692 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6693 * mixer widget
f12ab1e0
TI
6694 * Note: PASD motherboards uses the Line In 2 as the input for
6695 * front panel mic (mic 2)
df694daa
KY
6696 */
6697 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6698 /* mute analog inputs */
6699 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6700 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6701 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6702 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6703 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6704
6705 /*
6706 * Set up output mixers (0x08 - 0x0a)
6707 */
6708 /* set vol=0 to output mixers */
6709 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6710 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6711 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6712 /* set up input amps for analog loopback */
6713 /* Amp Indices: DAC = 0, mixer = 1 */
6714 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6715 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6716 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6717 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6718 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6719 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 6720
df694daa
KY
6721 { }
6722};
6723
6724static int alc260_parse_auto_config(struct hda_codec *codec)
6725{
6726 struct alc_spec *spec = codec->spec;
df694daa
KY
6727 int err;
6728 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6729
f12ab1e0
TI
6730 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6731 alc260_ignore);
6732 if (err < 0)
df694daa 6733 return err;
f12ab1e0
TI
6734 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6735 if (err < 0)
4a471b7d 6736 return err;
603c4019 6737 if (!spec->kctls.list)
df694daa 6738 return 0; /* can't find valid BIOS pin config */
05f5f477 6739 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 6740 if (err < 0)
df694daa
KY
6741 return err;
6742
6743 spec->multiout.max_channels = 2;
6744
0852d7a6 6745 if (spec->autocfg.dig_outs)
df694daa 6746 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 6747 if (spec->kctls.list)
d88897ea 6748 add_mixer(spec, spec->kctls.list);
df694daa 6749
d88897ea 6750 add_verb(spec, alc260_volume_init_verbs);
df694daa 6751
a1e8d2da 6752 spec->num_mux_defs = 1;
61b9b9b1 6753 spec->input_mux = &spec->private_imux[0];
df694daa 6754
6227cdce 6755 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 6756
df694daa
KY
6757 return 1;
6758}
6759
ae6b813a
TI
6760/* additional initialization for auto-configuration model */
6761static void alc260_auto_init(struct hda_codec *codec)
df694daa 6762{
f6c7e546 6763 struct alc_spec *spec = codec->spec;
df694daa
KY
6764 alc260_auto_init_multi_out(codec);
6765 alc260_auto_init_analog_input(codec);
7f311a46 6766 alc260_auto_init_input_src(codec);
757899ac 6767 alc_auto_init_digital(codec);
f6c7e546 6768 if (spec->unsol_event)
7fb0d78f 6769 alc_inithook(codec);
df694daa
KY
6770}
6771
cb53c626
TI
6772#ifdef CONFIG_SND_HDA_POWER_SAVE
6773static struct hda_amp_list alc260_loopbacks[] = {
6774 { 0x07, HDA_INPUT, 0 },
6775 { 0x07, HDA_INPUT, 1 },
6776 { 0x07, HDA_INPUT, 2 },
6777 { 0x07, HDA_INPUT, 3 },
6778 { 0x07, HDA_INPUT, 4 },
6779 { } /* end */
6780};
6781#endif
6782
df694daa
KY
6783/*
6784 * ALC260 configurations
6785 */
f5fcc13c
TI
6786static const char *alc260_models[ALC260_MODEL_LAST] = {
6787 [ALC260_BASIC] = "basic",
6788 [ALC260_HP] = "hp",
6789 [ALC260_HP_3013] = "hp-3013",
2922c9af 6790 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
6791 [ALC260_FUJITSU_S702X] = "fujitsu",
6792 [ALC260_ACER] = "acer",
bc9f98a9
KY
6793 [ALC260_WILL] = "will",
6794 [ALC260_REPLACER_672V] = "replacer",
cc959489 6795 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 6796#ifdef CONFIG_SND_DEBUG
f5fcc13c 6797 [ALC260_TEST] = "test",
7cf51e48 6798#endif
f5fcc13c
TI
6799 [ALC260_AUTO] = "auto",
6800};
6801
6802static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 6803 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 6804 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 6805 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 6806 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 6807 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 6808 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 6809 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 6810 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 6811 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
6812 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6813 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6814 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6815 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6816 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6817 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6818 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6819 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6820 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 6821 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 6822 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
6823 {}
6824};
6825
6826static struct alc_config_preset alc260_presets[] = {
6827 [ALC260_BASIC] = {
6828 .mixers = { alc260_base_output_mixer,
45bdd1c1 6829 alc260_input_mixer },
df694daa
KY
6830 .init_verbs = { alc260_init_verbs },
6831 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6832 .dac_nids = alc260_dac_nids,
f9e336f6 6833 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 6834 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
6835 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6836 .channel_mode = alc260_modes,
6837 .input_mux = &alc260_capture_source,
6838 },
6839 [ALC260_HP] = {
bec15c3a 6840 .mixers = { alc260_hp_output_mixer,
f9e336f6 6841 alc260_input_mixer },
bec15c3a
TI
6842 .init_verbs = { alc260_init_verbs,
6843 alc260_hp_unsol_verbs },
df694daa
KY
6844 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6845 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6846 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6847 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6848 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6849 .channel_mode = alc260_modes,
6850 .input_mux = &alc260_capture_source,
bec15c3a
TI
6851 .unsol_event = alc260_hp_unsol_event,
6852 .init_hook = alc260_hp_automute,
df694daa 6853 },
3f878308
KY
6854 [ALC260_HP_DC7600] = {
6855 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 6856 alc260_input_mixer },
3f878308
KY
6857 .init_verbs = { alc260_init_verbs,
6858 alc260_hp_dc7600_verbs },
6859 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6860 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6861 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6862 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
6863 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6864 .channel_mode = alc260_modes,
6865 .input_mux = &alc260_capture_source,
6866 .unsol_event = alc260_hp_3012_unsol_event,
6867 .init_hook = alc260_hp_3012_automute,
6868 },
df694daa
KY
6869 [ALC260_HP_3013] = {
6870 .mixers = { alc260_hp_3013_mixer,
f9e336f6 6871 alc260_input_mixer },
bec15c3a
TI
6872 .init_verbs = { alc260_hp_3013_init_verbs,
6873 alc260_hp_3013_unsol_verbs },
df694daa
KY
6874 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6875 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6876 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6877 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6878 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6879 .channel_mode = alc260_modes,
6880 .input_mux = &alc260_capture_source,
bec15c3a
TI
6881 .unsol_event = alc260_hp_3013_unsol_event,
6882 .init_hook = alc260_hp_3013_automute,
df694daa
KY
6883 },
6884 [ALC260_FUJITSU_S702X] = {
f9e336f6 6885 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
6886 .init_verbs = { alc260_fujitsu_init_verbs },
6887 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6888 .dac_nids = alc260_dac_nids,
d57fdac0
JW
6889 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6890 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
6891 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6892 .channel_mode = alc260_modes,
a1e8d2da
JW
6893 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6894 .input_mux = alc260_fujitsu_capture_sources,
df694daa 6895 },
0bfc90e9 6896 [ALC260_ACER] = {
f9e336f6 6897 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
6898 .init_verbs = { alc260_acer_init_verbs },
6899 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6900 .dac_nids = alc260_dac_nids,
6901 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6902 .adc_nids = alc260_dual_adc_nids,
6903 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6904 .channel_mode = alc260_modes,
a1e8d2da
JW
6905 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6906 .input_mux = alc260_acer_capture_sources,
0bfc90e9 6907 },
cc959489
MS
6908 [ALC260_FAVORIT100] = {
6909 .mixers = { alc260_favorit100_mixer },
6910 .init_verbs = { alc260_favorit100_init_verbs },
6911 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6912 .dac_nids = alc260_dac_nids,
6913 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6914 .adc_nids = alc260_dual_adc_nids,
6915 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6916 .channel_mode = alc260_modes,
6917 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6918 .input_mux = alc260_favorit100_capture_sources,
6919 },
bc9f98a9 6920 [ALC260_WILL] = {
f9e336f6 6921 .mixers = { alc260_will_mixer },
bc9f98a9
KY
6922 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6923 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6924 .dac_nids = alc260_dac_nids,
6925 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6926 .adc_nids = alc260_adc_nids,
6927 .dig_out_nid = ALC260_DIGOUT_NID,
6928 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6929 .channel_mode = alc260_modes,
6930 .input_mux = &alc260_capture_source,
6931 },
6932 [ALC260_REPLACER_672V] = {
f9e336f6 6933 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
6934 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6935 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6936 .dac_nids = alc260_dac_nids,
6937 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6938 .adc_nids = alc260_adc_nids,
6939 .dig_out_nid = ALC260_DIGOUT_NID,
6940 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6941 .channel_mode = alc260_modes,
6942 .input_mux = &alc260_capture_source,
6943 .unsol_event = alc260_replacer_672v_unsol_event,
6944 .init_hook = alc260_replacer_672v_automute,
6945 },
7cf51e48
JW
6946#ifdef CONFIG_SND_DEBUG
6947 [ALC260_TEST] = {
f9e336f6 6948 .mixers = { alc260_test_mixer },
7cf51e48
JW
6949 .init_verbs = { alc260_test_init_verbs },
6950 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6951 .dac_nids = alc260_test_dac_nids,
6952 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6953 .adc_nids = alc260_test_adc_nids,
6954 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6955 .channel_mode = alc260_modes,
a1e8d2da
JW
6956 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6957 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
6958 },
6959#endif
df694daa
KY
6960};
6961
6962static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
6963{
6964 struct alc_spec *spec;
df694daa 6965 int err, board_config;
1da177e4 6966
e560d8d8 6967 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
6968 if (spec == NULL)
6969 return -ENOMEM;
6970
6971 codec->spec = spec;
6972
f5fcc13c
TI
6973 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6974 alc260_models,
6975 alc260_cfg_tbl);
6976 if (board_config < 0) {
9a11f1aa 6977 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 6978 codec->chip_name);
df694daa 6979 board_config = ALC260_AUTO;
16ded525 6980 }
1da177e4 6981
df694daa
KY
6982 if (board_config == ALC260_AUTO) {
6983 /* automatic parse from the BIOS config */
6984 err = alc260_parse_auto_config(codec);
6985 if (err < 0) {
6986 alc_free(codec);
6987 return err;
f12ab1e0 6988 } else if (!err) {
9c7f852e
TI
6989 printk(KERN_INFO
6990 "hda_codec: Cannot set up configuration "
6991 "from BIOS. Using base mode...\n");
df694daa
KY
6992 board_config = ALC260_BASIC;
6993 }
a9430dd8 6994 }
e9edcee0 6995
680cd536
KK
6996 err = snd_hda_attach_beep_device(codec, 0x1);
6997 if (err < 0) {
6998 alc_free(codec);
6999 return err;
7000 }
7001
df694daa 7002 if (board_config != ALC260_AUTO)
e9c364c0 7003 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7004
1da177e4
LT
7005 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7006 spec->stream_analog_capture = &alc260_pcm_analog_capture;
7007
a3bcba38
TI
7008 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7009 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7010
4ef0ef19
TI
7011 if (!spec->adc_nids && spec->input_mux) {
7012 /* check whether NID 0x04 is valid */
7013 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7014 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7015 /* get type */
7016 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7017 spec->adc_nids = alc260_adc_nids_alt;
7018 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7019 } else {
7020 spec->adc_nids = alc260_adc_nids;
7021 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7022 }
7023 }
b59bdf3b 7024 set_capture_mixer(codec);
45bdd1c1 7025 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7026
2134ea4f
TI
7027 spec->vmaster_nid = 0x08;
7028
1da177e4 7029 codec->patch_ops = alc_patch_ops;
df694daa 7030 if (board_config == ALC260_AUTO)
ae6b813a 7031 spec->init_hook = alc260_auto_init;
cb53c626
TI
7032#ifdef CONFIG_SND_HDA_POWER_SAVE
7033 if (!spec->loopback.amplist)
7034 spec->loopback.amplist = alc260_loopbacks;
7035#endif
1da177e4
LT
7036
7037 return 0;
7038}
7039
e9edcee0 7040
1da177e4 7041/*
4953550a 7042 * ALC882/883/885/888/889 support
1da177e4
LT
7043 *
7044 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7045 * configuration. Each pin widget can choose any input DACs and a mixer.
7046 * Each ADC is connected from a mixer of all inputs. This makes possible
7047 * 6-channel independent captures.
7048 *
7049 * In addition, an independent DAC for the multi-playback (not used in this
7050 * driver yet).
7051 */
df694daa
KY
7052#define ALC882_DIGOUT_NID 0x06
7053#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7054#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7055#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7056#define ALC1200_DIGOUT_NID 0x10
7057
1da177e4 7058
d2a6d7dc 7059static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7060 { 8, NULL }
7061};
7062
4953550a 7063/* DACs */
1da177e4
LT
7064static hda_nid_t alc882_dac_nids[4] = {
7065 /* front, rear, clfe, rear_surr */
7066 0x02, 0x03, 0x04, 0x05
7067};
4953550a 7068#define alc883_dac_nids alc882_dac_nids
1da177e4 7069
4953550a 7070/* ADCs */
df694daa
KY
7071#define alc882_adc_nids alc880_adc_nids
7072#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
7073#define alc883_adc_nids alc882_adc_nids_alt
7074static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7075static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7076#define alc889_adc_nids alc880_adc_nids
1da177e4 7077
e1406348
TI
7078static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7079static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
7080#define alc883_capsrc_nids alc882_capsrc_nids_alt
7081static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7082#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7083
1da177e4
LT
7084/* input MUX */
7085/* FIXME: should be a matrix-type input source selection */
7086
7087static struct hda_input_mux alc882_capture_source = {
7088 .num_items = 4,
7089 .items = {
7090 { "Mic", 0x0 },
7091 { "Front Mic", 0x1 },
7092 { "Line", 0x2 },
7093 { "CD", 0x4 },
7094 },
7095};
41d5545d 7096
4953550a
TI
7097#define alc883_capture_source alc882_capture_source
7098
87a8c370
JK
7099static struct hda_input_mux alc889_capture_source = {
7100 .num_items = 3,
7101 .items = {
7102 { "Front Mic", 0x0 },
7103 { "Mic", 0x3 },
7104 { "Line", 0x2 },
7105 },
7106};
7107
41d5545d
KS
7108static struct hda_input_mux mb5_capture_source = {
7109 .num_items = 3,
7110 .items = {
7111 { "Mic", 0x1 },
b8f171e7 7112 { "Line", 0x7 },
41d5545d
KS
7113 { "CD", 0x4 },
7114 },
7115};
7116
e458b1fa
LY
7117static struct hda_input_mux macmini3_capture_source = {
7118 .num_items = 2,
7119 .items = {
7120 { "Line", 0x2 },
7121 { "CD", 0x4 },
7122 },
7123};
7124
4953550a
TI
7125static struct hda_input_mux alc883_3stack_6ch_intel = {
7126 .num_items = 4,
7127 .items = {
7128 { "Mic", 0x1 },
7129 { "Front Mic", 0x0 },
7130 { "Line", 0x2 },
7131 { "CD", 0x4 },
7132 },
7133};
7134
7135static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7136 .num_items = 2,
7137 .items = {
7138 { "Mic", 0x1 },
7139 { "Line", 0x2 },
7140 },
7141};
7142
7143static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7144 .num_items = 4,
7145 .items = {
7146 { "Mic", 0x0 },
150b432f 7147 { "Int Mic", 0x1 },
4953550a
TI
7148 { "Line", 0x2 },
7149 { "CD", 0x4 },
7150 },
7151};
7152
7153static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7154 .num_items = 2,
7155 .items = {
7156 { "Mic", 0x0 },
7157 { "Int Mic", 0x1 },
7158 },
7159};
7160
7161static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7162 .num_items = 3,
7163 .items = {
7164 { "Mic", 0x0 },
7165 { "Front Mic", 0x1 },
7166 { "Line", 0x4 },
7167 },
7168};
7169
7170static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7171 .num_items = 2,
7172 .items = {
7173 { "Mic", 0x0 },
7174 { "Line", 0x2 },
7175 },
7176};
7177
7178static struct hda_input_mux alc889A_mb31_capture_source = {
7179 .num_items = 2,
7180 .items = {
7181 { "Mic", 0x0 },
7182 /* Front Mic (0x01) unused */
7183 { "Line", 0x2 },
7184 /* Line 2 (0x03) unused */
af901ca1 7185 /* CD (0x04) unused? */
4953550a
TI
7186 },
7187};
7188
b7cccc52
JM
7189static struct hda_input_mux alc889A_imac91_capture_source = {
7190 .num_items = 2,
7191 .items = {
7192 { "Mic", 0x01 },
7193 { "Line", 0x2 }, /* Not sure! */
7194 },
7195};
7196
4953550a
TI
7197/*
7198 * 2ch mode
7199 */
7200static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7201 { 2, NULL }
7202};
7203
272a527c
KY
7204/*
7205 * 2ch mode
7206 */
7207static struct hda_verb alc882_3ST_ch2_init[] = {
7208 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7209 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7210 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7211 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7212 { } /* end */
7213};
7214
4953550a
TI
7215/*
7216 * 4ch mode
7217 */
7218static struct hda_verb alc882_3ST_ch4_init[] = {
7219 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7220 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7221 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7222 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7223 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7224 { } /* end */
7225};
7226
272a527c
KY
7227/*
7228 * 6ch mode
7229 */
7230static struct hda_verb alc882_3ST_ch6_init[] = {
7231 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7232 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7233 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7234 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7235 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7236 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7237 { } /* end */
7238};
7239
4953550a 7240static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7241 { 2, alc882_3ST_ch2_init },
4953550a 7242 { 4, alc882_3ST_ch4_init },
272a527c
KY
7243 { 6, alc882_3ST_ch6_init },
7244};
7245
4953550a
TI
7246#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7247
a65cc60f 7248/*
7249 * 2ch mode
7250 */
7251static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7252 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7253 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7254 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7255 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7256 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7257 { } /* end */
7258};
7259
7260/*
7261 * 4ch mode
7262 */
7263static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7264 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7265 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7266 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7267 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7268 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7269 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7270 { } /* end */
7271};
7272
7273/*
7274 * 6ch mode
7275 */
7276static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7277 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7278 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7279 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7280 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7281 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7282 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7283 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7284 { } /* end */
7285};
7286
7287static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7288 { 2, alc883_3ST_ch2_clevo_init },
7289 { 4, alc883_3ST_ch4_clevo_init },
7290 { 6, alc883_3ST_ch6_clevo_init },
7291};
7292
7293
df694daa
KY
7294/*
7295 * 6ch mode
7296 */
7297static struct hda_verb alc882_sixstack_ch6_init[] = {
7298 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7299 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7300 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7301 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7302 { } /* end */
7303};
7304
7305/*
7306 * 8ch mode
7307 */
7308static struct hda_verb alc882_sixstack_ch8_init[] = {
7309 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7310 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7311 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7312 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7313 { } /* end */
7314};
7315
7316static struct hda_channel_mode alc882_sixstack_modes[2] = {
7317 { 6, alc882_sixstack_ch6_init },
7318 { 8, alc882_sixstack_ch8_init },
7319};
7320
76e6f5a9
RH
7321
7322/* Macbook Air 2,1 */
7323
7324static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7325 { 2, NULL },
7326};
7327
87350ad0 7328/*
def319f9 7329 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7330 */
7331
7332/*
7333 * 2ch mode
7334 */
7335static struct hda_verb alc885_mbp_ch2_init[] = {
7336 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7337 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7338 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7339 { } /* end */
7340};
7341
7342/*
a3f730af 7343 * 4ch mode
87350ad0 7344 */
a3f730af 7345static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7346 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7347 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7348 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7349 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7350 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7351 { } /* end */
7352};
7353
a3f730af 7354static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7355 { 2, alc885_mbp_ch2_init },
a3f730af 7356 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7357};
7358
92b9de83
KS
7359/*
7360 * 2ch
7361 * Speakers/Woofer/HP = Front
7362 * LineIn = Input
7363 */
7364static struct hda_verb alc885_mb5_ch2_init[] = {
7365 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7366 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7367 { } /* end */
7368};
7369
7370/*
7371 * 6ch mode
7372 * Speakers/HP = Front
7373 * Woofer = LFE
7374 * LineIn = Surround
7375 */
7376static struct hda_verb alc885_mb5_ch6_init[] = {
7377 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7378 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7379 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7380 { } /* end */
7381};
7382
7383static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7384 { 2, alc885_mb5_ch2_init },
7385 { 6, alc885_mb5_ch6_init },
7386};
87350ad0 7387
d01aecdf 7388#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7389
7390/*
7391 * 2ch mode
7392 */
7393static struct hda_verb alc883_4ST_ch2_init[] = {
7394 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7395 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7396 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7397 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7398 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7399 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7400 { } /* end */
7401};
7402
7403/*
7404 * 4ch mode
7405 */
7406static struct hda_verb alc883_4ST_ch4_init[] = {
7407 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7408 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7409 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7410 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7411 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7412 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7413 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7414 { } /* end */
7415};
7416
7417/*
7418 * 6ch mode
7419 */
7420static struct hda_verb alc883_4ST_ch6_init[] = {
7421 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7422 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7423 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7424 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7425 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7426 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7427 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7428 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7429 { } /* end */
7430};
7431
7432/*
7433 * 8ch mode
7434 */
7435static struct hda_verb alc883_4ST_ch8_init[] = {
7436 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7437 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7438 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7439 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7440 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7441 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7442 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7443 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7444 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7445 { } /* end */
7446};
7447
7448static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7449 { 2, alc883_4ST_ch2_init },
7450 { 4, alc883_4ST_ch4_init },
7451 { 6, alc883_4ST_ch6_init },
7452 { 8, alc883_4ST_ch8_init },
7453};
7454
7455
7456/*
7457 * 2ch mode
7458 */
7459static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7460 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7461 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7462 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7463 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7464 { } /* end */
7465};
7466
7467/*
7468 * 4ch mode
7469 */
7470static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7471 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7472 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7473 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7474 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7475 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7476 { } /* end */
7477};
7478
7479/*
7480 * 6ch mode
7481 */
7482static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7483 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7484 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7485 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7486 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7487 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7488 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7489 { } /* end */
7490};
7491
7492static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7493 { 2, alc883_3ST_ch2_intel_init },
7494 { 4, alc883_3ST_ch4_intel_init },
7495 { 6, alc883_3ST_ch6_intel_init },
7496};
7497
dd7714c9
WF
7498/*
7499 * 2ch mode
7500 */
7501static struct hda_verb alc889_ch2_intel_init[] = {
7502 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7503 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7504 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7505 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7506 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7507 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7508 { } /* end */
7509};
7510
87a8c370
JK
7511/*
7512 * 6ch mode
7513 */
7514static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7515 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7516 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7517 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7518 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7519 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7520 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7521 { } /* end */
7522};
7523
7524/*
7525 * 8ch mode
7526 */
7527static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7528 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7529 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7530 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7531 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7532 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7533 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7534 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7535 { } /* end */
7536};
7537
dd7714c9
WF
7538static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7539 { 2, alc889_ch2_intel_init },
87a8c370
JK
7540 { 6, alc889_ch6_intel_init },
7541 { 8, alc889_ch8_intel_init },
7542};
7543
4953550a
TI
7544/*
7545 * 6ch mode
7546 */
7547static struct hda_verb alc883_sixstack_ch6_init[] = {
7548 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7549 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7550 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7551 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7552 { } /* end */
7553};
7554
7555/*
7556 * 8ch mode
7557 */
7558static struct hda_verb alc883_sixstack_ch8_init[] = {
7559 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7560 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7561 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7562 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7563 { } /* end */
7564};
7565
7566static struct hda_channel_mode alc883_sixstack_modes[2] = {
7567 { 6, alc883_sixstack_ch6_init },
7568 { 8, alc883_sixstack_ch8_init },
7569};
7570
7571
1da177e4
LT
7572/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7573 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7574 */
c8b6bf9b 7575static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7576 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7577 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7578 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7579 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7580 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7581 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7582 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7583 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7584 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7585 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7586 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7587 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7588 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7589 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7590 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7591 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7592 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
7593 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7594 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7595 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4 7596 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7597 { } /* end */
7598};
7599
76e6f5a9
RH
7600/* Macbook Air 2,1 same control for HP and internal Speaker */
7601
7602static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7603 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7604 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7605 { }
7606};
7607
7608
87350ad0 7609static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7610 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7611 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7612 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7613 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7614 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7615 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7616 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7617 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7618 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 7619 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
7620 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7621 { } /* end */
7622};
41d5545d
KS
7623
7624static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
7625 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7626 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7627 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7628 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7629 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7630 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
7631 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7632 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
7633 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7634 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
7635 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7636 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7637 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7638 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7639 { } /* end */
7640};
92b9de83 7641
e458b1fa
LY
7642static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7643 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7644 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7645 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7646 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7647 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7648 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7649 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7650 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7651 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7652 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7653 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7654 { } /* end */
7655};
7656
4b7e1803 7657static struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
7658 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7659 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
7660 { } /* end */
7661};
7662
7663
bdd148a3
KY
7664static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7665 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7666 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7667 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7668 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7669 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7670 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7671 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7672 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7673 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
7674 { } /* end */
7675};
7676
272a527c
KY
7677static struct snd_kcontrol_new alc882_targa_mixer[] = {
7678 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7679 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7680 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7681 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7682 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7683 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7684 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7685 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7686 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7687 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7688 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7689 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 7690 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
7691 { } /* end */
7692};
7693
7694/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7695 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7696 */
7697static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7698 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7699 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7700 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7701 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7702 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7703 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7704 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7705 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7706 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7707 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7708 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7709 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7710 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7711 { } /* end */
7712};
7713
914759b7
TI
7714static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7715 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7716 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7717 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7718 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7719 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7720 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7721 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7722 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7723 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7724 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
7725 { } /* end */
7726};
7727
df694daa
KY
7728static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7729 {
7730 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7731 .name = "Channel Mode",
7732 .info = alc_ch_mode_info,
7733 .get = alc_ch_mode_get,
7734 .put = alc_ch_mode_put,
7735 },
7736 { } /* end */
7737};
7738
4953550a 7739static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 7740 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
7741 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7742 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7743 /* Rear mixer */
05acb863
TI
7744 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7745 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7746 /* CLFE mixer */
05acb863
TI
7747 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7748 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7749 /* Side mixer */
05acb863
TI
7750 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7751 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7752
e9edcee0 7753 /* Front Pin: output 0 (0x0c) */
05acb863 7754 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7755 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7756 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 7757 /* Rear Pin: output 1 (0x0d) */
05acb863 7758 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7759 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7760 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 7761 /* CLFE Pin: output 2 (0x0e) */
05acb863 7762 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7763 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7764 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 7765 /* Side Pin: output 3 (0x0f) */
05acb863 7766 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7767 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7768 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 7769 /* Mic (rear) pin: input vref at 80% */
16ded525 7770 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7771 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7772 /* Front Mic pin: input vref at 80% */
16ded525 7773 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7774 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7775 /* Line In pin: input */
05acb863 7776 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
7777 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7778 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7779 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7780 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7781 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 7782 /* CD pin widget for input */
05acb863 7783 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
7784
7785 /* FIXME: use matrix-type input source selection */
7786 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 7787 /* Input mixer2 */
05acb863 7788 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 7789 /* Input mixer3 */
05acb863 7790 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
7791 /* ADC2: mute amp left and right */
7792 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7793 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
7794 /* ADC3: mute amp left and right */
7795 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7796 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
7797
7798 { }
7799};
7800
4953550a
TI
7801static struct hda_verb alc882_adc1_init_verbs[] = {
7802 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7803 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7804 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7805 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7806 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7807 /* ADC1: mute amp left and right */
7808 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7809 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7810 { }
7811};
7812
4b146cb0
TI
7813static struct hda_verb alc882_eapd_verbs[] = {
7814 /* change to EAPD mode */
7815 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 7816 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 7817 { }
4b146cb0
TI
7818};
7819
87a8c370
JK
7820static struct hda_verb alc889_eapd_verbs[] = {
7821 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7822 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7823 { }
7824};
7825
6732bd0d
WF
7826static struct hda_verb alc_hp15_unsol_verbs[] = {
7827 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7828 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7829 {}
7830};
87a8c370
JK
7831
7832static struct hda_verb alc885_init_verbs[] = {
7833 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
7834 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7835 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7836 /* Rear mixer */
88102f3f
KY
7837 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7838 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7839 /* CLFE mixer */
88102f3f
KY
7840 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7841 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7842 /* Side mixer */
88102f3f
KY
7843 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7844 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
7845
7846 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 7847 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
7848 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7849 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7850 /* Front Pin: output 0 (0x0c) */
7851 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7852 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7853 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7854 /* Rear Pin: output 1 (0x0d) */
7855 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7856 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7857 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
7858 /* CLFE Pin: output 2 (0x0e) */
7859 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7860 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7861 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7862 /* Side Pin: output 3 (0x0f) */
7863 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7864 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7865 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7866 /* Mic (rear) pin: input vref at 80% */
7867 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7868 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7869 /* Front Mic pin: input vref at 80% */
7870 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7871 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7872 /* Line In pin: input */
7873 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7874 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7875
7876 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7877 /* Input mixer1 */
88102f3f 7878 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
7879 /* Input mixer2 */
7880 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 7881 /* Input mixer3 */
88102f3f 7882 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
7883 /* ADC2: mute amp left and right */
7884 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7885 /* ADC3: mute amp left and right */
7886 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7887
7888 { }
7889};
7890
7891static struct hda_verb alc885_init_input_verbs[] = {
7892 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7893 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7894 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7895 { }
7896};
7897
7898
7899/* Unmute Selector 24h and set the default input to front mic */
7900static struct hda_verb alc889_init_input_verbs[] = {
7901 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7902 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7903 { }
7904};
7905
7906
4953550a
TI
7907#define alc883_init_verbs alc882_base_init_verbs
7908
9102cd1c
TD
7909/* Mac Pro test */
7910static struct snd_kcontrol_new alc882_macpro_mixer[] = {
7911 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7912 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7913 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
7914 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7915 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 7916 /* FIXME: this looks suspicious...
d355c82a
JK
7917 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
7918 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 7919 */
9102cd1c
TD
7920 { } /* end */
7921};
7922
7923static struct hda_verb alc882_macpro_init_verbs[] = {
7924 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7925 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7926 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7927 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7928 /* Front Pin: output 0 (0x0c) */
7929 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7930 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7931 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7932 /* Front Mic pin: input vref at 80% */
7933 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7934 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7935 /* Speaker: output */
7936 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7937 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7938 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
7939 /* Headphone output (output 0 - 0x0c) */
7940 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7941 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7942 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7943
7944 /* FIXME: use matrix-type input source selection */
7945 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7946 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7947 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7948 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7949 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7950 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7951 /* Input mixer2 */
7952 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7953 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7954 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7955 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7956 /* Input mixer3 */
7957 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7958 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7959 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7960 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7961 /* ADC1: mute amp left and right */
7962 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7963 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7964 /* ADC2: mute amp left and right */
7965 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7966 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7967 /* ADC3: mute amp left and right */
7968 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7969 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7970
7971 { }
7972};
f12ab1e0 7973
41d5545d
KS
7974/* Macbook 5,1 */
7975static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
7976 /* DACs */
7977 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7978 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7979 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7980 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 7981 /* Front mixer */
41d5545d
KS
7982 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7983 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7984 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
7985 /* Surround mixer */
7986 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7987 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7988 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7989 /* LFE mixer */
7990 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7991 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7992 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7993 /* HP mixer */
7994 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7995 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7996 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7997 /* Front Pin (0x0c) */
41d5545d
KS
7998 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7999 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8000 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8001 /* LFE Pin (0x0e) */
8002 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8003 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8004 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8005 /* HP Pin (0x0f) */
41d5545d
KS
8006 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8007 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8008 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8009 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8010 /* Front Mic pin: input vref at 80% */
8011 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8012 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8013 /* Line In pin */
8014 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8015 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8016
b8f171e7
AM
8017 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8018 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8019 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8020 { }
8021};
8022
e458b1fa
LY
8023/* Macmini 3,1 */
8024static struct hda_verb alc885_macmini3_init_verbs[] = {
8025 /* DACs */
8026 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8027 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8028 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8029 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8030 /* Front mixer */
8031 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8032 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8033 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8034 /* Surround mixer */
8035 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8036 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8037 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8038 /* LFE mixer */
8039 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8040 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8041 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8042 /* HP mixer */
8043 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8044 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8045 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8046 /* Front Pin (0x0c) */
8047 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8048 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8049 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8050 /* LFE Pin (0x0e) */
8051 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8052 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8053 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8054 /* HP Pin (0x0f) */
8055 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8056 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8057 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8058 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8059 /* Line In pin */
8060 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8061 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8062
8063 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8064 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8065 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8066 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8067 { }
8068};
8069
76e6f5a9
RH
8070
8071static struct hda_verb alc885_mba21_init_verbs[] = {
8072 /*Internal and HP Speaker Mixer*/
8073 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8074 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8075 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8076 /*Internal Speaker Pin (0x0c)*/
8077 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8078 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8079 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8080 /* HP Pin: output 0 (0x0e) */
8081 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8082 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8083 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8084 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8085 /* Line in (is hp when jack connected)*/
8086 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8087 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8088
8089 { }
8090 };
8091
8092
87350ad0
TI
8093/* Macbook Pro rev3 */
8094static struct hda_verb alc885_mbp3_init_verbs[] = {
8095 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8096 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8097 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8098 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8099 /* Rear mixer */
8100 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8101 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8102 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8103 /* HP mixer */
8104 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8105 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8106 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8107 /* Front Pin: output 0 (0x0c) */
8108 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8109 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8110 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8111 /* HP Pin: output 0 (0x0e) */
87350ad0 8112 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8113 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8114 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8115 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8116 /* Mic (rear) pin: input vref at 80% */
8117 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8118 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8119 /* Front Mic pin: input vref at 80% */
8120 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8121 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8122 /* Line In pin: use output 1 when in LineOut mode */
8123 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8124 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8125 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8126
8127 /* FIXME: use matrix-type input source selection */
8128 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8129 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8130 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8131 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8132 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8133 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8134 /* Input mixer2 */
8135 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8136 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8137 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8138 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8139 /* Input mixer3 */
8140 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8141 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8142 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8143 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8144 /* ADC1: mute amp left and right */
8145 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8146 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8147 /* ADC2: mute amp left and right */
8148 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8149 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8150 /* ADC3: mute amp left and right */
8151 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8152 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8153
8154 { }
8155};
8156
4b7e1803
JM
8157/* iMac 9,1 */
8158static struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8159 /* Internal Speaker Pin (0x0c) */
8160 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8161 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8162 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8163 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8164 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8165 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8166 /* HP Pin: Rear */
4b7e1803
JM
8167 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8168 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8169 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8170 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8171 /* Line in Rear */
8172 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8173 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8174 /* Front Mic pin: input vref at 80% */
8175 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8176 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8177 /* Rear mixer */
8178 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8179 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8180 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8181 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8182 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8183 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8184 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8185 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8186 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8187 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8188 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8189 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8190 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8191 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8192 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8193 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8194 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8195 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8196 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8197 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8198 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8199 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8200 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8201 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8202 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8203 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8204 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8205 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8206 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8207 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8208 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8209 { }
8210};
8211
c54728d8
NF
8212/* iMac 24 mixer. */
8213static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8214 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8215 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8216 { } /* end */
8217};
8218
8219/* iMac 24 init verbs. */
8220static struct hda_verb alc885_imac24_init_verbs[] = {
8221 /* Internal speakers: output 0 (0x0c) */
8222 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8223 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8224 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8225 /* Internal speakers: output 0 (0x0c) */
8226 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8227 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8228 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8229 /* Headphone: output 0 (0x0c) */
8230 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8231 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8232 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8233 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8234 /* Front Mic: input vref at 80% */
8235 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8236 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8237 { }
8238};
8239
8240/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8241static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8242{
a9fd4f3f 8243 struct alc_spec *spec = codec->spec;
c54728d8 8244
a9fd4f3f
TI
8245 spec->autocfg.hp_pins[0] = 0x14;
8246 spec->autocfg.speaker_pins[0] = 0x18;
8247 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8248}
8249
9d54f08b
TI
8250#define alc885_mb5_setup alc885_imac24_setup
8251#define alc885_macmini3_setup alc885_imac24_setup
8252
76e6f5a9
RH
8253/* Macbook Air 2,1 */
8254static void alc885_mba21_setup(struct hda_codec *codec)
8255{
8256 struct alc_spec *spec = codec->spec;
8257
8258 spec->autocfg.hp_pins[0] = 0x14;
8259 spec->autocfg.speaker_pins[0] = 0x18;
8260}
8261
8262
8263
4f5d1706 8264static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8265{
a9fd4f3f 8266 struct alc_spec *spec = codec->spec;
87350ad0 8267
a9fd4f3f
TI
8268 spec->autocfg.hp_pins[0] = 0x15;
8269 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8270}
8271
9d54f08b 8272static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8273{
9d54f08b 8274 struct alc_spec *spec = codec->spec;
4b7e1803 8275
9d54f08b 8276 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8277 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8278 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8279}
87350ad0 8280
272a527c
KY
8281static struct hda_verb alc882_targa_verbs[] = {
8282 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8283 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8284
8285 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8286 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8287
272a527c
KY
8288 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8289 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8290 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8291
8292 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8293 { } /* end */
8294};
8295
8296/* toggle speaker-output according to the hp-jack state */
8297static void alc882_targa_automute(struct hda_codec *codec)
8298{
a9fd4f3f
TI
8299 struct alc_spec *spec = codec->spec;
8300 alc_automute_amp(codec);
82beb8fd 8301 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8302 spec->jack_present ? 1 : 3);
8303}
8304
4f5d1706 8305static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8306{
8307 struct alc_spec *spec = codec->spec;
8308
8309 spec->autocfg.hp_pins[0] = 0x14;
8310 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8311}
8312
8313static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8314{
a9fd4f3f 8315 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8316 alc882_targa_automute(codec);
272a527c
KY
8317}
8318
8319static struct hda_verb alc882_asus_a7j_verbs[] = {
8320 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8321 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8322
8323 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8324 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8325 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8326
272a527c
KY
8327 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8328 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8329 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8330
8331 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8332 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8333 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8334 { } /* end */
8335};
8336
914759b7
TI
8337static struct hda_verb alc882_asus_a7m_verbs[] = {
8338 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8339 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8340
8341 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8342 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8343 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8344
914759b7
TI
8345 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8346 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8347 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8348
8349 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8350 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8351 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8352 { } /* end */
8353};
8354
9102cd1c
TD
8355static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8356{
8357 unsigned int gpiostate, gpiomask, gpiodir;
8358
8359 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8360 AC_VERB_GET_GPIO_DATA, 0);
8361
8362 if (!muted)
8363 gpiostate |= (1 << pin);
8364 else
8365 gpiostate &= ~(1 << pin);
8366
8367 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8368 AC_VERB_GET_GPIO_MASK, 0);
8369 gpiomask |= (1 << pin);
8370
8371 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8372 AC_VERB_GET_GPIO_DIRECTION, 0);
8373 gpiodir |= (1 << pin);
8374
8375
8376 snd_hda_codec_write(codec, codec->afg, 0,
8377 AC_VERB_SET_GPIO_MASK, gpiomask);
8378 snd_hda_codec_write(codec, codec->afg, 0,
8379 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8380
8381 msleep(1);
8382
8383 snd_hda_codec_write(codec, codec->afg, 0,
8384 AC_VERB_SET_GPIO_DATA, gpiostate);
8385}
8386
7debbe51
TI
8387/* set up GPIO at initialization */
8388static void alc885_macpro_init_hook(struct hda_codec *codec)
8389{
8390 alc882_gpio_mute(codec, 0, 0);
8391 alc882_gpio_mute(codec, 1, 0);
8392}
8393
8394/* set up GPIO and update auto-muting at initialization */
8395static void alc885_imac24_init_hook(struct hda_codec *codec)
8396{
8397 alc885_macpro_init_hook(codec);
4f5d1706 8398 alc_automute_amp(codec);
7debbe51
TI
8399}
8400
df694daa
KY
8401/*
8402 * generic initialization of ADC, input mixers and output mixers
8403 */
4953550a 8404static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8405 /*
8406 * Unmute ADC0-2 and set the default input to mic-in
8407 */
4953550a
TI
8408 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8409 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8410 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8411 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8412
4953550a
TI
8413 /*
8414 * Set up output mixers (0x0c - 0x0f)
8415 */
8416 /* set vol=0 to output mixers */
8417 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8418 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8420 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8421 /* set up input amps for analog loopback */
8422 /* Amp Indices: DAC = 0, mixer = 1 */
8423 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8424 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8425 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8426 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8427 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8428 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8429 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8430 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8431 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8432 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8433
4953550a
TI
8434 /* FIXME: use matrix-type input source selection */
8435 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8436 /* Input mixer2 */
88102f3f 8437 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8438 /* Input mixer3 */
88102f3f 8439 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8440 { }
9c7f852e
TI
8441};
8442
eb4c41d3
TS
8443/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8444static struct hda_verb alc889A_mb31_ch2_init[] = {
8445 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8446 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8447 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8448 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8449 { } /* end */
8450};
8451
8452/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8453static struct hda_verb alc889A_mb31_ch4_init[] = {
8454 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8455 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8456 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8457 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8458 { } /* end */
8459};
8460
8461/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8462static struct hda_verb alc889A_mb31_ch5_init[] = {
8463 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8464 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8465 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8466 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8467 { } /* end */
8468};
8469
8470/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8471static struct hda_verb alc889A_mb31_ch6_init[] = {
8472 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8473 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8474 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8475 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8476 { } /* end */
8477};
8478
8479static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8480 { 2, alc889A_mb31_ch2_init },
8481 { 4, alc889A_mb31_ch4_init },
8482 { 5, alc889A_mb31_ch5_init },
8483 { 6, alc889A_mb31_ch6_init },
8484};
8485
b373bdeb
AN
8486static struct hda_verb alc883_medion_eapd_verbs[] = {
8487 /* eanable EAPD on medion laptop */
8488 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8489 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8490 { }
8491};
8492
4953550a 8493#define alc883_base_mixer alc882_base_mixer
834be88d 8494
a8848bd6
AS
8495static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8496 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8497 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8498 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8499 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8500 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8501 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8502 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8503 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8504 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8505 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8506 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8507 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8508 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8509 { } /* end */
8510};
8511
0c4cc443 8512static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8513 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8514 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8515 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8516 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8517 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8518 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8519 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8520 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8521 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8522 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8523 { } /* end */
8524};
8525
fb97dc67
J
8526static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8527 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8528 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8529 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8530 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8531 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8532 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8533 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8534 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8535 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8536 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8537 { } /* end */
8538};
8539
9c7f852e
TI
8540static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8541 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8542 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8543 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8544 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8545 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8546 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8547 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8548 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8549 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8550 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8551 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8552 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8553 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8554 { } /* end */
8555};
df694daa 8556
9c7f852e
TI
8557static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8558 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8559 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8560 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8561 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8562 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8563 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8564 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8565 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8566 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8567 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8568 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8569 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8570 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8571 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8572 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8573 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8574 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8575 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8576 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8577 { } /* end */
8578};
8579
17bba1b7
J
8580static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8581 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8582 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8583 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8584 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8585 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8586 HDA_OUTPUT),
8587 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8588 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8589 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8590 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8591 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8592 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8593 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8594 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8595 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8596 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8597 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8598 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8599 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8600 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8601 { } /* end */
8602};
8603
87a8c370
JK
8604static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8605 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8606 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8607 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8608 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8609 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8610 HDA_OUTPUT),
8611 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8612 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8613 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8614 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8615 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8616 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8617 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8618 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8619 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8620 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
8621 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8622 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8623 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8624 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8625 { } /* end */
8626};
8627
d1d985f0 8628static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8629 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8630 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8631 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8632 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8633 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8634 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8635 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8636 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8637 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8638 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8639 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8640 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8641 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8642 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8643 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
8644 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8645 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8646 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8 8647 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
8648 { } /* end */
8649};
8650
c259249f 8651static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 8652 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8653 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8654 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8655 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8656 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8657 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8658 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8659 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8660 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8661 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8662 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8663 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8664 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8665 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8666 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8667 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8668 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 8669 { } /* end */
f12ab1e0 8670};
ccc656ce 8671
c259249f 8672static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 8673 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8674 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8675 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8676 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8677 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8678 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8679 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8680 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8681 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
8682 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8683 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8684 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 8685 { } /* end */
f12ab1e0 8686};
ccc656ce 8687
b99dba34
TI
8688static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8689 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8690 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8691 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8692 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8693 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8694 { } /* end */
8695};
8696
bc9f98a9
KY
8697static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8698 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8699 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
8700 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8701 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
8702 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8703 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8704 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8705 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 8706 { } /* end */
f12ab1e0 8707};
bc9f98a9 8708
272a527c
KY
8709static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8710 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8711 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8712 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8713 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8714 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8715 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8716 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
150b432f
DH
8717 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8718 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
8719 { } /* end */
8720};
8721
8722static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8723 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8724 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8725 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8726 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8727 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8728 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8729 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8730 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8731 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
272a527c 8732 { } /* end */
ea1fb29a 8733};
272a527c 8734
7ad7b218
MC
8735static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
8736 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8737 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8738 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8739 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
8740 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
8741 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
8742 { } /* end */
8743};
8744
8745static struct hda_verb alc883_medion_wim2160_verbs[] = {
8746 /* Unmute front mixer */
8747 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8748 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8749
8750 /* Set speaker pin to front mixer */
8751 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8752
8753 /* Init headphone pin */
8754 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8755 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8756 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8757 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8758
8759 { } /* end */
8760};
8761
8762/* toggle speaker-output according to the hp-jack state */
8763static void alc883_medion_wim2160_setup(struct hda_codec *codec)
8764{
8765 struct alc_spec *spec = codec->spec;
8766
8767 spec->autocfg.hp_pins[0] = 0x1a;
8768 spec->autocfg.speaker_pins[0] = 0x15;
8769}
8770
2880a867 8771static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
8772 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8773 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 8774 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
8775 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8776 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
8777 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8778 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8779 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 8780 { } /* end */
d1a991a6 8781};
2880a867 8782
d2fd4b09
TV
8783static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8784 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 8785 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
8786 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8787 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
8788 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8789 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8790 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8791 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8792 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8793 { } /* end */
8794};
8795
e2757d5e
KY
8796static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8797 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8798 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8799 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8800 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8801 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8802 0x0d, 1, 0x0, HDA_OUTPUT),
8803 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8804 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8805 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8806 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8807 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
8808 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8809 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8810 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8811 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8812 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8813 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8814 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8815 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8816 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8817 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
8818 { } /* end */
8819};
8820
eb4c41d3
TS
8821static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8822 /* Output mixers */
8823 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8824 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8825 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8826 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8827 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8828 HDA_OUTPUT),
8829 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8830 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8831 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8832 /* Output switches */
8833 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8834 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8835 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8836 /* Boost mixers */
8837 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8838 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8839 /* Input mixers */
8840 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8841 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8842 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8843 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8844 { } /* end */
8845};
8846
3e1647c5
GG
8847static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8848 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8849 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8850 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8851 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8852 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8853 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8854 { } /* end */
8855};
8856
e2757d5e
KY
8857static struct hda_bind_ctls alc883_bind_cap_vol = {
8858 .ops = &snd_hda_bind_vol,
8859 .values = {
8860 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8861 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8862 0
8863 },
8864};
8865
8866static struct hda_bind_ctls alc883_bind_cap_switch = {
8867 .ops = &snd_hda_bind_sw,
8868 .values = {
8869 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8870 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8871 0
8872 },
8873};
8874
8875static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8876 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8877 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8878 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8879 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8880 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8881 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4953550a
TI
8882 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8883 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8884 { } /* end */
8885};
df694daa 8886
4953550a
TI
8887static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8888 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8889 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8890 {
8891 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8892 /* .name = "Capture Source", */
8893 .name = "Input Source",
8894 .count = 1,
8895 .info = alc_mux_enum_info,
8896 .get = alc_mux_enum_get,
8897 .put = alc_mux_enum_put,
8898 },
8899 { } /* end */
8900};
9c7f852e 8901
4953550a
TI
8902static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8903 {
8904 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8905 .name = "Channel Mode",
8906 .info = alc_ch_mode_info,
8907 .get = alc_ch_mode_get,
8908 .put = alc_ch_mode_put,
8909 },
8910 { } /* end */
9c7f852e
TI
8911};
8912
a8848bd6 8913/* toggle speaker-output according to the hp-jack state */
4f5d1706 8914static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 8915{
a9fd4f3f 8916 struct alc_spec *spec = codec->spec;
a8848bd6 8917
a9fd4f3f
TI
8918 spec->autocfg.hp_pins[0] = 0x15;
8919 spec->autocfg.speaker_pins[0] = 0x14;
8920 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
8921}
8922
8923/* auto-toggle front mic */
8924/*
8925static void alc883_mitac_mic_automute(struct hda_codec *codec)
8926{
864f92be 8927 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
a8848bd6 8928
a8848bd6
AS
8929 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8930}
8931*/
8932
a8848bd6
AS
8933static struct hda_verb alc883_mitac_verbs[] = {
8934 /* HP */
8935 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8936 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8937 /* Subwoofer */
8938 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8939 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8940
8941 /* enable unsolicited event */
8942 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8943 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8944
8945 { } /* end */
8946};
8947
a65cc60f 8948static struct hda_verb alc883_clevo_m540r_verbs[] = {
8949 /* HP */
8950 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8951 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8952 /* Int speaker */
8953 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
8954
8955 /* enable unsolicited event */
8956 /*
8957 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8958 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8959 */
8960
8961 { } /* end */
8962};
8963
0c4cc443 8964static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
8965 /* HP */
8966 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8967 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8968 /* Int speaker */
8969 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8970 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8971
8972 /* enable unsolicited event */
8973 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 8974 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
8975
8976 { } /* end */
8977};
8978
fb97dc67
J
8979static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8980 /* HP */
8981 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8982 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8983 /* Subwoofer */
8984 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8985 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8986
8987 /* enable unsolicited event */
8988 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8989
8990 { } /* end */
8991};
8992
c259249f 8993static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
8994 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8995 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8996
8997 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8998 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8999
64a8be74
DH
9000/* Connect Line-Out side jack (SPDIF) to Side */
9001 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9002 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9003 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9004/* Connect Mic jack to CLFE */
9005 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9006 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9007 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9008/* Connect Line-in jack to Surround */
9009 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9010 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9011 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9012/* Connect HP out jack to Front */
9013 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9014 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9015 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9016
9017 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9018
9019 { } /* end */
9020};
9021
bc9f98a9
KY
9022static struct hda_verb alc883_lenovo_101e_verbs[] = {
9023 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9024 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9025 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9026 { } /* end */
9027};
9028
272a527c
KY
9029static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9030 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9031 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9032 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9033 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9034 { } /* end */
9035};
9036
9037static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9038 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9039 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9040 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9041 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9042 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9043 { } /* end */
9044};
9045
189609ae
KY
9046static struct hda_verb alc883_haier_w66_verbs[] = {
9047 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9048 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9049
9050 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9051
9052 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9053 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9054 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9055 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9056 { } /* end */
9057};
9058
e2757d5e
KY
9059static struct hda_verb alc888_lenovo_sky_verbs[] = {
9060 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9061 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9062 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9063 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9064 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9065 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9066 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9067 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9068 { } /* end */
9069};
9070
8718b700
HRK
9071static struct hda_verb alc888_6st_dell_verbs[] = {
9072 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9073 { }
9074};
9075
3e1647c5
GG
9076static struct hda_verb alc883_vaiott_verbs[] = {
9077 /* HP */
9078 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9079 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9080
9081 /* enable unsolicited event */
9082 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9083
9084 { } /* end */
9085};
9086
4f5d1706 9087static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9088{
a9fd4f3f 9089 struct alc_spec *spec = codec->spec;
8718b700 9090
a9fd4f3f
TI
9091 spec->autocfg.hp_pins[0] = 0x1b;
9092 spec->autocfg.speaker_pins[0] = 0x14;
9093 spec->autocfg.speaker_pins[1] = 0x16;
9094 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
9095}
9096
4723c022 9097static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9098 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9099 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9100 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9101 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9102 { } /* end */
5795b9e6
CM
9103};
9104
3ea0d7cf
HRK
9105/*
9106 * 2ch mode
9107 */
4723c022 9108static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9109 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9110 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9111 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9112 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9113 { } /* end */
8341de60
CM
9114};
9115
3ea0d7cf
HRK
9116/*
9117 * 4ch mode
9118 */
9119static struct hda_verb alc888_3st_hp_4ch_init[] = {
9120 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9121 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9122 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9123 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9124 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9125 { } /* end */
9126};
9127
9128/*
9129 * 6ch mode
9130 */
4723c022 9131static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9132 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9133 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9134 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9135 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9136 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9137 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9138 { } /* end */
8341de60
CM
9139};
9140
3ea0d7cf 9141static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9142 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9143 { 4, alc888_3st_hp_4ch_init },
4723c022 9144 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9145};
9146
272a527c
KY
9147/* toggle front-jack and RCA according to the hp-jack state */
9148static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9149{
864f92be 9150 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 9151
47fd830a
TI
9152 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9153 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9154 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9155 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
9156}
9157
9158/* toggle RCA according to the front-jack state */
9159static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9160{
864f92be 9161 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 9162
47fd830a
TI
9163 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9164 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 9165}
47fd830a 9166
272a527c
KY
9167static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9168 unsigned int res)
9169{
9170 if ((res >> 26) == ALC880_HP_EVENT)
9171 alc888_lenovo_ms7195_front_automute(codec);
9172 if ((res >> 26) == ALC880_FRONT_EVENT)
9173 alc888_lenovo_ms7195_rca_automute(codec);
9174}
9175
9176static struct hda_verb alc883_medion_md2_verbs[] = {
9177 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9178 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9179
9180 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9181
9182 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9183 { } /* end */
9184};
9185
9186/* toggle speaker-output according to the hp-jack state */
4f5d1706 9187static void alc883_medion_md2_setup(struct hda_codec *codec)
272a527c 9188{
a9fd4f3f 9189 struct alc_spec *spec = codec->spec;
272a527c 9190
a9fd4f3f
TI
9191 spec->autocfg.hp_pins[0] = 0x14;
9192 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
9193}
9194
ccc656ce 9195/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9196#define alc883_targa_init_hook alc882_targa_init_hook
9197#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9198
0c4cc443
HRK
9199static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
9200{
9201 unsigned int present;
9202
d56757ab 9203 present = snd_hda_jack_detect(codec, 0x18);
0c4cc443
HRK
9204 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
9205 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9206}
9207
4f5d1706 9208static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9209{
a9fd4f3f
TI
9210 struct alc_spec *spec = codec->spec;
9211
9212 spec->autocfg.hp_pins[0] = 0x15;
9213 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
9214}
9215
9216static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9217{
a9fd4f3f 9218 alc_automute_amp(codec);
0c4cc443
HRK
9219 alc883_clevo_m720_mic_automute(codec);
9220}
9221
9222static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9223 unsigned int res)
9224{
0c4cc443 9225 switch (res >> 26) {
0c4cc443
HRK
9226 case ALC880_MIC_EVENT:
9227 alc883_clevo_m720_mic_automute(codec);
9228 break;
a9fd4f3f
TI
9229 default:
9230 alc_automute_amp_unsol_event(codec, res);
9231 break;
0c4cc443 9232 }
368c7a95
J
9233}
9234
fb97dc67 9235/* toggle speaker-output according to the hp-jack state */
4f5d1706 9236static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9237{
a9fd4f3f 9238 struct alc_spec *spec = codec->spec;
fb97dc67 9239
a9fd4f3f
TI
9240 spec->autocfg.hp_pins[0] = 0x14;
9241 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9242}
9243
4f5d1706 9244static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9245{
a9fd4f3f 9246 struct alc_spec *spec = codec->spec;
189609ae 9247
a9fd4f3f
TI
9248 spec->autocfg.hp_pins[0] = 0x1b;
9249 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9250}
9251
bc9f98a9
KY
9252static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9253{
864f92be 9254 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9255
47fd830a
TI
9256 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9257 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9258}
9259
9260static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9261{
864f92be 9262 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9263
47fd830a
TI
9264 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9265 HDA_AMP_MUTE, bits);
9266 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9267 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9268}
9269
9270static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9271 unsigned int res)
9272{
9273 if ((res >> 26) == ALC880_HP_EVENT)
9274 alc883_lenovo_101e_all_automute(codec);
9275 if ((res >> 26) == ALC880_FRONT_EVENT)
9276 alc883_lenovo_101e_ispeaker_automute(codec);
9277}
9278
676a9b53 9279/* toggle speaker-output according to the hp-jack state */
4f5d1706 9280static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9281{
a9fd4f3f 9282 struct alc_spec *spec = codec->spec;
676a9b53 9283
a9fd4f3f
TI
9284 spec->autocfg.hp_pins[0] = 0x14;
9285 spec->autocfg.speaker_pins[0] = 0x15;
9286 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9287}
9288
d1a991a6
KY
9289static struct hda_verb alc883_acer_eapd_verbs[] = {
9290 /* HP Pin: output 0 (0x0c) */
9291 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9292 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9293 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9294 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9295 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9296 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9297 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9298 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9299 /* eanable EAPD on medion laptop */
9300 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9301 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9302 /* enable unsolicited event */
9303 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9304 { }
9305};
9306
fc86f954
DK
9307static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
9308 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9309 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9310 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9311 { } /* end */
9312};
9313
4f5d1706 9314static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9315{
a9fd4f3f 9316 struct alc_spec *spec = codec->spec;
5795b9e6 9317
a9fd4f3f
TI
9318 spec->autocfg.hp_pins[0] = 0x1b;
9319 spec->autocfg.speaker_pins[0] = 0x14;
9320 spec->autocfg.speaker_pins[1] = 0x15;
9321 spec->autocfg.speaker_pins[2] = 0x16;
9322 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9323}
9324
4f5d1706 9325static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9326{
a9fd4f3f 9327 struct alc_spec *spec = codec->spec;
e2757d5e 9328
a9fd4f3f
TI
9329 spec->autocfg.hp_pins[0] = 0x1b;
9330 spec->autocfg.speaker_pins[0] = 0x14;
9331 spec->autocfg.speaker_pins[1] = 0x15;
9332 spec->autocfg.speaker_pins[2] = 0x16;
9333 spec->autocfg.speaker_pins[3] = 0x17;
9334 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9335}
9336
4f5d1706 9337static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9338{
9339 struct alc_spec *spec = codec->spec;
9340
9341 spec->autocfg.hp_pins[0] = 0x15;
9342 spec->autocfg.speaker_pins[0] = 0x14;
9343 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9344}
9345
e2757d5e
KY
9346static struct hda_verb alc888_asus_m90v_verbs[] = {
9347 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9348 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9349 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9350 /* enable unsolicited event */
9351 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9352 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9353 { } /* end */
9354};
9355
4f5d1706 9356static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9357{
a9fd4f3f 9358 struct alc_spec *spec = codec->spec;
e2757d5e 9359
a9fd4f3f
TI
9360 spec->autocfg.hp_pins[0] = 0x1b;
9361 spec->autocfg.speaker_pins[0] = 0x14;
9362 spec->autocfg.speaker_pins[1] = 0x15;
9363 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9364 spec->ext_mic.pin = 0x18;
9365 spec->int_mic.pin = 0x19;
9366 spec->ext_mic.mux_idx = 0;
9367 spec->int_mic.mux_idx = 1;
9368 spec->auto_mic = 1;
e2757d5e
KY
9369}
9370
9371static struct hda_verb alc888_asus_eee1601_verbs[] = {
9372 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9373 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9374 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9375 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9376 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9377 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9378 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9379 /* enable unsolicited event */
9380 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9381 { } /* end */
9382};
9383
e2757d5e
KY
9384static void alc883_eee1601_inithook(struct hda_codec *codec)
9385{
a9fd4f3f
TI
9386 struct alc_spec *spec = codec->spec;
9387
9388 spec->autocfg.hp_pins[0] = 0x14;
9389 spec->autocfg.speaker_pins[0] = 0x1b;
9390 alc_automute_pin(codec);
e2757d5e
KY
9391}
9392
eb4c41d3
TS
9393static struct hda_verb alc889A_mb31_verbs[] = {
9394 /* Init rear pin (used as headphone output) */
9395 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9396 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9397 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9398 /* Init line pin (used as output in 4ch and 6ch mode) */
9399 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9400 /* Init line 2 pin (used as headphone out by default) */
9401 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9402 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9403 { } /* end */
9404};
9405
9406/* Mute speakers according to the headphone jack state */
9407static void alc889A_mb31_automute(struct hda_codec *codec)
9408{
9409 unsigned int present;
9410
9411 /* Mute only in 2ch or 4ch mode */
9412 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9413 == 0x00) {
864f92be 9414 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9415 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9416 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9417 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9418 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9419 }
9420}
9421
9422static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9423{
9424 if ((res >> 26) == ALC880_HP_EVENT)
9425 alc889A_mb31_automute(codec);
9426}
9427
4953550a 9428
cb53c626 9429#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9430#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9431#endif
9432
def319f9 9433/* pcm configuration: identical with ALC880 */
4953550a
TI
9434#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9435#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9436#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9437#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9438
9439static hda_nid_t alc883_slave_dig_outs[] = {
9440 ALC1200_DIGOUT_NID, 0,
9441};
9442
9443static hda_nid_t alc1200_slave_dig_outs[] = {
9444 ALC883_DIGOUT_NID, 0,
9445};
9c7f852e
TI
9446
9447/*
9448 * configuration and preset
9449 */
4953550a
TI
9450static const char *alc882_models[ALC882_MODEL_LAST] = {
9451 [ALC882_3ST_DIG] = "3stack-dig",
9452 [ALC882_6ST_DIG] = "6stack-dig",
9453 [ALC882_ARIMA] = "arima",
9454 [ALC882_W2JC] = "w2jc",
9455 [ALC882_TARGA] = "targa",
9456 [ALC882_ASUS_A7J] = "asus-a7j",
9457 [ALC882_ASUS_A7M] = "asus-a7m",
9458 [ALC885_MACPRO] = "macpro",
9459 [ALC885_MB5] = "mb5",
e458b1fa 9460 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9461 [ALC885_MBA21] = "mba21",
4953550a
TI
9462 [ALC885_MBP3] = "mbp3",
9463 [ALC885_IMAC24] = "imac24",
4b7e1803 9464 [ALC885_IMAC91] = "imac91",
4953550a 9465 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9466 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9467 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9468 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9469 [ALC883_TARGA_DIG] = "targa-dig",
9470 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9471 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9472 [ALC883_ACER] = "acer",
2880a867 9473 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9474 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9475 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9476 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9477 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9478 [ALC883_MEDION] = "medion",
272a527c 9479 [ALC883_MEDION_MD2] = "medion-md2",
7ad7b218 9480 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9481 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9482 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9483 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9484 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9485 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9486 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9487 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9488 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9489 [ALC883_MITAC] = "mitac",
a65cc60f 9490 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9491 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9492 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9493 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9494 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9495 [ALC889A_INTEL] = "intel-alc889a",
9496 [ALC889_INTEL] = "intel-x58",
3ab90935 9497 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9498 [ALC889A_MB31] = "mb31",
3e1647c5 9499 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9500 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9501};
9502
4953550a
TI
9503static struct snd_pci_quirk alc882_cfg_tbl[] = {
9504 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9505
ac3e3741 9506 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9507 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9508 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9509 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9510 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9511 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9512 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9513 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9514 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9515 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9516 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9517 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9518 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9519 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9520 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9521 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9522 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9523 ALC888_ACER_ASPIRE_6530G),
cc374c47 9524 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9525 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9526 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9527 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9528 /* default Acer -- disabled as it causes more problems.
9529 * model=auto should work fine now
9530 */
9531 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9532
5795b9e6 9533 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9534
febe3375 9535 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9536 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9537 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9538 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9539 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9540 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9541
9542 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9543 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9544 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9545 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9546 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9547 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9548 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9549 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9550 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9551 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9552 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9553
9554 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9555 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9556 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9557 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9558 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9559 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9560 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9561 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9562 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9563
6f3bf657 9564 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9565 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9566 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9567 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9568 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9569 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9570 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9571 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9572 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9573 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9574 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9575 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9576 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9577 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9578 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9579 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9580 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9581 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9582 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9583 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9584 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9585 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9586 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9587 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9588 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9589 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9590 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9591 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9592 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9593 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9594 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9595
ac3e3741 9596 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9597 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9598 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9599 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9600 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9601 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9602 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9603 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9604 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9605 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9606 ALC883_FUJITSU_PI2515),
bfb53037 9607 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9608 ALC888_FUJITSU_XA3530),
272a527c 9609 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9610 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9611 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9612 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9613 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
272a527c 9614 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
959973b9 9615 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9616 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9617 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9618
17bba1b7
J
9619 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9620 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9621 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9622 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9623 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9624 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9625 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9626
4953550a 9627 {}
f3cd3f5d
WF
9628};
9629
4953550a
TI
9630/* codec SSID table for Intel Mac */
9631static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9632 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9633 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9634 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9635 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9636 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9637 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9638 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 9639 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 9640 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 9641 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 9642 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
9643 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9644 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9645 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9646 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9647 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 9648 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
9649 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9650 * so apparently no perfect solution yet
4953550a
TI
9651 */
9652 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9653 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9654 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9655 {} /* terminator */
b25c9da1
WF
9656};
9657
4953550a
TI
9658static struct alc_config_preset alc882_presets[] = {
9659 [ALC882_3ST_DIG] = {
9660 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9661 .init_verbs = { alc882_base_init_verbs,
9662 alc882_adc1_init_verbs },
4953550a
TI
9663 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9664 .dac_nids = alc882_dac_nids,
9665 .dig_out_nid = ALC882_DIGOUT_NID,
9666 .dig_in_nid = ALC882_DIGIN_NID,
9667 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9668 .channel_mode = alc882_ch_modes,
9669 .need_dac_fix = 1,
9670 .input_mux = &alc882_capture_source,
9671 },
9672 [ALC882_6ST_DIG] = {
9673 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9674 .init_verbs = { alc882_base_init_verbs,
9675 alc882_adc1_init_verbs },
4953550a
TI
9676 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9677 .dac_nids = alc882_dac_nids,
9678 .dig_out_nid = ALC882_DIGOUT_NID,
9679 .dig_in_nid = ALC882_DIGIN_NID,
9680 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9681 .channel_mode = alc882_sixstack_modes,
9682 .input_mux = &alc882_capture_source,
9683 },
9684 [ALC882_ARIMA] = {
9685 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9686 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9687 alc882_eapd_verbs },
4953550a
TI
9688 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9689 .dac_nids = alc882_dac_nids,
9690 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9691 .channel_mode = alc882_sixstack_modes,
9692 .input_mux = &alc882_capture_source,
9693 },
9694 [ALC882_W2JC] = {
9695 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9696 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9697 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
9698 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9699 .dac_nids = alc882_dac_nids,
9700 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9701 .channel_mode = alc880_threestack_modes,
9702 .need_dac_fix = 1,
9703 .input_mux = &alc882_capture_source,
9704 .dig_out_nid = ALC882_DIGOUT_NID,
9705 },
76e6f5a9
RH
9706 [ALC885_MBA21] = {
9707 .mixers = { alc885_mba21_mixer },
9708 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9709 .num_dacs = 2,
9710 .dac_nids = alc882_dac_nids,
9711 .channel_mode = alc885_mba21_ch_modes,
9712 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9713 .input_mux = &alc882_capture_source,
9714 .unsol_event = alc_automute_amp_unsol_event,
9715 .setup = alc885_mba21_setup,
9716 .init_hook = alc_automute_amp,
9717 },
4953550a
TI
9718 [ALC885_MBP3] = {
9719 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9720 .init_verbs = { alc885_mbp3_init_verbs,
9721 alc880_gpio1_init_verbs },
be0ae923 9722 .num_dacs = 2,
4953550a 9723 .dac_nids = alc882_dac_nids,
be0ae923
TI
9724 .hp_nid = 0x04,
9725 .channel_mode = alc885_mbp_4ch_modes,
9726 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
9727 .input_mux = &alc882_capture_source,
9728 .dig_out_nid = ALC882_DIGOUT_NID,
9729 .dig_in_nid = ALC882_DIGIN_NID,
9730 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9731 .setup = alc885_mbp3_setup,
9732 .init_hook = alc_automute_amp,
4953550a
TI
9733 },
9734 [ALC885_MB5] = {
9735 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
9736 .init_verbs = { alc885_mb5_init_verbs,
9737 alc880_gpio1_init_verbs },
9738 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9739 .dac_nids = alc882_dac_nids,
9740 .channel_mode = alc885_mb5_6ch_modes,
9741 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
9742 .input_mux = &mb5_capture_source,
9743 .dig_out_nid = ALC882_DIGOUT_NID,
9744 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9745 .unsol_event = alc_automute_amp_unsol_event,
9746 .setup = alc885_mb5_setup,
9747 .init_hook = alc_automute_amp,
4953550a 9748 },
e458b1fa
LY
9749 [ALC885_MACMINI3] = {
9750 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9751 .init_verbs = { alc885_macmini3_init_verbs,
9752 alc880_gpio1_init_verbs },
9753 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9754 .dac_nids = alc882_dac_nids,
9755 .channel_mode = alc885_macmini3_6ch_modes,
9756 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9757 .input_mux = &macmini3_capture_source,
9758 .dig_out_nid = ALC882_DIGOUT_NID,
9759 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9760 .unsol_event = alc_automute_amp_unsol_event,
9761 .setup = alc885_macmini3_setup,
9762 .init_hook = alc_automute_amp,
e458b1fa 9763 },
4953550a
TI
9764 [ALC885_MACPRO] = {
9765 .mixers = { alc882_macpro_mixer },
9766 .init_verbs = { alc882_macpro_init_verbs },
9767 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9768 .dac_nids = alc882_dac_nids,
9769 .dig_out_nid = ALC882_DIGOUT_NID,
9770 .dig_in_nid = ALC882_DIGIN_NID,
9771 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9772 .channel_mode = alc882_ch_modes,
9773 .input_mux = &alc882_capture_source,
9774 .init_hook = alc885_macpro_init_hook,
9775 },
9776 [ALC885_IMAC24] = {
9777 .mixers = { alc885_imac24_mixer },
9778 .init_verbs = { alc885_imac24_init_verbs },
9779 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9780 .dac_nids = alc882_dac_nids,
9781 .dig_out_nid = ALC882_DIGOUT_NID,
9782 .dig_in_nid = ALC882_DIGIN_NID,
9783 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9784 .channel_mode = alc882_ch_modes,
9785 .input_mux = &alc882_capture_source,
9786 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 9787 .setup = alc885_imac24_setup,
4953550a
TI
9788 .init_hook = alc885_imac24_init_hook,
9789 },
4b7e1803 9790 [ALC885_IMAC91] = {
b7cccc52 9791 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
9792 .init_verbs = { alc885_imac91_init_verbs,
9793 alc880_gpio1_init_verbs },
9794 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9795 .dac_nids = alc882_dac_nids,
b7cccc52
JM
9796 .channel_mode = alc885_mba21_ch_modes,
9797 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9798 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
9799 .dig_out_nid = ALC882_DIGOUT_NID,
9800 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9801 .unsol_event = alc_automute_amp_unsol_event,
9802 .setup = alc885_imac91_setup,
9803 .init_hook = alc_automute_amp,
4b7e1803 9804 },
4953550a
TI
9805 [ALC882_TARGA] = {
9806 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 9807 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 9808 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
9809 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9810 .dac_nids = alc882_dac_nids,
9811 .dig_out_nid = ALC882_DIGOUT_NID,
9812 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9813 .adc_nids = alc882_adc_nids,
9814 .capsrc_nids = alc882_capsrc_nids,
9815 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9816 .channel_mode = alc882_3ST_6ch_modes,
9817 .need_dac_fix = 1,
9818 .input_mux = &alc882_capture_source,
9819 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
9820 .setup = alc882_targa_setup,
9821 .init_hook = alc882_targa_automute,
4953550a
TI
9822 },
9823 [ALC882_ASUS_A7J] = {
9824 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9825 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9826 alc882_asus_a7j_verbs},
4953550a
TI
9827 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9828 .dac_nids = alc882_dac_nids,
9829 .dig_out_nid = ALC882_DIGOUT_NID,
9830 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9831 .adc_nids = alc882_adc_nids,
9832 .capsrc_nids = alc882_capsrc_nids,
9833 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9834 .channel_mode = alc882_3ST_6ch_modes,
9835 .need_dac_fix = 1,
9836 .input_mux = &alc882_capture_source,
9837 },
9838 [ALC882_ASUS_A7M] = {
9839 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9840 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9841 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
9842 alc882_asus_a7m_verbs },
9843 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9844 .dac_nids = alc882_dac_nids,
9845 .dig_out_nid = ALC882_DIGOUT_NID,
9846 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9847 .channel_mode = alc880_threestack_modes,
9848 .need_dac_fix = 1,
9849 .input_mux = &alc882_capture_source,
9850 },
9c7f852e
TI
9851 [ALC883_3ST_2ch_DIG] = {
9852 .mixers = { alc883_3ST_2ch_mixer },
9853 .init_verbs = { alc883_init_verbs },
9854 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9855 .dac_nids = alc883_dac_nids,
9856 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9857 .dig_in_nid = ALC883_DIGIN_NID,
9858 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9859 .channel_mode = alc883_3ST_2ch_modes,
9860 .input_mux = &alc883_capture_source,
9861 },
9862 [ALC883_3ST_6ch_DIG] = {
9863 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9864 .init_verbs = { alc883_init_verbs },
9865 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9866 .dac_nids = alc883_dac_nids,
9867 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9868 .dig_in_nid = ALC883_DIGIN_NID,
9869 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9870 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9871 .need_dac_fix = 1,
9c7f852e 9872 .input_mux = &alc883_capture_source,
f12ab1e0 9873 },
9c7f852e
TI
9874 [ALC883_3ST_6ch] = {
9875 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9876 .init_verbs = { alc883_init_verbs },
9877 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9878 .dac_nids = alc883_dac_nids,
9c7f852e
TI
9879 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9880 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9881 .need_dac_fix = 1,
9c7f852e 9882 .input_mux = &alc883_capture_source,
f12ab1e0 9883 },
17bba1b7
J
9884 [ALC883_3ST_6ch_INTEL] = {
9885 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
9886 .init_verbs = { alc883_init_verbs },
9887 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9888 .dac_nids = alc883_dac_nids,
9889 .dig_out_nid = ALC883_DIGOUT_NID,
9890 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 9891 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
9892 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
9893 .channel_mode = alc883_3ST_6ch_intel_modes,
9894 .need_dac_fix = 1,
9895 .input_mux = &alc883_3stack_6ch_intel,
9896 },
87a8c370
JK
9897 [ALC889A_INTEL] = {
9898 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
9899 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
9900 alc_hp15_unsol_verbs },
87a8c370
JK
9901 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9902 .dac_nids = alc883_dac_nids,
9903 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9904 .adc_nids = alc889_adc_nids,
9905 .dig_out_nid = ALC883_DIGOUT_NID,
9906 .dig_in_nid = ALC883_DIGIN_NID,
9907 .slave_dig_outs = alc883_slave_dig_outs,
9908 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9909 .channel_mode = alc889_8ch_intel_modes,
9910 .capsrc_nids = alc889_capsrc_nids,
9911 .input_mux = &alc889_capture_source,
4f5d1706
TI
9912 .setup = alc889_automute_setup,
9913 .init_hook = alc_automute_amp,
6732bd0d 9914 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
9915 .need_dac_fix = 1,
9916 },
9917 [ALC889_INTEL] = {
9918 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9919 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 9920 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
9921 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9922 .dac_nids = alc883_dac_nids,
9923 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9924 .adc_nids = alc889_adc_nids,
9925 .dig_out_nid = ALC883_DIGOUT_NID,
9926 .dig_in_nid = ALC883_DIGIN_NID,
9927 .slave_dig_outs = alc883_slave_dig_outs,
9928 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9929 .channel_mode = alc889_8ch_intel_modes,
9930 .capsrc_nids = alc889_capsrc_nids,
9931 .input_mux = &alc889_capture_source,
4f5d1706 9932 .setup = alc889_automute_setup,
6732bd0d
WF
9933 .init_hook = alc889_intel_init_hook,
9934 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
9935 .need_dac_fix = 1,
9936 },
9c7f852e
TI
9937 [ALC883_6ST_DIG] = {
9938 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9939 .init_verbs = { alc883_init_verbs },
9940 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9941 .dac_nids = alc883_dac_nids,
9942 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9943 .dig_in_nid = ALC883_DIGIN_NID,
9944 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9945 .channel_mode = alc883_sixstack_modes,
9946 .input_mux = &alc883_capture_source,
9947 },
ccc656ce 9948 [ALC883_TARGA_DIG] = {
c259249f 9949 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
9950 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9951 alc883_targa_verbs},
ccc656ce
KY
9952 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9953 .dac_nids = alc883_dac_nids,
9954 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9955 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9956 .channel_mode = alc883_3ST_6ch_modes,
9957 .need_dac_fix = 1,
9958 .input_mux = &alc883_capture_source,
c259249f 9959 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9960 .setup = alc882_targa_setup,
9961 .init_hook = alc882_targa_automute,
ccc656ce
KY
9962 },
9963 [ALC883_TARGA_2ch_DIG] = {
c259249f 9964 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
9965 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9966 alc883_targa_verbs},
ccc656ce
KY
9967 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9968 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9969 .adc_nids = alc883_adc_nids_alt,
9970 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 9971 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 9972 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9973 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9974 .channel_mode = alc883_3ST_2ch_modes,
9975 .input_mux = &alc883_capture_source,
c259249f 9976 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9977 .setup = alc882_targa_setup,
9978 .init_hook = alc882_targa_automute,
ccc656ce 9979 },
64a8be74 9980 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
9981 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
9982 alc883_chmode_mixer },
64a8be74 9983 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 9984 alc883_targa_verbs },
64a8be74
DH
9985 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9986 .dac_nids = alc883_dac_nids,
9987 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9988 .adc_nids = alc883_adc_nids_rev,
9989 .capsrc_nids = alc883_capsrc_nids_rev,
9990 .dig_out_nid = ALC883_DIGOUT_NID,
9991 .dig_in_nid = ALC883_DIGIN_NID,
9992 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
9993 .channel_mode = alc883_4ST_8ch_modes,
9994 .need_dac_fix = 1,
9995 .input_mux = &alc883_capture_source,
c259249f 9996 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9997 .setup = alc882_targa_setup,
9998 .init_hook = alc882_targa_automute,
64a8be74 9999 },
bab282b9 10000 [ALC883_ACER] = {
676a9b53 10001 .mixers = { alc883_base_mixer },
bab282b9
VA
10002 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10003 * and the headphone jack. Turn this on and rely on the
10004 * standard mute methods whenever the user wants to turn
10005 * these outputs off.
10006 */
10007 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10008 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10009 .dac_nids = alc883_dac_nids,
bab282b9
VA
10010 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10011 .channel_mode = alc883_3ST_2ch_modes,
10012 .input_mux = &alc883_capture_source,
10013 },
2880a867 10014 [ALC883_ACER_ASPIRE] = {
676a9b53 10015 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10016 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10017 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10018 .dac_nids = alc883_dac_nids,
10019 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10020 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10021 .channel_mode = alc883_3ST_2ch_modes,
10022 .input_mux = &alc883_capture_source,
a9fd4f3f 10023 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10024 .setup = alc883_acer_aspire_setup,
10025 .init_hook = alc_automute_amp,
d1a991a6 10026 },
5b2d1eca 10027 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 10028 .mixers = { alc888_base_mixer,
5b2d1eca
VP
10029 alc883_chmode_mixer },
10030 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10031 alc888_acer_aspire_4930g_verbs },
10032 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10033 .dac_nids = alc883_dac_nids,
10034 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10035 .adc_nids = alc883_adc_nids_rev,
10036 .capsrc_nids = alc883_capsrc_nids_rev,
10037 .dig_out_nid = ALC883_DIGOUT_NID,
10038 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10039 .channel_mode = alc883_3ST_6ch_modes,
10040 .need_dac_fix = 1,
973b8cb0 10041 .const_channel_count = 6,
5b2d1eca 10042 .num_mux_defs =
ef8ef5fb
VP
10043 ARRAY_SIZE(alc888_2_capture_sources),
10044 .input_mux = alc888_2_capture_sources,
d2fd4b09 10045 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10046 .setup = alc888_acer_aspire_4930g_setup,
10047 .init_hook = alc_automute_amp,
d2fd4b09
TV
10048 },
10049 [ALC888_ACER_ASPIRE_6530G] = {
10050 .mixers = { alc888_acer_aspire_6530_mixer },
10051 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10052 alc888_acer_aspire_6530g_verbs },
10053 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10054 .dac_nids = alc883_dac_nids,
10055 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10056 .adc_nids = alc883_adc_nids_rev,
10057 .capsrc_nids = alc883_capsrc_nids_rev,
10058 .dig_out_nid = ALC883_DIGOUT_NID,
10059 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10060 .channel_mode = alc883_3ST_2ch_modes,
10061 .num_mux_defs =
10062 ARRAY_SIZE(alc888_2_capture_sources),
10063 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 10064 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10065 .setup = alc888_acer_aspire_6530g_setup,
10066 .init_hook = alc_automute_amp,
5b2d1eca 10067 },
3b315d70 10068 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10069 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10070 alc883_chmode_mixer },
10071 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10072 alc889_acer_aspire_8930g_verbs,
10073 alc889_eapd_verbs},
3b315d70
HM
10074 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10075 .dac_nids = alc883_dac_nids,
018df418
HM
10076 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10077 .adc_nids = alc889_adc_nids,
10078 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10079 .dig_out_nid = ALC883_DIGOUT_NID,
10080 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10081 .channel_mode = alc883_3ST_6ch_modes,
10082 .need_dac_fix = 1,
10083 .const_channel_count = 6,
10084 .num_mux_defs =
018df418
HM
10085 ARRAY_SIZE(alc889_capture_sources),
10086 .input_mux = alc889_capture_sources,
3b315d70 10087 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10088 .setup = alc889_acer_aspire_8930g_setup,
10089 .init_hook = alc_automute_amp,
f5de24b0 10090#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10091 .power_hook = alc_power_eapd,
f5de24b0 10092#endif
3b315d70 10093 },
fc86f954
DK
10094 [ALC888_ACER_ASPIRE_7730G] = {
10095 .mixers = { alc883_3ST_6ch_mixer,
10096 alc883_chmode_mixer },
10097 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10098 alc888_acer_aspire_7730G_verbs },
10099 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10100 .dac_nids = alc883_dac_nids,
10101 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10102 .adc_nids = alc883_adc_nids_rev,
10103 .capsrc_nids = alc883_capsrc_nids_rev,
10104 .dig_out_nid = ALC883_DIGOUT_NID,
10105 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10106 .channel_mode = alc883_3ST_6ch_modes,
10107 .need_dac_fix = 1,
10108 .const_channel_count = 6,
10109 .input_mux = &alc883_capture_source,
10110 .unsol_event = alc_automute_amp_unsol_event,
10111 .setup = alc888_acer_aspire_6530g_setup,
10112 .init_hook = alc_automute_amp,
10113 },
c07584c8
TD
10114 [ALC883_MEDION] = {
10115 .mixers = { alc883_fivestack_mixer,
10116 alc883_chmode_mixer },
10117 .init_verbs = { alc883_init_verbs,
b373bdeb 10118 alc883_medion_eapd_verbs },
c07584c8
TD
10119 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10120 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10121 .adc_nids = alc883_adc_nids_alt,
10122 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10123 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10124 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10125 .channel_mode = alc883_sixstack_modes,
10126 .input_mux = &alc883_capture_source,
b373bdeb 10127 },
272a527c
KY
10128 [ALC883_MEDION_MD2] = {
10129 .mixers = { alc883_medion_md2_mixer},
10130 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
10131 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10132 .dac_nids = alc883_dac_nids,
10133 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10134 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10135 .channel_mode = alc883_3ST_2ch_modes,
10136 .input_mux = &alc883_capture_source,
a9fd4f3f 10137 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10138 .setup = alc883_medion_md2_setup,
10139 .init_hook = alc_automute_amp,
ea1fb29a 10140 },
7ad7b218
MC
10141 [ALC883_MEDION_WIM2160] = {
10142 .mixers = { alc883_medion_wim2160_mixer },
10143 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10144 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10145 .dac_nids = alc883_dac_nids,
10146 .dig_out_nid = ALC883_DIGOUT_NID,
10147 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10148 .adc_nids = alc883_adc_nids,
10149 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10150 .channel_mode = alc883_3ST_2ch_modes,
10151 .input_mux = &alc883_capture_source,
10152 .unsol_event = alc_automute_amp_unsol_event,
10153 .setup = alc883_medion_wim2160_setup,
10154 .init_hook = alc_automute_amp,
10155 },
b373bdeb 10156 [ALC883_LAPTOP_EAPD] = {
676a9b53 10157 .mixers = { alc883_base_mixer },
b373bdeb
AN
10158 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10159 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10160 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10161 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10162 .channel_mode = alc883_3ST_2ch_modes,
10163 .input_mux = &alc883_capture_source,
10164 },
a65cc60f 10165 [ALC883_CLEVO_M540R] = {
10166 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10167 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10168 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10169 .dac_nids = alc883_dac_nids,
10170 .dig_out_nid = ALC883_DIGOUT_NID,
10171 .dig_in_nid = ALC883_DIGIN_NID,
10172 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10173 .channel_mode = alc883_3ST_6ch_clevo_modes,
10174 .need_dac_fix = 1,
10175 .input_mux = &alc883_capture_source,
10176 /* This machine has the hardware HP auto-muting, thus
10177 * we need no software mute via unsol event
10178 */
10179 },
0c4cc443
HRK
10180 [ALC883_CLEVO_M720] = {
10181 .mixers = { alc883_clevo_m720_mixer },
10182 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10183 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10184 .dac_nids = alc883_dac_nids,
10185 .dig_out_nid = ALC883_DIGOUT_NID,
10186 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10187 .channel_mode = alc883_3ST_2ch_modes,
10188 .input_mux = &alc883_capture_source,
0c4cc443 10189 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10190 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10191 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10192 },
bc9f98a9
KY
10193 [ALC883_LENOVO_101E_2ch] = {
10194 .mixers = { alc883_lenovo_101e_2ch_mixer},
10195 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10196 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10197 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10198 .adc_nids = alc883_adc_nids_alt,
10199 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10200 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10201 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10202 .channel_mode = alc883_3ST_2ch_modes,
10203 .input_mux = &alc883_lenovo_101e_capture_source,
10204 .unsol_event = alc883_lenovo_101e_unsol_event,
10205 .init_hook = alc883_lenovo_101e_all_automute,
10206 },
272a527c
KY
10207 [ALC883_LENOVO_NB0763] = {
10208 .mixers = { alc883_lenovo_nb0763_mixer },
10209 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10210 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10211 .dac_nids = alc883_dac_nids,
272a527c
KY
10212 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10213 .channel_mode = alc883_3ST_2ch_modes,
10214 .need_dac_fix = 1,
10215 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 10216 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10217 .setup = alc883_medion_md2_setup,
10218 .init_hook = alc_automute_amp,
272a527c
KY
10219 },
10220 [ALC888_LENOVO_MS7195_DIG] = {
10221 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10222 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10223 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10224 .dac_nids = alc883_dac_nids,
10225 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10226 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10227 .channel_mode = alc883_3ST_6ch_modes,
10228 .need_dac_fix = 1,
10229 .input_mux = &alc883_capture_source,
10230 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10231 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
10232 },
10233 [ALC883_HAIER_W66] = {
c259249f 10234 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10235 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10236 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10237 .dac_nids = alc883_dac_nids,
10238 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10239 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10240 .channel_mode = alc883_3ST_2ch_modes,
10241 .input_mux = &alc883_capture_source,
a9fd4f3f 10242 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10243 .setup = alc883_haier_w66_setup,
10244 .init_hook = alc_automute_amp,
eea6419e 10245 },
4723c022 10246 [ALC888_3ST_HP] = {
eea6419e 10247 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10248 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10249 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10250 .dac_nids = alc883_dac_nids,
4723c022
CM
10251 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10252 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10253 .need_dac_fix = 1,
10254 .input_mux = &alc883_capture_source,
a9fd4f3f 10255 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10256 .setup = alc888_3st_hp_setup,
10257 .init_hook = alc_automute_amp,
8341de60 10258 },
5795b9e6 10259 [ALC888_6ST_DELL] = {
f24dbdc6 10260 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10261 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10262 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10263 .dac_nids = alc883_dac_nids,
10264 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10265 .dig_in_nid = ALC883_DIGIN_NID,
10266 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10267 .channel_mode = alc883_sixstack_modes,
10268 .input_mux = &alc883_capture_source,
a9fd4f3f 10269 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10270 .setup = alc888_6st_dell_setup,
10271 .init_hook = alc_automute_amp,
5795b9e6 10272 },
a8848bd6
AS
10273 [ALC883_MITAC] = {
10274 .mixers = { alc883_mitac_mixer },
10275 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10276 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10277 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10278 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10279 .channel_mode = alc883_3ST_2ch_modes,
10280 .input_mux = &alc883_capture_source,
a9fd4f3f 10281 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10282 .setup = alc883_mitac_setup,
10283 .init_hook = alc_automute_amp,
a8848bd6 10284 },
fb97dc67
J
10285 [ALC883_FUJITSU_PI2515] = {
10286 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10287 .init_verbs = { alc883_init_verbs,
10288 alc883_2ch_fujitsu_pi2515_verbs},
10289 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10290 .dac_nids = alc883_dac_nids,
10291 .dig_out_nid = ALC883_DIGOUT_NID,
10292 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10293 .channel_mode = alc883_3ST_2ch_modes,
10294 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10295 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10296 .setup = alc883_2ch_fujitsu_pi2515_setup,
10297 .init_hook = alc_automute_amp,
fb97dc67 10298 },
ef8ef5fb
VP
10299 [ALC888_FUJITSU_XA3530] = {
10300 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10301 .init_verbs = { alc883_init_verbs,
10302 alc888_fujitsu_xa3530_verbs },
10303 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10304 .dac_nids = alc883_dac_nids,
10305 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10306 .adc_nids = alc883_adc_nids_rev,
10307 .capsrc_nids = alc883_capsrc_nids_rev,
10308 .dig_out_nid = ALC883_DIGOUT_NID,
10309 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10310 .channel_mode = alc888_4ST_8ch_intel_modes,
10311 .num_mux_defs =
10312 ARRAY_SIZE(alc888_2_capture_sources),
10313 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10314 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10315 .setup = alc888_fujitsu_xa3530_setup,
10316 .init_hook = alc_automute_amp,
ef8ef5fb 10317 },
e2757d5e
KY
10318 [ALC888_LENOVO_SKY] = {
10319 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10320 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10321 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10322 .dac_nids = alc883_dac_nids,
10323 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10324 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10325 .channel_mode = alc883_sixstack_modes,
10326 .need_dac_fix = 1,
10327 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10328 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10329 .setup = alc888_lenovo_sky_setup,
10330 .init_hook = alc_automute_amp,
e2757d5e
KY
10331 },
10332 [ALC888_ASUS_M90V] = {
10333 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10334 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10335 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10336 .dac_nids = alc883_dac_nids,
10337 .dig_out_nid = ALC883_DIGOUT_NID,
10338 .dig_in_nid = ALC883_DIGIN_NID,
10339 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10340 .channel_mode = alc883_3ST_6ch_modes,
10341 .need_dac_fix = 1,
10342 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10343 .unsol_event = alc_sku_unsol_event,
10344 .setup = alc883_mode2_setup,
10345 .init_hook = alc_inithook,
e2757d5e
KY
10346 },
10347 [ALC888_ASUS_EEE1601] = {
10348 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10349 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10350 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10351 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10352 .dac_nids = alc883_dac_nids,
10353 .dig_out_nid = ALC883_DIGOUT_NID,
10354 .dig_in_nid = ALC883_DIGIN_NID,
10355 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10356 .channel_mode = alc883_3ST_2ch_modes,
10357 .need_dac_fix = 1,
10358 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10359 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10360 .init_hook = alc883_eee1601_inithook,
10361 },
3ab90935
WF
10362 [ALC1200_ASUS_P5Q] = {
10363 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10364 .init_verbs = { alc883_init_verbs },
10365 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10366 .dac_nids = alc883_dac_nids,
10367 .dig_out_nid = ALC1200_DIGOUT_NID,
10368 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10369 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10370 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10371 .channel_mode = alc883_sixstack_modes,
10372 .input_mux = &alc883_capture_source,
10373 },
eb4c41d3
TS
10374 [ALC889A_MB31] = {
10375 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10376 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10377 alc880_gpio1_init_verbs },
10378 .adc_nids = alc883_adc_nids,
10379 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10380 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10381 .dac_nids = alc883_dac_nids,
10382 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10383 .channel_mode = alc889A_mb31_6ch_modes,
10384 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10385 .input_mux = &alc889A_mb31_capture_source,
10386 .dig_out_nid = ALC883_DIGOUT_NID,
10387 .unsol_event = alc889A_mb31_unsol_event,
10388 .init_hook = alc889A_mb31_automute,
10389 },
3e1647c5
GG
10390 [ALC883_SONY_VAIO_TT] = {
10391 .mixers = { alc883_vaiott_mixer },
10392 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10393 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10394 .dac_nids = alc883_dac_nids,
10395 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10396 .channel_mode = alc883_3ST_2ch_modes,
10397 .input_mux = &alc883_capture_source,
10398 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10399 .setup = alc883_vaiott_setup,
10400 .init_hook = alc_automute_amp,
3e1647c5 10401 },
9c7f852e
TI
10402};
10403
10404
4953550a
TI
10405/*
10406 * Pin config fixes
10407 */
10408enum {
10409 PINFIX_ABIT_AW9D_MAX
10410};
10411
10412static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
10413 { 0x15, 0x01080104 }, /* side */
10414 { 0x16, 0x01011012 }, /* rear */
10415 { 0x17, 0x01016011 }, /* clfe */
10416 { }
10417};
10418
f8f25ba3
TI
10419static const struct alc_fixup alc882_fixups[] = {
10420 [PINFIX_ABIT_AW9D_MAX] = {
10421 .pins = alc882_abit_aw9d_pinfix
10422 },
4953550a
TI
10423};
10424
f8f25ba3 10425static struct snd_pci_quirk alc882_fixup_tbl[] = {
4953550a
TI
10426 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10427 {}
10428};
10429
9c7f852e
TI
10430/*
10431 * BIOS auto configuration
10432 */
05f5f477
TI
10433static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10434 const struct auto_pin_cfg *cfg)
10435{
10436 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10437}
10438
4953550a 10439static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10440 hda_nid_t nid, int pin_type,
489008cd 10441 hda_nid_t dac)
9c7f852e 10442{
f12ab1e0
TI
10443 int idx;
10444
489008cd 10445 /* set as output */
f6c7e546 10446 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10447
10448 if (dac == 0x25)
9c7f852e 10449 idx = 4;
489008cd
TI
10450 else if (dac >= 0x02 && dac <= 0x05)
10451 idx = dac - 2;
f9700d5a 10452 else
489008cd 10453 return;
9c7f852e 10454 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
10455}
10456
4953550a 10457static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10458{
10459 struct alc_spec *spec = codec->spec;
10460 int i;
10461
10462 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10463 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10464 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10465 if (nid)
4953550a 10466 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 10467 spec->multiout.dac_nids[i]);
9c7f852e
TI
10468 }
10469}
10470
4953550a 10471static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10472{
10473 struct alc_spec *spec = codec->spec;
489008cd 10474 hda_nid_t pin, dac;
9c7f852e 10475
eb06ed8f 10476 pin = spec->autocfg.hp_pins[0];
489008cd
TI
10477 if (pin) {
10478 dac = spec->multiout.hp_nid;
10479 if (!dac)
10480 dac = spec->multiout.dac_nids[0]; /* to front */
10481 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10482 }
f6c7e546 10483 pin = spec->autocfg.speaker_pins[0];
489008cd
TI
10484 if (pin) {
10485 dac = spec->multiout.extra_out_nid[0];
10486 if (!dac)
10487 dac = spec->multiout.dac_nids[0]; /* to front */
10488 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10489 }
9c7f852e
TI
10490}
10491
4953550a 10492static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10493{
10494 struct alc_spec *spec = codec->spec;
10495 int i;
10496
10497 for (i = 0; i < AUTO_PIN_LAST; i++) {
10498 hda_nid_t nid = spec->autocfg.input_pins[i];
4953550a
TI
10499 if (!nid)
10500 continue;
0d971c9f 10501 alc_set_input_pin(codec, nid, i);
4953550a
TI
10502 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10503 snd_hda_codec_write(codec, nid, 0,
10504 AC_VERB_SET_AMP_GAIN_MUTE,
10505 AMP_OUT_MUTE);
10506 }
10507}
10508
10509static void alc882_auto_init_input_src(struct hda_codec *codec)
10510{
10511 struct alc_spec *spec = codec->spec;
10512 int c;
10513
10514 for (c = 0; c < spec->num_adc_nids; c++) {
10515 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10516 hda_nid_t nid = spec->capsrc_nids[c];
10517 unsigned int mux_idx;
10518 const struct hda_input_mux *imux;
10519 int conns, mute, idx, item;
10520
10521 conns = snd_hda_get_connections(codec, nid, conn_list,
10522 ARRAY_SIZE(conn_list));
10523 if (conns < 0)
10524 continue;
10525 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10526 imux = &spec->input_mux[mux_idx];
5311114d
TI
10527 if (!imux->num_items && mux_idx > 0)
10528 imux = &spec->input_mux[0];
4953550a
TI
10529 for (idx = 0; idx < conns; idx++) {
10530 /* if the current connection is the selected one,
10531 * unmute it as default - otherwise mute it
10532 */
10533 mute = AMP_IN_MUTE(idx);
10534 for (item = 0; item < imux->num_items; item++) {
10535 if (imux->items[item].index == idx) {
10536 if (spec->cur_mux[c] == item)
10537 mute = AMP_IN_UNMUTE(idx);
10538 break;
10539 }
10540 }
10541 /* check if we have a selector or mixer
10542 * we could check for the widget type instead, but
10543 * just check for Amp-In presence (in case of mixer
10544 * without amp-in there is something wrong, this
10545 * function shouldn't be used or capsrc nid is wrong)
10546 */
10547 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10548 snd_hda_codec_write(codec, nid, 0,
10549 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10550 mute);
10551 else if (mute != AMP_IN_MUTE(idx))
10552 snd_hda_codec_write(codec, nid, 0,
10553 AC_VERB_SET_CONNECT_SEL,
10554 idx);
9c7f852e
TI
10555 }
10556 }
10557}
10558
4953550a
TI
10559/* add mic boosts if needed */
10560static int alc_auto_add_mic_boost(struct hda_codec *codec)
10561{
10562 struct alc_spec *spec = codec->spec;
10563 int err;
10564 hda_nid_t nid;
10565
10566 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
10567 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10568 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10569 "Mic Boost",
10570 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10571 if (err < 0)
10572 return err;
10573 }
10574 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
10575 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10576 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10577 "Front Mic Boost",
10578 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10579 if (err < 0)
10580 return err;
10581 }
10582 return 0;
10583}
f511b01c 10584
9c7f852e 10585/* almost identical with ALC880 parser... */
4953550a 10586static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10587{
10588 struct alc_spec *spec = codec->spec;
05f5f477 10589 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 10590 int err;
9c7f852e 10591
05f5f477
TI
10592 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10593 alc882_ignore);
9c7f852e
TI
10594 if (err < 0)
10595 return err;
05f5f477
TI
10596 if (!spec->autocfg.line_outs)
10597 return 0; /* can't find valid BIOS pin config */
776e184e 10598
05f5f477
TI
10599 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10600 if (err < 0)
10601 return err;
10602 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
10603 if (err < 0)
10604 return err;
10605 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10606 "Headphone");
05f5f477
TI
10607 if (err < 0)
10608 return err;
10609 err = alc880_auto_create_extra_out(spec,
10610 spec->autocfg.speaker_pins[0],
10611 "Speaker");
10612 if (err < 0)
10613 return err;
05f5f477 10614 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10615 if (err < 0)
10616 return err;
10617
05f5f477
TI
10618 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10619
757899ac 10620 alc_auto_parse_digital(codec);
05f5f477
TI
10621
10622 if (spec->kctls.list)
10623 add_mixer(spec, spec->kctls.list);
10624
10625 add_verb(spec, alc883_auto_init_verbs);
4953550a 10626 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10627 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10628 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10629
05f5f477
TI
10630 spec->num_mux_defs = 1;
10631 spec->input_mux = &spec->private_imux[0];
10632
6227cdce 10633 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10634
10635 err = alc_auto_add_mic_boost(codec);
10636 if (err < 0)
10637 return err;
61b9b9b1 10638
776e184e 10639 return 1; /* config found */
9c7f852e
TI
10640}
10641
10642/* additional initialization for auto-configuration model */
4953550a 10643static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10644{
f6c7e546 10645 struct alc_spec *spec = codec->spec;
4953550a
TI
10646 alc882_auto_init_multi_out(codec);
10647 alc882_auto_init_hp_out(codec);
10648 alc882_auto_init_analog_input(codec);
10649 alc882_auto_init_input_src(codec);
757899ac 10650 alc_auto_init_digital(codec);
f6c7e546 10651 if (spec->unsol_event)
7fb0d78f 10652 alc_inithook(codec);
9c7f852e
TI
10653}
10654
4953550a 10655static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10656{
10657 struct alc_spec *spec;
10658 int err, board_config;
10659
10660 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10661 if (spec == NULL)
10662 return -ENOMEM;
10663
10664 codec->spec = spec;
10665
da00c244
KY
10666 alc_auto_parse_customize_define(codec);
10667
4953550a
TI
10668 switch (codec->vendor_id) {
10669 case 0x10ec0882:
10670 case 0x10ec0885:
10671 break;
10672 default:
10673 /* ALC883 and variants */
10674 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10675 break;
10676 }
2c3bf9ab 10677
4953550a
TI
10678 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10679 alc882_models,
10680 alc882_cfg_tbl);
10681
10682 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10683 board_config = snd_hda_check_board_codec_sid_config(codec,
10684 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10685
10686 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 10687 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
10688 codec->chip_name);
10689 board_config = ALC882_AUTO;
9c7f852e
TI
10690 }
10691
7fa90e87
TI
10692 if (board_config == ALC882_AUTO)
10693 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
4953550a
TI
10694
10695 if (board_config == ALC882_AUTO) {
9c7f852e 10696 /* automatic parse from the BIOS config */
4953550a 10697 err = alc882_parse_auto_config(codec);
9c7f852e
TI
10698 if (err < 0) {
10699 alc_free(codec);
10700 return err;
f12ab1e0 10701 } else if (!err) {
9c7f852e
TI
10702 printk(KERN_INFO
10703 "hda_codec: Cannot set up configuration "
10704 "from BIOS. Using base mode...\n");
4953550a 10705 board_config = ALC882_3ST_DIG;
9c7f852e
TI
10706 }
10707 }
10708
dc1eae25 10709 if (has_cdefine_beep(codec)) {
8af2591d
TI
10710 err = snd_hda_attach_beep_device(codec, 0x1);
10711 if (err < 0) {
10712 alc_free(codec);
10713 return err;
10714 }
680cd536
KK
10715 }
10716
4953550a 10717 if (board_config != ALC882_AUTO)
e9c364c0 10718 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 10719
4953550a
TI
10720 spec->stream_analog_playback = &alc882_pcm_analog_playback;
10721 spec->stream_analog_capture = &alc882_pcm_analog_capture;
10722 /* FIXME: setup DAC5 */
10723 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
10724 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
10725
10726 spec->stream_digital_playback = &alc882_pcm_digital_playback;
10727 spec->stream_digital_capture = &alc882_pcm_digital_capture;
10728
4953550a 10729 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 10730 int i, j;
4953550a
TI
10731 spec->num_adc_nids = 0;
10732 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 10733 const struct hda_input_mux *imux = spec->input_mux;
4953550a 10734 hda_nid_t cap;
d11f74c6 10735 hda_nid_t items[16];
4953550a
TI
10736 hda_nid_t nid = alc882_adc_nids[i];
10737 unsigned int wcap = get_wcaps(codec, nid);
10738 /* get type */
a22d543a 10739 wcap = get_wcaps_type(wcap);
4953550a
TI
10740 if (wcap != AC_WID_AUD_IN)
10741 continue;
10742 spec->private_adc_nids[spec->num_adc_nids] = nid;
10743 err = snd_hda_get_connections(codec, nid, &cap, 1);
10744 if (err < 0)
10745 continue;
d11f74c6
TI
10746 err = snd_hda_get_connections(codec, cap, items,
10747 ARRAY_SIZE(items));
10748 if (err < 0)
10749 continue;
10750 for (j = 0; j < imux->num_items; j++)
10751 if (imux->items[j].index >= err)
10752 break;
10753 if (j < imux->num_items)
10754 continue;
4953550a
TI
10755 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
10756 spec->num_adc_nids++;
61b9b9b1 10757 }
4953550a
TI
10758 spec->adc_nids = spec->private_adc_nids;
10759 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
10760 }
10761
b59bdf3b 10762 set_capture_mixer(codec);
da00c244 10763
dc1eae25 10764 if (has_cdefine_beep(codec))
da00c244 10765 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 10766
7fa90e87
TI
10767 if (board_config == ALC882_AUTO)
10768 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
10769
2134ea4f
TI
10770 spec->vmaster_nid = 0x0c;
10771
9c7f852e 10772 codec->patch_ops = alc_patch_ops;
4953550a
TI
10773 if (board_config == ALC882_AUTO)
10774 spec->init_hook = alc882_auto_init;
cb53c626
TI
10775#ifdef CONFIG_SND_HDA_POWER_SAVE
10776 if (!spec->loopback.amplist)
4953550a 10777 spec->loopback.amplist = alc882_loopbacks;
cb53c626 10778#endif
9c7f852e
TI
10779
10780 return 0;
10781}
10782
4953550a 10783
9c7f852e
TI
10784/*
10785 * ALC262 support
10786 */
10787
10788#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
10789#define ALC262_DIGIN_NID ALC880_DIGIN_NID
10790
10791#define alc262_dac_nids alc260_dac_nids
10792#define alc262_adc_nids alc882_adc_nids
10793#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
10794#define alc262_capsrc_nids alc882_capsrc_nids
10795#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
10796
10797#define alc262_modes alc260_modes
10798#define alc262_capture_source alc882_capture_source
10799
4e555fe5
KY
10800static hda_nid_t alc262_dmic_adc_nids[1] = {
10801 /* ADC0 */
10802 0x09
10803};
10804
10805static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
10806
9c7f852e
TI
10807static struct snd_kcontrol_new alc262_base_mixer[] = {
10808 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10809 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10810 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10811 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10812 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10813 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10814 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10815 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10816 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
10817 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10818 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 10819 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
10820 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
10821 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10822 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
10823 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10824 { } /* end */
10825};
10826
ce875f07
TI
10827/* update HP, line and mono-out pins according to the master switch */
10828static void alc262_hp_master_update(struct hda_codec *codec)
10829{
10830 struct alc_spec *spec = codec->spec;
10831 int val = spec->master_sw;
10832
10833 /* HP & line-out */
10834 snd_hda_codec_write_cache(codec, 0x1b, 0,
10835 AC_VERB_SET_PIN_WIDGET_CONTROL,
10836 val ? PIN_HP : 0);
10837 snd_hda_codec_write_cache(codec, 0x15, 0,
10838 AC_VERB_SET_PIN_WIDGET_CONTROL,
10839 val ? PIN_HP : 0);
10840 /* mono (speaker) depending on the HP jack sense */
10841 val = val && !spec->jack_present;
10842 snd_hda_codec_write_cache(codec, 0x16, 0,
10843 AC_VERB_SET_PIN_WIDGET_CONTROL,
10844 val ? PIN_OUT : 0);
10845}
10846
10847static void alc262_hp_bpc_automute(struct hda_codec *codec)
10848{
10849 struct alc_spec *spec = codec->spec;
864f92be
WF
10850
10851 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
10852 alc262_hp_master_update(codec);
10853}
10854
10855static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
10856{
10857 if ((res >> 26) != ALC880_HP_EVENT)
10858 return;
10859 alc262_hp_bpc_automute(codec);
10860}
10861
10862static void alc262_hp_wildwest_automute(struct hda_codec *codec)
10863{
10864 struct alc_spec *spec = codec->spec;
864f92be
WF
10865
10866 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
10867 alc262_hp_master_update(codec);
10868}
10869
10870static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
10871 unsigned int res)
10872{
10873 if ((res >> 26) != ALC880_HP_EVENT)
10874 return;
10875 alc262_hp_wildwest_automute(codec);
10876}
10877
b72519b5 10878#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
10879
10880static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10881 struct snd_ctl_elem_value *ucontrol)
10882{
10883 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10884 struct alc_spec *spec = codec->spec;
10885 int val = !!*ucontrol->value.integer.value;
10886
10887 if (val == spec->master_sw)
10888 return 0;
10889 spec->master_sw = val;
10890 alc262_hp_master_update(codec);
10891 return 1;
10892}
10893
b72519b5
TI
10894#define ALC262_HP_MASTER_SWITCH \
10895 { \
10896 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10897 .name = "Master Playback Switch", \
10898 .info = snd_ctl_boolean_mono_info, \
10899 .get = alc262_hp_master_sw_get, \
10900 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
10901 }, \
10902 { \
10903 .iface = NID_MAPPING, \
10904 .name = "Master Playback Switch", \
10905 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
10906 }
10907
5b0cb1d8 10908
9c7f852e 10909static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 10910 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
10911 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10912 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10913 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
10914 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10915 HDA_OUTPUT),
10916 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10917 HDA_OUTPUT),
9c7f852e
TI
10918 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10919 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10920 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
10921 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10922 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 10923 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
10924 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10925 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10926 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10927 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
10928 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
10929 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
10930 { } /* end */
10931};
10932
cd7509a4 10933static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 10934 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
10935 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10936 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10937 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10938 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
10939 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10940 HDA_OUTPUT),
10941 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10942 HDA_OUTPUT),
cd7509a4
KY
10943 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
10944 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 10945 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
10946 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10947 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10948 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10949 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
10950 { } /* end */
10951};
10952
10953static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
10954 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10955 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10956 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
10957 { } /* end */
10958};
10959
66d2a9d6 10960/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 10961static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
10962{
10963 struct alc_spec *spec = codec->spec;
66d2a9d6 10964
a9fd4f3f 10965 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 10966 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
10967}
10968
66d2a9d6 10969static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
10970 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10971 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
10972 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10973 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10974 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10975 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10976 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10977 { } /* end */
10978};
10979
10980static struct hda_verb alc262_hp_t5735_verbs[] = {
10981 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10982 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10983
10984 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10985 { }
10986};
10987
8c427226 10988static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
10989 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10990 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
10991 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
10992 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
10993 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10994 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10995 { } /* end */
10996};
10997
10998static struct hda_verb alc262_hp_rp5700_verbs[] = {
10999 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11000 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11001 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11002 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11003 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11004 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11005 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11006 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11007 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11008 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11009 {}
11010};
11011
11012static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11013 .num_items = 1,
11014 .items = {
11015 { "Line", 0x1 },
11016 },
11017};
11018
42171c17
TI
11019/* bind hp and internal speaker mute (with plug check) as master switch */
11020static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 11021{
42171c17
TI
11022 struct alc_spec *spec = codec->spec;
11023 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11024 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11025 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11026 unsigned int mute;
0724ea2a 11027
42171c17
TI
11028 /* HP */
11029 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11030 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11031 HDA_AMP_MUTE, mute);
11032 /* mute internal speaker per jack sense */
11033 if (spec->jack_present)
11034 mute = HDA_AMP_MUTE;
11035 if (line_nid)
11036 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11037 HDA_AMP_MUTE, mute);
11038 if (speaker_nid && speaker_nid != line_nid)
11039 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 11040 HDA_AMP_MUTE, mute);
42171c17
TI
11041}
11042
11043#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11044
11045static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11046 struct snd_ctl_elem_value *ucontrol)
11047{
11048 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11049 struct alc_spec *spec = codec->spec;
11050 int val = !!*ucontrol->value.integer.value;
11051
11052 if (val == spec->master_sw)
11053 return 0;
11054 spec->master_sw = val;
11055 alc262_hippo_master_update(codec);
11056 return 1;
11057}
11058
11059#define ALC262_HIPPO_MASTER_SWITCH \
11060 { \
11061 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11062 .name = "Master Playback Switch", \
11063 .info = snd_ctl_boolean_mono_info, \
11064 .get = alc262_hippo_master_sw_get, \
11065 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11066 }, \
11067 { \
11068 .iface = NID_MAPPING, \
11069 .name = "Master Playback Switch", \
11070 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11071 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11072 }
42171c17
TI
11073
11074static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11075 ALC262_HIPPO_MASTER_SWITCH,
11076 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11077 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11078 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11079 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11080 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11081 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11082 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11083 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11084 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11085 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11086 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11087 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11088 { } /* end */
11089};
11090
11091static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11092 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11093 ALC262_HIPPO_MASTER_SWITCH,
11094 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11095 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11096 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11097 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11098 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11099 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11100 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11101 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11102 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11103 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11104 { } /* end */
11105};
11106
11107/* mute/unmute internal speaker according to the hp jack and mute state */
11108static void alc262_hippo_automute(struct hda_codec *codec)
11109{
11110 struct alc_spec *spec = codec->spec;
11111 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 11112
864f92be 11113 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 11114 alc262_hippo_master_update(codec);
0724ea2a 11115}
5b31954e 11116
42171c17
TI
11117static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11118{
11119 if ((res >> 26) != ALC880_HP_EVENT)
11120 return;
11121 alc262_hippo_automute(codec);
11122}
11123
4f5d1706 11124static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11125{
11126 struct alc_spec *spec = codec->spec;
11127
11128 spec->autocfg.hp_pins[0] = 0x15;
11129 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11130}
11131
4f5d1706 11132static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11133{
11134 struct alc_spec *spec = codec->spec;
11135
11136 spec->autocfg.hp_pins[0] = 0x1b;
11137 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11138}
11139
11140
272a527c 11141static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11142 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11143 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11144 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11145 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11146 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11147 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11148 { } /* end */
11149};
11150
83c34218 11151static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11152 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11153 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11154 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11155 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11156 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11157 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11158 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11159 { } /* end */
11160};
272a527c 11161
ba340e82
TV
11162static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11163 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11164 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11165 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11166 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11167 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11168 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
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("Mic Boost", 0x18, 0, HDA_INPUT),
11172 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11173 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11174 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11175 { } /* end */
11176};
11177
11178static struct hda_verb alc262_tyan_verbs[] = {
11179 /* Headphone automute */
11180 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11181 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11182 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11183
11184 /* P11 AUX_IN, white 4-pin connector */
11185 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11186 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11187 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11188 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11189
11190 {}
11191};
11192
11193/* unsolicited event for HP jack sensing */
4f5d1706 11194static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11195{
a9fd4f3f 11196 struct alc_spec *spec = codec->spec;
ba340e82 11197
a9fd4f3f
TI
11198 spec->autocfg.hp_pins[0] = 0x1b;
11199 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
11200}
11201
ba340e82 11202
9c7f852e
TI
11203#define alc262_capture_mixer alc882_capture_mixer
11204#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11205
11206/*
11207 * generic initialization of ADC, input mixers and output mixers
11208 */
11209static struct hda_verb alc262_init_verbs[] = {
11210 /*
11211 * Unmute ADC0-2 and set the default input to mic-in
11212 */
11213 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11214 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11215 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11216 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11217 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11218 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11219
cb53c626 11220 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11221 * mixer widget
f12ab1e0
TI
11222 * Note: PASD motherboards uses the Line In 2 as the input for
11223 * front panel mic (mic 2)
9c7f852e
TI
11224 */
11225 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11226 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11227 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11228 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11229 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11230 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11231
11232 /*
df694daa
KY
11233 * Set up output mixers (0x0c - 0x0e)
11234 */
11235 /* set vol=0 to output mixers */
11236 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11237 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11238 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11239 /* set up input amps for analog loopback */
11240 /* Amp Indices: DAC = 0, mixer = 1 */
11241 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11242 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11243 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11244 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11245 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11246 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11247
11248 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11249 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11250 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11251 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11252 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11253 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11254
11255 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11256 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11257 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11258 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11259 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11260
df694daa
KY
11261 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11262 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11263
df694daa
KY
11264 /* FIXME: use matrix-type input source selection */
11265 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11266 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11267 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11268 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11269 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11270 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11271 /* Input mixer2 */
11272 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11273 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11274 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11275 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11276 /* Input mixer3 */
11277 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11278 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11279 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11280 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11281
11282 { }
11283};
1da177e4 11284
4e555fe5
KY
11285static struct hda_verb alc262_eapd_verbs[] = {
11286 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11287 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11288 { }
11289};
11290
ccc656ce
KY
11291static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11292 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11293 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11294 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11295
11296 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11297 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11298 {}
11299};
11300
272a527c
KY
11301static struct hda_verb alc262_sony_unsol_verbs[] = {
11302 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11303 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11304 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11305
11306 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11307 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11308 {}
272a527c
KY
11309};
11310
4e555fe5
KY
11311static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11312 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11313 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11314 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11315 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11316 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11317 { } /* end */
11318};
11319
11320static struct hda_verb alc262_toshiba_s06_verbs[] = {
11321 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11322 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11323 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11324 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11325 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11326 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11327 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11328 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11329 {}
11330};
11331
4f5d1706 11332static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11333{
a9fd4f3f
TI
11334 struct alc_spec *spec = codec->spec;
11335
11336 spec->autocfg.hp_pins[0] = 0x15;
11337 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11338 spec->ext_mic.pin = 0x18;
11339 spec->ext_mic.mux_idx = 0;
11340 spec->int_mic.pin = 0x12;
11341 spec->int_mic.mux_idx = 9;
11342 spec->auto_mic = 1;
4e555fe5
KY
11343}
11344
e8f9ae2a
PT
11345/*
11346 * nec model
11347 * 0x15 = headphone
11348 * 0x16 = internal speaker
11349 * 0x18 = external mic
11350 */
11351
11352static struct snd_kcontrol_new alc262_nec_mixer[] = {
11353 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11354 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11355
11356 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11357 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11358 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11359
11360 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11361 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11362 { } /* end */
11363};
11364
11365static struct hda_verb alc262_nec_verbs[] = {
11366 /* Unmute Speaker */
11367 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11368
11369 /* Headphone */
11370 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11371 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11372
11373 /* External mic to headphone */
11374 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11375 /* External mic to speaker */
11376 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11377 {}
11378};
11379
834be88d
TI
11380/*
11381 * fujitsu model
5d9fab2d
TV
11382 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11383 * 0x1b = port replicator headphone out
834be88d
TI
11384 */
11385
11386#define ALC_HP_EVENT 0x37
11387
11388static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11389 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11390 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11391 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11392 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11393 {}
11394};
11395
0e31daf7
J
11396static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11397 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11398 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11399 {}
11400};
11401
e2595322
DC
11402static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11403 /* Front Mic pin: input vref at 50% */
11404 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11405 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11406 {}
11407};
11408
834be88d 11409static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11410 .num_items = 3,
834be88d
TI
11411 .items = {
11412 { "Mic", 0x0 },
39d3ed38 11413 { "Int Mic", 0x1 },
834be88d
TI
11414 { "CD", 0x4 },
11415 },
11416};
11417
9c7f852e
TI
11418static struct hda_input_mux alc262_HP_capture_source = {
11419 .num_items = 5,
11420 .items = {
11421 { "Mic", 0x0 },
accbe498 11422 { "Front Mic", 0x1 },
9c7f852e
TI
11423 { "Line", 0x2 },
11424 { "CD", 0x4 },
11425 { "AUX IN", 0x6 },
11426 },
11427};
11428
accbe498 11429static struct hda_input_mux alc262_HP_D7000_capture_source = {
11430 .num_items = 4,
11431 .items = {
11432 { "Mic", 0x0 },
11433 { "Front Mic", 0x2 },
11434 { "Line", 0x1 },
11435 { "CD", 0x4 },
11436 },
11437};
11438
ebc7a406 11439/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11440static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11441{
11442 struct alc_spec *spec = codec->spec;
11443 unsigned int mute;
11444
f12ab1e0 11445 if (force || !spec->sense_updated) {
864f92be
WF
11446 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11447 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11448 spec->sense_updated = 1;
11449 }
ebc7a406
TI
11450 /* unmute internal speaker only if both HPs are unplugged and
11451 * master switch is on
11452 */
11453 if (spec->jack_present)
11454 mute = HDA_AMP_MUTE;
11455 else
834be88d 11456 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11457 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11458 HDA_AMP_MUTE, mute);
834be88d
TI
11459}
11460
11461/* unsolicited event for HP jack sensing */
11462static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11463 unsigned int res)
11464{
11465 if ((res >> 26) != ALC_HP_EVENT)
11466 return;
11467 alc262_fujitsu_automute(codec, 1);
11468}
11469
ebc7a406
TI
11470static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11471{
11472 alc262_fujitsu_automute(codec, 1);
11473}
11474
834be88d 11475/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11476static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11477 .ops = &snd_hda_bind_vol,
11478 .values = {
11479 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11480 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11481 0
11482 },
11483};
834be88d 11484
0e31daf7
J
11485/* mute/unmute internal speaker according to the hp jack and mute state */
11486static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11487{
11488 struct alc_spec *spec = codec->spec;
11489 unsigned int mute;
11490
11491 if (force || !spec->sense_updated) {
864f92be 11492 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11493 spec->sense_updated = 1;
11494 }
11495 if (spec->jack_present) {
11496 /* mute internal speaker */
11497 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11498 HDA_AMP_MUTE, HDA_AMP_MUTE);
11499 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11500 HDA_AMP_MUTE, HDA_AMP_MUTE);
11501 } else {
11502 /* unmute internal speaker if necessary */
11503 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11504 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11505 HDA_AMP_MUTE, mute);
11506 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11507 HDA_AMP_MUTE, mute);
11508 }
11509}
11510
11511/* unsolicited event for HP jack sensing */
11512static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11513 unsigned int res)
11514{
11515 if ((res >> 26) != ALC_HP_EVENT)
11516 return;
11517 alc262_lenovo_3000_automute(codec, 1);
11518}
11519
8de56b7d
TI
11520static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11521 int dir, int idx, long *valp)
11522{
11523 int i, change = 0;
11524
11525 for (i = 0; i < 2; i++, valp++)
11526 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11527 HDA_AMP_MUTE,
11528 *valp ? 0 : HDA_AMP_MUTE);
11529 return change;
11530}
11531
834be88d
TI
11532/* bind hp and internal speaker mute (with plug check) */
11533static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11534 struct snd_ctl_elem_value *ucontrol)
11535{
11536 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11537 long *valp = ucontrol->value.integer.value;
11538 int change;
11539
8de56b7d
TI
11540 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11541 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11542 if (change)
11543 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11544 return change;
11545}
11546
11547static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11548 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11549 {
11550 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11551 .name = "Master Playback Switch",
5e26dfd0 11552 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11553 .info = snd_hda_mixer_amp_switch_info,
11554 .get = snd_hda_mixer_amp_switch_get,
11555 .put = alc262_fujitsu_master_sw_put,
11556 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11557 },
5b0cb1d8
JK
11558 {
11559 .iface = NID_MAPPING,
11560 .name = "Master Playback Switch",
11561 .private_value = 0x1b,
11562 },
834be88d
TI
11563 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11564 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11565 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11566 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11567 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
11568 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11569 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11570 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11571 { } /* end */
11572};
11573
0e31daf7
J
11574/* bind hp and internal speaker mute (with plug check) */
11575static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11576 struct snd_ctl_elem_value *ucontrol)
11577{
11578 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11579 long *valp = ucontrol->value.integer.value;
11580 int change;
11581
8de56b7d 11582 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11583 if (change)
11584 alc262_lenovo_3000_automute(codec, 0);
11585 return change;
11586}
11587
11588static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11589 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11590 {
11591 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11592 .name = "Master Playback Switch",
5e26dfd0 11593 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11594 .info = snd_hda_mixer_amp_switch_info,
11595 .get = snd_hda_mixer_amp_switch_get,
11596 .put = alc262_lenovo_3000_master_sw_put,
11597 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11598 },
11599 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11600 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11601 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11602 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11603 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11604 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11605 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11606 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11607 { } /* end */
11608};
11609
9f99a638
HM
11610static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11611 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11612 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11613 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11614 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11615 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11616 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11617 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11618 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11619 { } /* end */
11620};
11621
304dcaac
TI
11622/* additional init verbs for Benq laptops */
11623static struct hda_verb alc262_EAPD_verbs[] = {
11624 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11625 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11626 {}
11627};
11628
83c34218
KY
11629static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11630 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11631 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11632
11633 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11634 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11635 {}
11636};
11637
f651b50b
TD
11638/* Samsung Q1 Ultra Vista model setup */
11639static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11640 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11641 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11642 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11643 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11644 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 11645 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
11646 { } /* end */
11647};
11648
11649static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11650 /* output mixer */
11651 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11652 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11653 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11654 /* speaker */
11655 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11656 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11657 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11658 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11659 /* HP */
f651b50b 11660 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11661 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11662 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11663 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11664 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11665 /* internal mic */
11666 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11667 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11668 /* ADC, choose mic */
11669 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11670 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11671 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11672 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11673 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11674 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11675 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11676 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11677 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11678 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
11679 {}
11680};
11681
f651b50b
TD
11682/* mute/unmute internal speaker according to the hp jack and mute state */
11683static void alc262_ultra_automute(struct hda_codec *codec)
11684{
11685 struct alc_spec *spec = codec->spec;
11686 unsigned int mute;
f651b50b 11687
bb9f76cd
TI
11688 mute = 0;
11689 /* auto-mute only when HP is used as HP */
11690 if (!spec->cur_mux[0]) {
864f92be 11691 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
11692 if (spec->jack_present)
11693 mute = HDA_AMP_MUTE;
f651b50b 11694 }
bb9f76cd
TI
11695 /* mute/unmute internal speaker */
11696 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11697 HDA_AMP_MUTE, mute);
11698 /* mute/unmute HP */
11699 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11700 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
11701}
11702
11703/* unsolicited event for HP jack sensing */
11704static void alc262_ultra_unsol_event(struct hda_codec *codec,
11705 unsigned int res)
11706{
11707 if ((res >> 26) != ALC880_HP_EVENT)
11708 return;
11709 alc262_ultra_automute(codec);
11710}
11711
bb9f76cd
TI
11712static struct hda_input_mux alc262_ultra_capture_source = {
11713 .num_items = 2,
11714 .items = {
11715 { "Mic", 0x1 },
11716 { "Headphone", 0x7 },
11717 },
11718};
11719
11720static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11721 struct snd_ctl_elem_value *ucontrol)
11722{
11723 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11724 struct alc_spec *spec = codec->spec;
11725 int ret;
11726
54cbc9ab 11727 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
11728 if (!ret)
11729 return 0;
11730 /* reprogram the HP pin as mic or HP according to the input source */
11731 snd_hda_codec_write_cache(codec, 0x15, 0,
11732 AC_VERB_SET_PIN_WIDGET_CONTROL,
11733 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11734 alc262_ultra_automute(codec); /* mute/unmute HP */
11735 return ret;
11736}
11737
11738static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11739 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11740 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11741 {
11742 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11743 .name = "Capture Source",
54cbc9ab
TI
11744 .info = alc_mux_enum_info,
11745 .get = alc_mux_enum_get,
bb9f76cd
TI
11746 .put = alc262_ultra_mux_enum_put,
11747 },
5b0cb1d8
JK
11748 {
11749 .iface = NID_MAPPING,
11750 .name = "Capture Source",
11751 .private_value = 0x15,
11752 },
bb9f76cd
TI
11753 { } /* end */
11754};
11755
c3fc1f50
TI
11756/* We use two mixers depending on the output pin; 0x16 is a mono output
11757 * and thus it's bound with a different mixer.
11758 * This function returns which mixer amp should be used.
11759 */
11760static int alc262_check_volbit(hda_nid_t nid)
11761{
11762 if (!nid)
11763 return 0;
11764 else if (nid == 0x16)
11765 return 2;
11766 else
11767 return 1;
11768}
11769
11770static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
11771 const char *pfx, int *vbits)
11772{
c3fc1f50
TI
11773 unsigned long val;
11774 int vbit;
11775
11776 vbit = alc262_check_volbit(nid);
11777 if (!vbit)
11778 return 0;
11779 if (*vbits & vbit) /* a volume control for this mixer already there */
11780 return 0;
11781 *vbits |= vbit;
c3fc1f50
TI
11782 if (vbit == 2)
11783 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11784 else
11785 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
0afe5f89 11786 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val);
c3fc1f50
TI
11787}
11788
11789static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
11790 const char *pfx)
11791{
c3fc1f50
TI
11792 unsigned long val;
11793
11794 if (!nid)
11795 return 0;
c3fc1f50
TI
11796 if (nid == 0x16)
11797 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11798 else
11799 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
0afe5f89 11800 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
c3fc1f50
TI
11801}
11802
df694daa 11803/* add playback controls from the parsed DAC table */
f12ab1e0
TI
11804static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11805 const struct auto_pin_cfg *cfg)
df694daa 11806{
c3fc1f50
TI
11807 const char *pfx;
11808 int vbits;
df694daa
KY
11809 int err;
11810
11811 spec->multiout.num_dacs = 1; /* only use one dac */
11812 spec->multiout.dac_nids = spec->private_dac_nids;
11813 spec->multiout.dac_nids[0] = 2;
11814
c3fc1f50
TI
11815 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
11816 pfx = "Master";
11817 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11818 pfx = "Speaker";
11819 else
11820 pfx = "Front";
11821 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx);
11822 if (err < 0)
11823 return err;
11824 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker");
11825 if (err < 0)
11826 return err;
11827 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone");
11828 if (err < 0)
11829 return err;
df694daa 11830
c3fc1f50
TI
11831 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
11832 alc262_check_volbit(cfg->speaker_pins[0]) |
11833 alc262_check_volbit(cfg->hp_pins[0]);
11834 if (vbits == 1 || vbits == 2)
11835 pfx = "Master"; /* only one mixer is used */
11836 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11837 pfx = "Speaker";
11838 else
11839 pfx = "Front";
11840 vbits = 0;
11841 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits);
11842 if (err < 0)
11843 return err;
11844 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker",
11845 &vbits);
11846 if (err < 0)
11847 return err;
11848 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone",
11849 &vbits);
11850 if (err < 0)
11851 return err;
f12ab1e0 11852 return 0;
df694daa
KY
11853}
11854
05f5f477 11855#define alc262_auto_create_input_ctls \
eaa9b3a7 11856 alc882_auto_create_input_ctls
df694daa
KY
11857
11858/*
11859 * generic initialization of ADC, input mixers and output mixers
11860 */
11861static struct hda_verb alc262_volume_init_verbs[] = {
11862 /*
11863 * Unmute ADC0-2 and set the default input to mic-in
11864 */
11865 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11866 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11867 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11868 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11869 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11870 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11871
cb53c626 11872 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 11873 * mixer widget
f12ab1e0
TI
11874 * Note: PASD motherboards uses the Line In 2 as the input for
11875 * front panel mic (mic 2)
df694daa
KY
11876 */
11877 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11878 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11879 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11880 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11881 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11882 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
11883
11884 /*
11885 * Set up output mixers (0x0c - 0x0f)
11886 */
11887 /* set vol=0 to output mixers */
11888 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11889 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11890 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 11891
df694daa
KY
11892 /* set up input amps for analog loopback */
11893 /* Amp Indices: DAC = 0, mixer = 1 */
11894 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11895 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11896 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11897 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11898 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11899 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11900
11901 /* FIXME: use matrix-type input source selection */
11902 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11903 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11904 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11905 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11906 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11907 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11908 /* Input mixer2 */
11909 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11910 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11911 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11912 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11913 /* Input mixer3 */
11914 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11915 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11916 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11917 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11918
11919 { }
11920};
11921
9c7f852e
TI
11922static struct hda_verb alc262_HP_BPC_init_verbs[] = {
11923 /*
11924 * Unmute ADC0-2 and set the default input to mic-in
11925 */
11926 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11927 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11928 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11929 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11930 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11931 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11932
cb53c626 11933 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11934 * mixer widget
f12ab1e0
TI
11935 * Note: PASD motherboards uses the Line In 2 as the input for
11936 * front panel mic (mic 2)
9c7f852e
TI
11937 */
11938 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11939 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11940 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11941 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11942 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11943 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11944 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11945 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 11946
9c7f852e
TI
11947 /*
11948 * Set up output mixers (0x0c - 0x0e)
11949 */
11950 /* set vol=0 to output mixers */
11951 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11952 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11953 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11954
11955 /* set up input amps for analog loopback */
11956 /* Amp Indices: DAC = 0, mixer = 1 */
11957 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11958 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11959 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11960 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11961 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11962 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11963
ce875f07 11964 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
11965 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11966 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11967
11968 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11969 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11970
11971 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11972 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11973
11974 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11975 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11976 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11977 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11978 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11979
0e4835c1 11980 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
11981 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11982 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 11983 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
11984 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11985 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11986
11987
11988 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
11989 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
11990 /* Input mixer1: only unmute Mic */
9c7f852e 11991 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
11992 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11993 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11994 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11995 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11996 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11997 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11998 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11999 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12000 /* Input mixer2 */
12001 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12002 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12003 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12004 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12005 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12006 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12007 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12008 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12009 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12010 /* Input mixer3 */
12011 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12012 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12013 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12014 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12015 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12016 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12017 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12018 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12019 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12020
ce875f07
TI
12021 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12022
9c7f852e
TI
12023 { }
12024};
12025
cd7509a4
KY
12026static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12027 /*
12028 * Unmute ADC0-2 and set the default input to mic-in
12029 */
12030 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12031 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12032 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12033 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12034 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12035 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12036
cb53c626 12037 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12038 * mixer widget
12039 * Note: PASD motherboards uses the Line In 2 as the input for front
12040 * panel mic (mic 2)
12041 */
12042 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12043 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12044 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12045 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12046 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12047 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12048 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12049 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12050 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12051 /*
12052 * Set up output mixers (0x0c - 0x0e)
12053 */
12054 /* set vol=0 to output mixers */
12055 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12056 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12057 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12058
12059 /* set up input amps for analog loopback */
12060 /* Amp Indices: DAC = 0, mixer = 1 */
12061 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12062 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12063 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12064 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12065 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12066 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12067
12068
12069 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12070 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12071 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12072 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12073 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12074 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12075 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12076
12077 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12078 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12079
12080 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12081 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12082
12083 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12084 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12085 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12086 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12087 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12088 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12089
12090 /* FIXME: use matrix-type input source selection */
12091 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12092 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12093 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12094 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12095 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12096 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12097 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12098 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12099 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12100 /* Input mixer2 */
12101 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12102 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12103 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12104 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12105 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12106 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12107 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12108 /* Input mixer3 */
12109 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12110 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12111 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12112 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12113 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12114 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12115 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12116
ce875f07
TI
12117 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12118
cd7509a4
KY
12119 { }
12120};
12121
9f99a638
HM
12122static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12123
12124 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12125 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12126 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12127
12128 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12129 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12130 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12131 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12132
12133 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12134 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12135 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12136 {}
12137};
12138
12139
cb53c626
TI
12140#ifdef CONFIG_SND_HDA_POWER_SAVE
12141#define alc262_loopbacks alc880_loopbacks
12142#endif
12143
def319f9 12144/* pcm configuration: identical with ALC880 */
df694daa
KY
12145#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12146#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12147#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12148#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12149
12150/*
12151 * BIOS auto configuration
12152 */
12153static int alc262_parse_auto_config(struct hda_codec *codec)
12154{
12155 struct alc_spec *spec = codec->spec;
12156 int err;
12157 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12158
f12ab1e0
TI
12159 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12160 alc262_ignore);
12161 if (err < 0)
df694daa 12162 return err;
e64f14f4 12163 if (!spec->autocfg.line_outs) {
0852d7a6 12164 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12165 spec->multiout.max_channels = 2;
12166 spec->no_analog = 1;
12167 goto dig_only;
12168 }
df694daa 12169 return 0; /* can't find valid BIOS pin config */
e64f14f4 12170 }
f12ab1e0
TI
12171 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12172 if (err < 0)
12173 return err;
05f5f477 12174 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12175 if (err < 0)
df694daa
KY
12176 return err;
12177
12178 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12179
e64f14f4 12180 dig_only:
757899ac 12181 alc_auto_parse_digital(codec);
df694daa 12182
603c4019 12183 if (spec->kctls.list)
d88897ea 12184 add_mixer(spec, spec->kctls.list);
df694daa 12185
d88897ea 12186 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12187 spec->num_mux_defs = 1;
61b9b9b1 12188 spec->input_mux = &spec->private_imux[0];
df694daa 12189
776e184e
TI
12190 err = alc_auto_add_mic_boost(codec);
12191 if (err < 0)
12192 return err;
12193
6227cdce 12194 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12195
df694daa
KY
12196 return 1;
12197}
12198
12199#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12200#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12201#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12202#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12203
12204
12205/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12206static void alc262_auto_init(struct hda_codec *codec)
df694daa 12207{
f6c7e546 12208 struct alc_spec *spec = codec->spec;
df694daa
KY
12209 alc262_auto_init_multi_out(codec);
12210 alc262_auto_init_hp_out(codec);
12211 alc262_auto_init_analog_input(codec);
f511b01c 12212 alc262_auto_init_input_src(codec);
757899ac 12213 alc_auto_init_digital(codec);
f6c7e546 12214 if (spec->unsol_event)
7fb0d78f 12215 alc_inithook(codec);
df694daa
KY
12216}
12217
12218/*
12219 * configuration and preset
12220 */
f5fcc13c
TI
12221static const char *alc262_models[ALC262_MODEL_LAST] = {
12222 [ALC262_BASIC] = "basic",
12223 [ALC262_HIPPO] = "hippo",
12224 [ALC262_HIPPO_1] = "hippo_1",
12225 [ALC262_FUJITSU] = "fujitsu",
12226 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12227 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12228 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12229 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12230 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12231 [ALC262_BENQ_T31] = "benq-t31",
12232 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12233 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12234 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12235 [ALC262_ULTRA] = "ultra",
0e31daf7 12236 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12237 [ALC262_NEC] = "nec",
ba340e82 12238 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12239 [ALC262_AUTO] = "auto",
12240};
12241
12242static struct snd_pci_quirk alc262_cfg_tbl[] = {
12243 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12244 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12245 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12246 ALC262_HP_BPC),
12247 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12248 ALC262_HP_BPC),
53eff7e1
TI
12249 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12250 ALC262_HP_BPC),
cd7509a4 12251 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12252 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12253 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12254 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12255 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12256 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12257 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12258 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12259 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12260 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12261 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12262 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12263 ALC262_HP_TC_T5735),
8c427226 12264 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12265 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12266 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12267 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12268 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12269 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12270 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12271 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12272#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12273 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12274 ALC262_SONY_ASSAMD),
c5b5165c 12275#endif
36ca6e13 12276 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12277 ALC262_TOSHIBA_RX1),
80ffe869 12278 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12279 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12280 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12281 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12282 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12283 ALC262_ULTRA),
3e420e78 12284 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12285 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12286 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12287 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12288 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12289 {}
12290};
12291
12292static struct alc_config_preset alc262_presets[] = {
12293 [ALC262_BASIC] = {
12294 .mixers = { alc262_base_mixer },
12295 .init_verbs = { alc262_init_verbs },
12296 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12297 .dac_nids = alc262_dac_nids,
12298 .hp_nid = 0x03,
12299 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12300 .channel_mode = alc262_modes,
a3bcba38 12301 .input_mux = &alc262_capture_source,
df694daa 12302 },
ccc656ce 12303 [ALC262_HIPPO] = {
42171c17 12304 .mixers = { alc262_hippo_mixer },
6732bd0d 12305 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12306 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12307 .dac_nids = alc262_dac_nids,
12308 .hp_nid = 0x03,
12309 .dig_out_nid = ALC262_DIGOUT_NID,
12310 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12311 .channel_mode = alc262_modes,
12312 .input_mux = &alc262_capture_source,
12313 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12314 .setup = alc262_hippo_setup,
12315 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12316 },
12317 [ALC262_HIPPO_1] = {
12318 .mixers = { alc262_hippo1_mixer },
12319 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12320 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12321 .dac_nids = alc262_dac_nids,
12322 .hp_nid = 0x02,
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,
42171c17 12327 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12328 .setup = alc262_hippo1_setup,
12329 .init_hook = alc262_hippo_automute,
ccc656ce 12330 },
834be88d
TI
12331 [ALC262_FUJITSU] = {
12332 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12333 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12334 alc262_fujitsu_unsol_verbs },
834be88d
TI
12335 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12336 .dac_nids = alc262_dac_nids,
12337 .hp_nid = 0x03,
12338 .dig_out_nid = ALC262_DIGOUT_NID,
12339 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12340 .channel_mode = alc262_modes,
12341 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12342 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12343 .init_hook = alc262_fujitsu_init_hook,
834be88d 12344 },
9c7f852e
TI
12345 [ALC262_HP_BPC] = {
12346 .mixers = { alc262_HP_BPC_mixer },
12347 .init_verbs = { alc262_HP_BPC_init_verbs },
12348 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12349 .dac_nids = alc262_dac_nids,
12350 .hp_nid = 0x03,
12351 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12352 .channel_mode = alc262_modes,
12353 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12354 .unsol_event = alc262_hp_bpc_unsol_event,
12355 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12356 },
cd7509a4
KY
12357 [ALC262_HP_BPC_D7000_WF] = {
12358 .mixers = { alc262_HP_BPC_WildWest_mixer },
12359 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12360 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12361 .dac_nids = alc262_dac_nids,
12362 .hp_nid = 0x03,
12363 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12364 .channel_mode = alc262_modes,
accbe498 12365 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12366 .unsol_event = alc262_hp_wildwest_unsol_event,
12367 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12368 },
cd7509a4
KY
12369 [ALC262_HP_BPC_D7000_WL] = {
12370 .mixers = { alc262_HP_BPC_WildWest_mixer,
12371 alc262_HP_BPC_WildWest_option_mixer },
12372 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12373 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12374 .dac_nids = alc262_dac_nids,
12375 .hp_nid = 0x03,
12376 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12377 .channel_mode = alc262_modes,
accbe498 12378 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12379 .unsol_event = alc262_hp_wildwest_unsol_event,
12380 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12381 },
66d2a9d6
KY
12382 [ALC262_HP_TC_T5735] = {
12383 .mixers = { alc262_hp_t5735_mixer },
12384 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12385 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12386 .dac_nids = alc262_dac_nids,
12387 .hp_nid = 0x03,
12388 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12389 .channel_mode = alc262_modes,
12390 .input_mux = &alc262_capture_source,
dc99be47 12391 .unsol_event = alc_sku_unsol_event,
4f5d1706 12392 .setup = alc262_hp_t5735_setup,
dc99be47 12393 .init_hook = alc_inithook,
8c427226
KY
12394 },
12395 [ALC262_HP_RP5700] = {
12396 .mixers = { alc262_hp_rp5700_mixer },
12397 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12398 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12399 .dac_nids = alc262_dac_nids,
12400 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12401 .channel_mode = alc262_modes,
12402 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12403 },
304dcaac
TI
12404 [ALC262_BENQ_ED8] = {
12405 .mixers = { alc262_base_mixer },
12406 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12407 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12408 .dac_nids = alc262_dac_nids,
12409 .hp_nid = 0x03,
12410 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12411 .channel_mode = alc262_modes,
12412 .input_mux = &alc262_capture_source,
f12ab1e0 12413 },
272a527c
KY
12414 [ALC262_SONY_ASSAMD] = {
12415 .mixers = { alc262_sony_mixer },
12416 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12417 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12418 .dac_nids = alc262_dac_nids,
12419 .hp_nid = 0x02,
12420 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12421 .channel_mode = alc262_modes,
12422 .input_mux = &alc262_capture_source,
12423 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12424 .setup = alc262_hippo_setup,
12425 .init_hook = alc262_hippo_automute,
83c34218
KY
12426 },
12427 [ALC262_BENQ_T31] = {
12428 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12429 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12430 alc_hp15_unsol_verbs },
83c34218
KY
12431 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12432 .dac_nids = alc262_dac_nids,
12433 .hp_nid = 0x03,
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,
ea1fb29a 12440 },
f651b50b 12441 [ALC262_ULTRA] = {
f9e336f6
TI
12442 .mixers = { alc262_ultra_mixer },
12443 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12444 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12445 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12446 .dac_nids = alc262_dac_nids,
f651b50b
TD
12447 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12448 .channel_mode = alc262_modes,
12449 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12450 .adc_nids = alc262_adc_nids, /* ADC0 */
12451 .capsrc_nids = alc262_capsrc_nids,
12452 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12453 .unsol_event = alc262_ultra_unsol_event,
12454 .init_hook = alc262_ultra_automute,
12455 },
0e31daf7
J
12456 [ALC262_LENOVO_3000] = {
12457 .mixers = { alc262_lenovo_3000_mixer },
12458 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12459 alc262_lenovo_3000_unsol_verbs,
12460 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12461 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12462 .dac_nids = alc262_dac_nids,
12463 .hp_nid = 0x03,
12464 .dig_out_nid = ALC262_DIGOUT_NID,
12465 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12466 .channel_mode = alc262_modes,
12467 .input_mux = &alc262_fujitsu_capture_source,
12468 .unsol_event = alc262_lenovo_3000_unsol_event,
12469 },
e8f9ae2a
PT
12470 [ALC262_NEC] = {
12471 .mixers = { alc262_nec_mixer },
12472 .init_verbs = { alc262_nec_verbs },
12473 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12474 .dac_nids = alc262_dac_nids,
12475 .hp_nid = 0x03,
12476 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12477 .channel_mode = alc262_modes,
12478 .input_mux = &alc262_capture_source,
12479 },
4e555fe5
KY
12480 [ALC262_TOSHIBA_S06] = {
12481 .mixers = { alc262_toshiba_s06_mixer },
12482 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12483 alc262_eapd_verbs },
12484 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12485 .capsrc_nids = alc262_dmic_capsrc_nids,
12486 .dac_nids = alc262_dac_nids,
12487 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12488 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12489 .dig_out_nid = ALC262_DIGOUT_NID,
12490 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12491 .channel_mode = alc262_modes,
4f5d1706
TI
12492 .unsol_event = alc_sku_unsol_event,
12493 .setup = alc262_toshiba_s06_setup,
12494 .init_hook = alc_inithook,
4e555fe5 12495 },
9f99a638
HM
12496 [ALC262_TOSHIBA_RX1] = {
12497 .mixers = { alc262_toshiba_rx1_mixer },
12498 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12499 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12500 .dac_nids = alc262_dac_nids,
12501 .hp_nid = 0x03,
12502 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12503 .channel_mode = alc262_modes,
12504 .input_mux = &alc262_capture_source,
12505 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12506 .setup = alc262_hippo_setup,
12507 .init_hook = alc262_hippo_automute,
9f99a638 12508 },
ba340e82
TV
12509 [ALC262_TYAN] = {
12510 .mixers = { alc262_tyan_mixer },
12511 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12512 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12513 .dac_nids = alc262_dac_nids,
12514 .hp_nid = 0x02,
12515 .dig_out_nid = ALC262_DIGOUT_NID,
12516 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12517 .channel_mode = alc262_modes,
12518 .input_mux = &alc262_capture_source,
a9fd4f3f 12519 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12520 .setup = alc262_tyan_setup,
12521 .init_hook = alc_automute_amp,
ba340e82 12522 },
df694daa
KY
12523};
12524
12525static int patch_alc262(struct hda_codec *codec)
12526{
12527 struct alc_spec *spec;
12528 int board_config;
12529 int err;
12530
dc041e0b 12531 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12532 if (spec == NULL)
12533 return -ENOMEM;
12534
12535 codec->spec = spec;
12536#if 0
f12ab1e0
TI
12537 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12538 * under-run
12539 */
df694daa
KY
12540 {
12541 int tmp;
12542 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12543 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12544 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12545 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12546 }
12547#endif
da00c244 12548 alc_auto_parse_customize_define(codec);
df694daa 12549
2c3bf9ab
TI
12550 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12551
f5fcc13c
TI
12552 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12553 alc262_models,
12554 alc262_cfg_tbl);
cd7509a4 12555
f5fcc13c 12556 if (board_config < 0) {
9a11f1aa
TI
12557 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12558 codec->chip_name);
df694daa
KY
12559 board_config = ALC262_AUTO;
12560 }
12561
12562 if (board_config == ALC262_AUTO) {
12563 /* automatic parse from the BIOS config */
12564 err = alc262_parse_auto_config(codec);
12565 if (err < 0) {
12566 alc_free(codec);
12567 return err;
f12ab1e0 12568 } else if (!err) {
9c7f852e
TI
12569 printk(KERN_INFO
12570 "hda_codec: Cannot set up configuration "
12571 "from BIOS. Using base mode...\n");
df694daa
KY
12572 board_config = ALC262_BASIC;
12573 }
12574 }
12575
dc1eae25 12576 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12577 err = snd_hda_attach_beep_device(codec, 0x1);
12578 if (err < 0) {
12579 alc_free(codec);
12580 return err;
12581 }
680cd536
KK
12582 }
12583
df694daa 12584 if (board_config != ALC262_AUTO)
e9c364c0 12585 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12586
df694daa
KY
12587 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12588 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12589
df694daa
KY
12590 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12591 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12592
f12ab1e0 12593 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12594 int i;
12595 /* check whether the digital-mic has to be supported */
12596 for (i = 0; i < spec->input_mux->num_items; i++) {
12597 if (spec->input_mux->items[i].index >= 9)
12598 break;
12599 }
12600 if (i < spec->input_mux->num_items) {
12601 /* use only ADC0 */
12602 spec->adc_nids = alc262_dmic_adc_nids;
12603 spec->num_adc_nids = 1;
12604 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12605 } else {
8c927b4a
TI
12606 /* all analog inputs */
12607 /* check whether NID 0x07 is valid */
12608 unsigned int wcap = get_wcaps(codec, 0x07);
12609
12610 /* get type */
a22d543a 12611 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12612 if (wcap != AC_WID_AUD_IN) {
12613 spec->adc_nids = alc262_adc_nids_alt;
12614 spec->num_adc_nids =
12615 ARRAY_SIZE(alc262_adc_nids_alt);
12616 spec->capsrc_nids = alc262_capsrc_nids_alt;
12617 } else {
12618 spec->adc_nids = alc262_adc_nids;
12619 spec->num_adc_nids =
12620 ARRAY_SIZE(alc262_adc_nids);
12621 spec->capsrc_nids = alc262_capsrc_nids;
12622 }
df694daa
KY
12623 }
12624 }
e64f14f4 12625 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12626 set_capture_mixer(codec);
dc1eae25 12627 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 12628 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12629
2134ea4f
TI
12630 spec->vmaster_nid = 0x0c;
12631
df694daa
KY
12632 codec->patch_ops = alc_patch_ops;
12633 if (board_config == ALC262_AUTO)
ae6b813a 12634 spec->init_hook = alc262_auto_init;
cb53c626
TI
12635#ifdef CONFIG_SND_HDA_POWER_SAVE
12636 if (!spec->loopback.amplist)
12637 spec->loopback.amplist = alc262_loopbacks;
12638#endif
ea1fb29a 12639
df694daa
KY
12640 return 0;
12641}
12642
a361d84b
KY
12643/*
12644 * ALC268 channel source setting (2 channel)
12645 */
12646#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12647#define alc268_modes alc260_modes
ea1fb29a 12648
a361d84b
KY
12649static hda_nid_t alc268_dac_nids[2] = {
12650 /* front, hp */
12651 0x02, 0x03
12652};
12653
12654static hda_nid_t alc268_adc_nids[2] = {
12655 /* ADC0-1 */
12656 0x08, 0x07
12657};
12658
12659static hda_nid_t alc268_adc_nids_alt[1] = {
12660 /* ADC0 */
12661 0x08
12662};
12663
e1406348
TI
12664static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12665
a361d84b
KY
12666static struct snd_kcontrol_new alc268_base_mixer[] = {
12667 /* output mixer control */
12668 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12669 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12670 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12671 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
12672 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12673 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12674 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
12675 { }
12676};
12677
42171c17
TI
12678static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12679 /* output mixer control */
12680 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12681 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12682 ALC262_HIPPO_MASTER_SWITCH,
12683 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12684 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12685 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12686 { }
12687};
12688
aef9d318
TI
12689/* bind Beep switches of both NID 0x0f and 0x10 */
12690static struct hda_bind_ctls alc268_bind_beep_sw = {
12691 .ops = &snd_hda_bind_sw,
12692 .values = {
12693 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12694 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12695 0
12696 },
12697};
12698
12699static struct snd_kcontrol_new alc268_beep_mixer[] = {
12700 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12701 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12702 { }
12703};
12704
d1a991a6
KY
12705static struct hda_verb alc268_eapd_verbs[] = {
12706 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12707 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12708 { }
12709};
12710
d273809e 12711/* Toshiba specific */
d273809e
TI
12712static struct hda_verb alc268_toshiba_verbs[] = {
12713 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12714 { } /* end */
12715};
12716
12717/* Acer specific */
889c4395 12718/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
12719static struct hda_bind_ctls alc268_acer_bind_master_vol = {
12720 .ops = &snd_hda_bind_vol,
12721 .values = {
12722 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12723 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12724 0
12725 },
12726};
12727
889c4395
TI
12728/* mute/unmute internal speaker according to the hp jack and mute state */
12729static void alc268_acer_automute(struct hda_codec *codec, int force)
12730{
12731 struct alc_spec *spec = codec->spec;
12732 unsigned int mute;
12733
12734 if (force || !spec->sense_updated) {
864f92be 12735 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
12736 spec->sense_updated = 1;
12737 }
12738 if (spec->jack_present)
12739 mute = HDA_AMP_MUTE; /* mute internal speaker */
12740 else /* unmute internal speaker if necessary */
12741 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
12742 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12743 HDA_AMP_MUTE, mute);
12744}
12745
12746
12747/* bind hp and internal speaker mute (with plug check) */
12748static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
12749 struct snd_ctl_elem_value *ucontrol)
12750{
12751 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12752 long *valp = ucontrol->value.integer.value;
12753 int change;
12754
8de56b7d 12755 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
12756 if (change)
12757 alc268_acer_automute(codec, 0);
12758 return change;
12759}
d273809e 12760
8ef355da
KY
12761static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12762 /* output mixer control */
12763 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12764 {
12765 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12766 .name = "Master Playback Switch",
5e26dfd0 12767 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
12768 .info = snd_hda_mixer_amp_switch_info,
12769 .get = snd_hda_mixer_amp_switch_get,
12770 .put = alc268_acer_master_sw_put,
12771 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12772 },
12773 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12774 { }
12775};
12776
d273809e
TI
12777static struct snd_kcontrol_new alc268_acer_mixer[] = {
12778 /* output mixer control */
12779 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12780 {
12781 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12782 .name = "Master Playback Switch",
5e26dfd0 12783 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
12784 .info = snd_hda_mixer_amp_switch_info,
12785 .get = snd_hda_mixer_amp_switch_get,
12786 .put = alc268_acer_master_sw_put,
12787 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12788 },
33bf17ab
TI
12789 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12790 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12791 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
12792 { }
12793};
12794
c238b4f4
TI
12795static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12796 /* output mixer control */
12797 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12798 {
12799 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12800 .name = "Master Playback Switch",
5e26dfd0 12801 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
12802 .info = snd_hda_mixer_amp_switch_info,
12803 .get = snd_hda_mixer_amp_switch_get,
12804 .put = alc268_acer_master_sw_put,
12805 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12806 },
12807 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12808 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12809 { }
12810};
12811
8ef355da
KY
12812static struct hda_verb alc268_acer_aspire_one_verbs[] = {
12813 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12814 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12815 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12816 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12817 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12818 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12819 { }
12820};
12821
d273809e 12822static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
12823 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12824 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
12825 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12826 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
12827 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12828 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
12829 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12830 { }
12831};
12832
12833/* unsolicited event for HP jack sensing */
42171c17 12834#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
12835#define alc268_toshiba_setup alc262_hippo_setup
12836#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
12837
12838static void alc268_acer_unsol_event(struct hda_codec *codec,
12839 unsigned int res)
12840{
889c4395 12841 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
12842 return;
12843 alc268_acer_automute(codec, 1);
12844}
12845
889c4395
TI
12846static void alc268_acer_init_hook(struct hda_codec *codec)
12847{
12848 alc268_acer_automute(codec, 1);
12849}
12850
8ef355da
KY
12851/* toggle speaker-output according to the hp-jack state */
12852static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
12853{
12854 unsigned int present;
12855 unsigned char bits;
12856
864f92be 12857 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 12858 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 12859 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 12860 HDA_AMP_MUTE, bits);
8ef355da 12861 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 12862 HDA_AMP_MUTE, bits);
8ef355da
KY
12863}
12864
8ef355da
KY
12865static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
12866 unsigned int res)
12867{
4f5d1706
TI
12868 switch (res >> 26) {
12869 case ALC880_HP_EVENT:
8ef355da 12870 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
12871 break;
12872 case ALC880_MIC_EVENT:
12873 alc_mic_automute(codec);
12874 break;
12875 }
12876}
12877
12878static void alc268_acer_lc_setup(struct hda_codec *codec)
12879{
12880 struct alc_spec *spec = codec->spec;
12881 spec->ext_mic.pin = 0x18;
12882 spec->ext_mic.mux_idx = 0;
12883 spec->int_mic.pin = 0x12;
12884 spec->int_mic.mux_idx = 6;
12885 spec->auto_mic = 1;
8ef355da
KY
12886}
12887
12888static void alc268_acer_lc_init_hook(struct hda_codec *codec)
12889{
12890 alc268_aspire_one_speaker_automute(codec);
4f5d1706 12891 alc_mic_automute(codec);
8ef355da
KY
12892}
12893
3866f0b0
TI
12894static struct snd_kcontrol_new alc268_dell_mixer[] = {
12895 /* output mixer control */
12896 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12897 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12898 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12899 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12900 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12901 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12902 { }
12903};
12904
12905static struct hda_verb alc268_dell_verbs[] = {
12906 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12907 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12908 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 12909 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
12910 { }
12911};
12912
12913/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 12914static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 12915{
a9fd4f3f 12916 struct alc_spec *spec = codec->spec;
3866f0b0 12917
a9fd4f3f
TI
12918 spec->autocfg.hp_pins[0] = 0x15;
12919 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12920 spec->ext_mic.pin = 0x18;
12921 spec->ext_mic.mux_idx = 0;
12922 spec->int_mic.pin = 0x19;
12923 spec->int_mic.mux_idx = 1;
12924 spec->auto_mic = 1;
3866f0b0
TI
12925}
12926
eb5a6621
HRK
12927static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12928 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12929 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12930 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12931 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12932 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12933 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12934 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12935 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12936 { }
12937};
12938
12939static struct hda_verb alc267_quanta_il1_verbs[] = {
12940 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12941 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12942 { }
12943};
12944
4f5d1706 12945static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 12946{
a9fd4f3f 12947 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
12948 spec->autocfg.hp_pins[0] = 0x15;
12949 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12950 spec->ext_mic.pin = 0x18;
12951 spec->ext_mic.mux_idx = 0;
12952 spec->int_mic.pin = 0x19;
12953 spec->int_mic.mux_idx = 1;
12954 spec->auto_mic = 1;
eb5a6621
HRK
12955}
12956
a361d84b
KY
12957/*
12958 * generic initialization of ADC, input mixers and output mixers
12959 */
12960static struct hda_verb alc268_base_init_verbs[] = {
12961 /* Unmute DAC0-1 and set vol = 0 */
12962 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 12963 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
12964
12965 /*
12966 * Set up output mixers (0x0c - 0x0e)
12967 */
12968 /* set vol=0 to output mixers */
12969 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
12970 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12971
12972 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12973 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12974
12975 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12976 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12977 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12978 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12979 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12980 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12981 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12982 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12983
12984 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12985 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12986 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12987 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 12988 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
12989
12990 /* set PCBEEP vol = 0, mute connections */
12991 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12992 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12993 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 12994
a9b3aa8a 12995 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 12996
a9b3aa8a
JZ
12997 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
12998 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12999 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13000 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13001
a361d84b
KY
13002 { }
13003};
13004
13005/*
13006 * generic initialization of ADC, input mixers and output mixers
13007 */
13008static struct hda_verb alc268_volume_init_verbs[] = {
13009 /* set output DAC */
4cfb91c6
TI
13010 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13011 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13012
13013 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13014 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13015 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13016 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13017 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13018
a361d84b 13019 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13020 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13021 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13022
13023 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13024 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13025
aef9d318
TI
13026 /* set PCBEEP vol = 0, mute connections */
13027 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13028 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13029 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13030
13031 { }
13032};
13033
fdbc6626
TI
13034static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13035 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13036 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13037 { } /* end */
13038};
13039
a361d84b
KY
13040static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13041 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13042 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13043 _DEFINE_CAPSRC(1),
a361d84b
KY
13044 { } /* end */
13045};
13046
13047static struct snd_kcontrol_new alc268_capture_mixer[] = {
13048 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13049 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13050 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13051 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13052 _DEFINE_CAPSRC(2),
a361d84b
KY
13053 { } /* end */
13054};
13055
13056static struct hda_input_mux alc268_capture_source = {
13057 .num_items = 4,
13058 .items = {
13059 { "Mic", 0x0 },
13060 { "Front Mic", 0x1 },
13061 { "Line", 0x2 },
13062 { "CD", 0x3 },
13063 },
13064};
13065
0ccb541c 13066static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13067 .num_items = 3,
13068 .items = {
13069 { "Mic", 0x0 },
13070 { "Internal Mic", 0x1 },
13071 { "Line", 0x2 },
13072 },
13073};
13074
13075static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13076 .num_items = 3,
13077 .items = {
13078 { "Mic", 0x0 },
13079 { "Internal Mic", 0x6 },
13080 { "Line", 0x2 },
13081 },
13082};
13083
86c53bd2
JW
13084#ifdef CONFIG_SND_DEBUG
13085static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13086 /* Volume widgets */
13087 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13088 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13089 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13090 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13091 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13092 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13093 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13094 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13095 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13096 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13097 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13098 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13099 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13100 /* The below appears problematic on some hardwares */
13101 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13102 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13103 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13104 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13105 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13106
13107 /* Modes for retasking pin widgets */
13108 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13109 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13110 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13111 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13112
13113 /* Controls for GPIO pins, assuming they are configured as outputs */
13114 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13115 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13116 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13117 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13118
13119 /* Switches to allow the digital SPDIF output pin to be enabled.
13120 * The ALC268 does not have an SPDIF input.
13121 */
13122 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13123
13124 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13125 * this output to turn on an external amplifier.
13126 */
13127 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13128 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13129
13130 { } /* end */
13131};
13132#endif
13133
a361d84b
KY
13134/* create input playback/capture controls for the given pin */
13135static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13136 const char *ctlname, int idx)
13137{
3f3b7c1a 13138 hda_nid_t dac;
a361d84b
KY
13139 int err;
13140
3f3b7c1a
TI
13141 switch (nid) {
13142 case 0x14:
13143 case 0x16:
13144 dac = 0x02;
13145 break;
13146 case 0x15:
5d4abf93 13147 case 0x1b:
531d8791 13148 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13149 dac = 0x03;
13150 break;
13151 default:
13152 return 0;
13153 }
13154 if (spec->multiout.dac_nids[0] != dac &&
13155 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13156 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13157 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13158 HDA_OUTPUT));
13159 if (err < 0)
13160 return err;
3f3b7c1a
TI
13161 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13162 }
13163
3f3b7c1a 13164 if (nid != 0x16)
0afe5f89 13165 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13166 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13167 else /* mono */
0afe5f89 13168 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13169 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13170 if (err < 0)
13171 return err;
13172 return 0;
13173}
13174
13175/* add playback controls from the parsed DAC table */
13176static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13177 const struct auto_pin_cfg *cfg)
13178{
13179 hda_nid_t nid;
13180 int err;
13181
a361d84b 13182 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13183
13184 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13185 if (nid) {
13186 const char *name;
13187 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13188 name = "Speaker";
13189 else
13190 name = "Front";
13191 err = alc268_new_analog_output(spec, nid, name, 0);
13192 if (err < 0)
13193 return err;
13194 }
a361d84b
KY
13195
13196 nid = cfg->speaker_pins[0];
13197 if (nid == 0x1d) {
0afe5f89 13198 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13199 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13200 if (err < 0)
13201 return err;
3f3b7c1a
TI
13202 } else {
13203 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13204 if (err < 0)
13205 return err;
a361d84b
KY
13206 }
13207 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13208 if (nid) {
13209 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13210 if (err < 0)
13211 return err;
13212 }
a361d84b
KY
13213
13214 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13215 if (nid == 0x16) {
0afe5f89 13216 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13217 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13218 if (err < 0)
13219 return err;
13220 }
ea1fb29a 13221 return 0;
a361d84b
KY
13222}
13223
13224/* create playback/capture controls for input pins */
05f5f477 13225static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13226 const struct auto_pin_cfg *cfg)
13227{
05f5f477 13228 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13229}
13230
e9af4f36
TI
13231static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13232 hda_nid_t nid, int pin_type)
13233{
13234 int idx;
13235
13236 alc_set_pin_output(codec, nid, pin_type);
13237 if (nid == 0x14 || nid == 0x16)
13238 idx = 0;
13239 else
13240 idx = 1;
13241 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13242}
13243
13244static void alc268_auto_init_multi_out(struct hda_codec *codec)
13245{
13246 struct alc_spec *spec = codec->spec;
13247 hda_nid_t nid = spec->autocfg.line_out_pins[0];
13248 if (nid) {
13249 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13250 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13251 }
13252}
13253
13254static void alc268_auto_init_hp_out(struct hda_codec *codec)
13255{
13256 struct alc_spec *spec = codec->spec;
13257 hda_nid_t pin;
13258
13259 pin = spec->autocfg.hp_pins[0];
13260 if (pin)
13261 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13262 pin = spec->autocfg.speaker_pins[0];
13263 if (pin)
13264 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13265}
13266
a361d84b
KY
13267static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13268{
13269 struct alc_spec *spec = codec->spec;
13270 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13271 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13272 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13273 unsigned int dac_vol1, dac_vol2;
13274
e9af4f36 13275 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13276 snd_hda_codec_write(codec, speaker_nid, 0,
13277 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13278 /* mute mixer inputs from 0x1d */
a361d84b
KY
13279 snd_hda_codec_write(codec, 0x0f, 0,
13280 AC_VERB_SET_AMP_GAIN_MUTE,
13281 AMP_IN_UNMUTE(1));
13282 snd_hda_codec_write(codec, 0x10, 0,
13283 AC_VERB_SET_AMP_GAIN_MUTE,
13284 AMP_IN_UNMUTE(1));
13285 } else {
e9af4f36 13286 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13287 snd_hda_codec_write(codec, 0x0f, 0,
13288 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13289 snd_hda_codec_write(codec, 0x10, 0,
13290 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13291 }
13292
13293 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13294 if (line_nid == 0x14)
a361d84b
KY
13295 dac_vol2 = AMP_OUT_ZERO;
13296 else if (line_nid == 0x15)
13297 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13298 if (hp_nid == 0x14)
a361d84b
KY
13299 dac_vol2 = AMP_OUT_ZERO;
13300 else if (hp_nid == 0x15)
13301 dac_vol1 = AMP_OUT_ZERO;
13302 if (line_nid != 0x16 || hp_nid != 0x16 ||
13303 spec->autocfg.line_out_pins[1] != 0x16 ||
13304 spec->autocfg.line_out_pins[2] != 0x16)
13305 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13306
13307 snd_hda_codec_write(codec, 0x02, 0,
13308 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13309 snd_hda_codec_write(codec, 0x03, 0,
13310 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13311}
13312
def319f9 13313/* pcm configuration: identical with ALC880 */
a361d84b
KY
13314#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13315#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13316#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13317#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13318
13319/*
13320 * BIOS auto configuration
13321 */
13322static int alc268_parse_auto_config(struct hda_codec *codec)
13323{
13324 struct alc_spec *spec = codec->spec;
13325 int err;
13326 static hda_nid_t alc268_ignore[] = { 0 };
13327
13328 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13329 alc268_ignore);
13330 if (err < 0)
13331 return err;
7e0e44d4
TI
13332 if (!spec->autocfg.line_outs) {
13333 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13334 spec->multiout.max_channels = 2;
13335 spec->no_analog = 1;
13336 goto dig_only;
13337 }
a361d84b 13338 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13339 }
a361d84b
KY
13340 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13341 if (err < 0)
13342 return err;
05f5f477 13343 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13344 if (err < 0)
13345 return err;
13346
13347 spec->multiout.max_channels = 2;
13348
7e0e44d4 13349 dig_only:
a361d84b 13350 /* digital only support output */
757899ac 13351 alc_auto_parse_digital(codec);
603c4019 13352 if (spec->kctls.list)
d88897ea 13353 add_mixer(spec, spec->kctls.list);
a361d84b 13354
892981ff 13355 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13356 add_mixer(spec, alc268_beep_mixer);
aef9d318 13357
d88897ea 13358 add_verb(spec, alc268_volume_init_verbs);
5908589f 13359 spec->num_mux_defs = 2;
61b9b9b1 13360 spec->input_mux = &spec->private_imux[0];
a361d84b 13361
776e184e
TI
13362 err = alc_auto_add_mic_boost(codec);
13363 if (err < 0)
13364 return err;
13365
6227cdce 13366 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13367
a361d84b
KY
13368 return 1;
13369}
13370
a361d84b
KY
13371#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13372
13373/* init callback for auto-configuration model -- overriding the default init */
13374static void alc268_auto_init(struct hda_codec *codec)
13375{
f6c7e546 13376 struct alc_spec *spec = codec->spec;
a361d84b
KY
13377 alc268_auto_init_multi_out(codec);
13378 alc268_auto_init_hp_out(codec);
13379 alc268_auto_init_mono_speaker_out(codec);
13380 alc268_auto_init_analog_input(codec);
757899ac 13381 alc_auto_init_digital(codec);
f6c7e546 13382 if (spec->unsol_event)
7fb0d78f 13383 alc_inithook(codec);
a361d84b
KY
13384}
13385
13386/*
13387 * configuration and preset
13388 */
13389static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13390 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13391 [ALC268_3ST] = "3stack",
983f8ae4 13392 [ALC268_TOSHIBA] = "toshiba",
d273809e 13393 [ALC268_ACER] = "acer",
c238b4f4 13394 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13395 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13396 [ALC268_DELL] = "dell",
f12462c5 13397 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13398#ifdef CONFIG_SND_DEBUG
13399 [ALC268_TEST] = "test",
13400#endif
a361d84b
KY
13401 [ALC268_AUTO] = "auto",
13402};
13403
13404static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13405 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13406 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13407 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13408 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13409 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13410 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13411 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13412 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13413 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13414 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13415 /* almost compatible with toshiba but with optional digital outs;
13416 * auto-probing seems working fine
13417 */
8871e5b9 13418 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13419 ALC268_AUTO),
a361d84b 13420 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13421 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13422 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13423 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13424 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
8871e5b9 13425 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
a361d84b
KY
13426 {}
13427};
13428
3abf2f36
TI
13429/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13430static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13431 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13432 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13433 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13434 ALC268_TOSHIBA),
13435 {}
13436};
13437
a361d84b 13438static struct alc_config_preset alc268_presets[] = {
eb5a6621 13439 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13440 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13441 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13442 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13443 alc267_quanta_il1_verbs },
13444 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13445 .dac_nids = alc268_dac_nids,
13446 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13447 .adc_nids = alc268_adc_nids_alt,
13448 .hp_nid = 0x03,
13449 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13450 .channel_mode = alc268_modes,
4f5d1706
TI
13451 .unsol_event = alc_sku_unsol_event,
13452 .setup = alc267_quanta_il1_setup,
13453 .init_hook = alc_inithook,
eb5a6621 13454 },
a361d84b 13455 [ALC268_3ST] = {
aef9d318
TI
13456 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13457 alc268_beep_mixer },
a361d84b
KY
13458 .init_verbs = { alc268_base_init_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,
e1406348 13463 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13464 .hp_nid = 0x03,
13465 .dig_out_nid = ALC268_DIGOUT_NID,
13466 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13467 .channel_mode = alc268_modes,
13468 .input_mux = &alc268_capture_source,
13469 },
d1a991a6 13470 [ALC268_TOSHIBA] = {
42171c17 13471 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13472 alc268_beep_mixer },
d273809e
TI
13473 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13474 alc268_toshiba_verbs },
d1a991a6
KY
13475 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13476 .dac_nids = alc268_dac_nids,
13477 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13478 .adc_nids = alc268_adc_nids_alt,
e1406348 13479 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13480 .hp_nid = 0x03,
13481 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13482 .channel_mode = alc268_modes,
13483 .input_mux = &alc268_capture_source,
d273809e 13484 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13485 .setup = alc268_toshiba_setup,
13486 .init_hook = alc268_toshiba_automute,
d273809e
TI
13487 },
13488 [ALC268_ACER] = {
432fd133 13489 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13490 alc268_beep_mixer },
d273809e
TI
13491 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13492 alc268_acer_verbs },
13493 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13494 .dac_nids = alc268_dac_nids,
13495 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13496 .adc_nids = alc268_adc_nids_alt,
e1406348 13497 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13498 .hp_nid = 0x02,
13499 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13500 .channel_mode = alc268_modes,
0ccb541c 13501 .input_mux = &alc268_acer_capture_source,
d273809e 13502 .unsol_event = alc268_acer_unsol_event,
889c4395 13503 .init_hook = alc268_acer_init_hook,
d1a991a6 13504 },
c238b4f4
TI
13505 [ALC268_ACER_DMIC] = {
13506 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13507 alc268_beep_mixer },
13508 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13509 alc268_acer_verbs },
13510 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13511 .dac_nids = alc268_dac_nids,
13512 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13513 .adc_nids = alc268_adc_nids_alt,
13514 .capsrc_nids = alc268_capsrc_nids,
13515 .hp_nid = 0x02,
13516 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13517 .channel_mode = alc268_modes,
13518 .input_mux = &alc268_acer_dmic_capture_source,
13519 .unsol_event = alc268_acer_unsol_event,
13520 .init_hook = alc268_acer_init_hook,
13521 },
8ef355da
KY
13522 [ALC268_ACER_ASPIRE_ONE] = {
13523 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13524 alc268_beep_mixer,
fdbc6626 13525 alc268_capture_nosrc_mixer },
8ef355da
KY
13526 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13527 alc268_acer_aspire_one_verbs },
13528 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13529 .dac_nids = alc268_dac_nids,
13530 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13531 .adc_nids = alc268_adc_nids_alt,
13532 .capsrc_nids = alc268_capsrc_nids,
13533 .hp_nid = 0x03,
13534 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13535 .channel_mode = alc268_modes,
8ef355da 13536 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13537 .setup = alc268_acer_lc_setup,
8ef355da
KY
13538 .init_hook = alc268_acer_lc_init_hook,
13539 },
3866f0b0 13540 [ALC268_DELL] = {
fdbc6626
TI
13541 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13542 alc268_capture_nosrc_mixer },
3866f0b0
TI
13543 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13544 alc268_dell_verbs },
13545 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13546 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13547 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13548 .adc_nids = alc268_adc_nids_alt,
13549 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13550 .hp_nid = 0x02,
13551 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13552 .channel_mode = alc268_modes,
a9fd4f3f 13553 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13554 .setup = alc268_dell_setup,
13555 .init_hook = alc_inithook,
3866f0b0 13556 },
f12462c5 13557 [ALC268_ZEPTO] = {
aef9d318
TI
13558 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13559 alc268_beep_mixer },
f12462c5
MT
13560 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13561 alc268_toshiba_verbs },
13562 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13563 .dac_nids = alc268_dac_nids,
13564 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13565 .adc_nids = alc268_adc_nids_alt,
e1406348 13566 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13567 .hp_nid = 0x03,
13568 .dig_out_nid = ALC268_DIGOUT_NID,
13569 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13570 .channel_mode = alc268_modes,
13571 .input_mux = &alc268_capture_source,
4f5d1706
TI
13572 .setup = alc268_toshiba_setup,
13573 .init_hook = alc268_toshiba_automute,
f12462c5 13574 },
86c53bd2
JW
13575#ifdef CONFIG_SND_DEBUG
13576 [ALC268_TEST] = {
13577 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13578 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13579 alc268_volume_init_verbs },
13580 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13581 .dac_nids = alc268_dac_nids,
13582 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13583 .adc_nids = alc268_adc_nids_alt,
e1406348 13584 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13585 .hp_nid = 0x03,
13586 .dig_out_nid = ALC268_DIGOUT_NID,
13587 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13588 .channel_mode = alc268_modes,
13589 .input_mux = &alc268_capture_source,
13590 },
13591#endif
a361d84b
KY
13592};
13593
13594static int patch_alc268(struct hda_codec *codec)
13595{
13596 struct alc_spec *spec;
13597 int board_config;
22971e3a 13598 int i, has_beep, err;
a361d84b 13599
ef86f581 13600 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13601 if (spec == NULL)
13602 return -ENOMEM;
13603
13604 codec->spec = spec;
13605
13606 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13607 alc268_models,
13608 alc268_cfg_tbl);
13609
3abf2f36
TI
13610 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13611 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13612 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13613
a361d84b 13614 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13615 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13616 codec->chip_name);
a361d84b
KY
13617 board_config = ALC268_AUTO;
13618 }
13619
13620 if (board_config == ALC268_AUTO) {
13621 /* automatic parse from the BIOS config */
13622 err = alc268_parse_auto_config(codec);
13623 if (err < 0) {
13624 alc_free(codec);
13625 return err;
13626 } else if (!err) {
13627 printk(KERN_INFO
13628 "hda_codec: Cannot set up configuration "
13629 "from BIOS. Using base mode...\n");
13630 board_config = ALC268_3ST;
13631 }
13632 }
13633
13634 if (board_config != ALC268_AUTO)
e9c364c0 13635 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 13636
a361d84b
KY
13637 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13638 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 13639 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 13640
a361d84b
KY
13641 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13642
22971e3a
TI
13643 has_beep = 0;
13644 for (i = 0; i < spec->num_mixers; i++) {
13645 if (spec->mixers[i] == alc268_beep_mixer) {
13646 has_beep = 1;
13647 break;
13648 }
13649 }
13650
13651 if (has_beep) {
13652 err = snd_hda_attach_beep_device(codec, 0x1);
13653 if (err < 0) {
13654 alc_free(codec);
13655 return err;
13656 }
13657 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13658 /* override the amp caps for beep generator */
13659 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
13660 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13661 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13662 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13663 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 13664 }
aef9d318 13665
7e0e44d4 13666 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
13667 /* check whether NID 0x07 is valid */
13668 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 13669 int i;
3866f0b0 13670
defb5ab2 13671 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 13672 /* get type */
a22d543a 13673 wcap = get_wcaps_type(wcap);
fdbc6626
TI
13674 if (spec->auto_mic ||
13675 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
13676 spec->adc_nids = alc268_adc_nids_alt;
13677 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
13678 if (spec->auto_mic)
13679 fixup_automic_adc(codec);
fdbc6626
TI
13680 if (spec->auto_mic || spec->input_mux->num_items == 1)
13681 add_mixer(spec, alc268_capture_nosrc_mixer);
13682 else
13683 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
13684 } else {
13685 spec->adc_nids = alc268_adc_nids;
13686 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 13687 add_mixer(spec, alc268_capture_mixer);
a361d84b 13688 }
85860c06
TI
13689 /* set default input source */
13690 for (i = 0; i < spec->num_adc_nids; i++)
13691 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
13692 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
13693 i < spec->num_mux_defs ?
13694 spec->input_mux[i].items[0].index :
85860c06 13695 spec->input_mux->items[0].index);
a361d84b 13696 }
2134ea4f
TI
13697
13698 spec->vmaster_nid = 0x02;
13699
a361d84b
KY
13700 codec->patch_ops = alc_patch_ops;
13701 if (board_config == ALC268_AUTO)
13702 spec->init_hook = alc268_auto_init;
ea1fb29a 13703
a361d84b
KY
13704 return 0;
13705}
13706
f6a92248
KY
13707/*
13708 * ALC269 channel source setting (2 channel)
13709 */
13710#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13711
13712#define alc269_dac_nids alc260_dac_nids
13713
13714static hda_nid_t alc269_adc_nids[1] = {
13715 /* ADC1 */
f53281e6
KY
13716 0x08,
13717};
13718
e01bf509
TI
13719static hda_nid_t alc269_capsrc_nids[1] = {
13720 0x23,
13721};
13722
84898e87
KY
13723static hda_nid_t alc269vb_adc_nids[1] = {
13724 /* ADC1 */
13725 0x09,
13726};
13727
13728static hda_nid_t alc269vb_capsrc_nids[1] = {
13729 0x22,
13730};
13731
6694635d
TI
13732static hda_nid_t alc269_adc_candidates[] = {
13733 0x08, 0x09, 0x07,
13734};
e01bf509 13735
f6a92248
KY
13736#define alc269_modes alc260_modes
13737#define alc269_capture_source alc880_lg_lw_capture_source
13738
13739static struct snd_kcontrol_new alc269_base_mixer[] = {
13740 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13741 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13742 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13743 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13744 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13745 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13746 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13747 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13748 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13749 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13750 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13751 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
13752 { } /* end */
13753};
13754
60db6b53
KY
13755static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13756 /* output mixer control */
13757 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13758 {
13759 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13760 .name = "Master Playback Switch",
5e26dfd0 13761 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
13762 .info = snd_hda_mixer_amp_switch_info,
13763 .get = snd_hda_mixer_amp_switch_get,
13764 .put = alc268_acer_master_sw_put,
13765 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13766 },
13767 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13768 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13769 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13770 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13771 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13772 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
60db6b53
KY
13773 { }
13774};
13775
64154835
TV
13776static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13777 /* output mixer control */
13778 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13779 {
13780 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13781 .name = "Master Playback Switch",
5e26dfd0 13782 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
13783 .info = snd_hda_mixer_amp_switch_info,
13784 .get = snd_hda_mixer_amp_switch_get,
13785 .put = alc268_acer_master_sw_put,
13786 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13787 },
13788 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13789 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13790 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13791 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13792 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13793 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13794 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13795 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
13796 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
64154835
TV
13797 { }
13798};
13799
84898e87 13800static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 13801 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 13802 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 13803 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 13804 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
13805 { } /* end */
13806};
13807
84898e87
KY
13808static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13809 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13810 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13811 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13812 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13813 { } /* end */
13814};
13815
f53281e6 13816/* capture mixer elements */
84898e87
KY
13817static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13818 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13819 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13820 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13821 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13822 { } /* end */
13823};
13824
13825static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
13826 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13827 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
26f5df26
TI
13828 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13829 { } /* end */
13830};
13831
84898e87
KY
13832static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13833 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13834 HDA_CODEC_MUTE("Capture Switch", 0x09, 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 alc269vb_laptop_digital_capture_mixer[] = {
13841 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13842 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13843 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13844 { } /* end */
13845};
13846
26f5df26 13847/* FSC amilo */
84898e87 13848#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 13849
60db6b53
KY
13850static struct hda_verb alc269_quanta_fl1_verbs[] = {
13851 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13852 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13853 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13854 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13855 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13856 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13857 { }
13858};
f6a92248 13859
64154835
TV
13860static struct hda_verb alc269_lifebook_verbs[] = {
13861 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13862 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13863 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13864 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13865 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13866 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13867 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13868 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13869 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13870 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13871 { }
13872};
13873
60db6b53
KY
13874/* toggle speaker-output according to the hp-jack state */
13875static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13876{
13877 unsigned int present;
13878 unsigned char bits;
f6a92248 13879
864f92be 13880 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13881 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 13882 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 13883 HDA_AMP_MUTE, bits);
60db6b53 13884 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 13885 HDA_AMP_MUTE, bits);
f6a92248 13886
60db6b53
KY
13887 snd_hda_codec_write(codec, 0x20, 0,
13888 AC_VERB_SET_COEF_INDEX, 0x0c);
13889 snd_hda_codec_write(codec, 0x20, 0,
13890 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 13891
60db6b53
KY
13892 snd_hda_codec_write(codec, 0x20, 0,
13893 AC_VERB_SET_COEF_INDEX, 0x0c);
13894 snd_hda_codec_write(codec, 0x20, 0,
13895 AC_VERB_SET_PROC_COEF, 0x480);
13896}
f6a92248 13897
64154835
TV
13898/* toggle speaker-output according to the hp-jacks state */
13899static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
13900{
13901 unsigned int present;
13902 unsigned char bits;
13903
13904 /* Check laptop headphone socket */
864f92be 13905 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
13906
13907 /* Check port replicator headphone socket */
864f92be 13908 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 13909
5dbd5ec6 13910 bits = present ? HDA_AMP_MUTE : 0;
64154835 13911 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 13912 HDA_AMP_MUTE, bits);
64154835 13913 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 13914 HDA_AMP_MUTE, bits);
64154835
TV
13915
13916 snd_hda_codec_write(codec, 0x20, 0,
13917 AC_VERB_SET_COEF_INDEX, 0x0c);
13918 snd_hda_codec_write(codec, 0x20, 0,
13919 AC_VERB_SET_PROC_COEF, 0x680);
13920
13921 snd_hda_codec_write(codec, 0x20, 0,
13922 AC_VERB_SET_COEF_INDEX, 0x0c);
13923 snd_hda_codec_write(codec, 0x20, 0,
13924 AC_VERB_SET_PROC_COEF, 0x480);
13925}
13926
64154835
TV
13927static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13928{
13929 unsigned int present_laptop;
13930 unsigned int present_dock;
13931
864f92be
WF
13932 present_laptop = snd_hda_jack_detect(codec, 0x18);
13933 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
13934
13935 /* Laptop mic port overrides dock mic port, design decision */
13936 if (present_dock)
13937 snd_hda_codec_write(codec, 0x23, 0,
13938 AC_VERB_SET_CONNECT_SEL, 0x3);
13939 if (present_laptop)
13940 snd_hda_codec_write(codec, 0x23, 0,
13941 AC_VERB_SET_CONNECT_SEL, 0x0);
13942 if (!present_dock && !present_laptop)
13943 snd_hda_codec_write(codec, 0x23, 0,
13944 AC_VERB_SET_CONNECT_SEL, 0x1);
13945}
13946
60db6b53
KY
13947static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13948 unsigned int res)
13949{
4f5d1706
TI
13950 switch (res >> 26) {
13951 case ALC880_HP_EVENT:
60db6b53 13952 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
13953 break;
13954 case ALC880_MIC_EVENT:
13955 alc_mic_automute(codec);
13956 break;
13957 }
60db6b53 13958}
f6a92248 13959
64154835
TV
13960static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13961 unsigned int res)
13962{
13963 if ((res >> 26) == ALC880_HP_EVENT)
13964 alc269_lifebook_speaker_automute(codec);
13965 if ((res >> 26) == ALC880_MIC_EVENT)
13966 alc269_lifebook_mic_autoswitch(codec);
13967}
13968
4f5d1706
TI
13969static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13970{
13971 struct alc_spec *spec = codec->spec;
20645d70
TI
13972 spec->autocfg.hp_pins[0] = 0x15;
13973 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13974 spec->ext_mic.pin = 0x18;
13975 spec->ext_mic.mux_idx = 0;
13976 spec->int_mic.pin = 0x19;
13977 spec->int_mic.mux_idx = 1;
13978 spec->auto_mic = 1;
13979}
13980
60db6b53
KY
13981static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13982{
13983 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 13984 alc_mic_automute(codec);
60db6b53 13985}
f6a92248 13986
64154835
TV
13987static void alc269_lifebook_init_hook(struct hda_codec *codec)
13988{
13989 alc269_lifebook_speaker_automute(codec);
13990 alc269_lifebook_mic_autoswitch(codec);
13991}
13992
84898e87 13993static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
13994 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13995 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13996 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13997 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13998 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13999 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14000 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14001 {}
14002};
14003
84898e87 14004static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14005 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14006 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14007 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14008 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14009 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14010 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14011 {}
14012};
14013
84898e87
KY
14014static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14015 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14016 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14017 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14018 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14019 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14020 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14021 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14022 {}
14023};
14024
14025static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14026 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14027 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14028 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14029 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14030 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14031 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14032 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14033 {}
14034};
14035
f53281e6
KY
14036/* toggle speaker-output according to the hp-jack state */
14037static void alc269_speaker_automute(struct hda_codec *codec)
14038{
ebb83eeb
KY
14039 struct alc_spec *spec = codec->spec;
14040 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 14041 unsigned int present;
60db6b53 14042 unsigned char bits;
f53281e6 14043
ebb83eeb 14044 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 14045 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 14046 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14047 HDA_AMP_MUTE, bits);
f53281e6 14048 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14049 HDA_AMP_MUTE, bits);
f53281e6
KY
14050}
14051
f53281e6 14052/* unsolicited event for HP jack sensing */
84898e87 14053static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 14054 unsigned int res)
f53281e6 14055{
4f5d1706
TI
14056 switch (res >> 26) {
14057 case ALC880_HP_EVENT:
f53281e6 14058 alc269_speaker_automute(codec);
4f5d1706
TI
14059 break;
14060 case ALC880_MIC_EVENT:
14061 alc_mic_automute(codec);
14062 break;
14063 }
f53281e6
KY
14064}
14065
226b1ec8 14066static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14067{
4f5d1706 14068 struct alc_spec *spec = codec->spec;
20645d70
TI
14069 spec->autocfg.hp_pins[0] = 0x15;
14070 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14071 spec->ext_mic.pin = 0x18;
14072 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14073 spec->int_mic.pin = 0x19;
14074 spec->int_mic.mux_idx = 1;
4f5d1706 14075 spec->auto_mic = 1;
f53281e6
KY
14076}
14077
226b1ec8 14078static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14079{
14080 struct alc_spec *spec = codec->spec;
20645d70
TI
14081 spec->autocfg.hp_pins[0] = 0x15;
14082 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
14083 spec->ext_mic.pin = 0x18;
14084 spec->ext_mic.mux_idx = 0;
14085 spec->int_mic.pin = 0x12;
226b1ec8 14086 spec->int_mic.mux_idx = 5;
84898e87
KY
14087 spec->auto_mic = 1;
14088}
14089
226b1ec8 14090static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14091{
4f5d1706 14092 struct alc_spec *spec = codec->spec;
226b1ec8 14093 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14094 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14095 spec->ext_mic.pin = 0x18;
14096 spec->ext_mic.mux_idx = 0;
14097 spec->int_mic.pin = 0x19;
14098 spec->int_mic.mux_idx = 1;
14099 spec->auto_mic = 1;
f53281e6
KY
14100}
14101
226b1ec8
KY
14102static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14103{
14104 struct alc_spec *spec = codec->spec;
14105 spec->autocfg.hp_pins[0] = 0x21;
14106 spec->autocfg.speaker_pins[0] = 0x14;
14107 spec->ext_mic.pin = 0x18;
14108 spec->ext_mic.mux_idx = 0;
14109 spec->int_mic.pin = 0x12;
14110 spec->int_mic.mux_idx = 6;
14111 spec->auto_mic = 1;
14112}
14113
84898e87 14114static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
14115{
14116 alc269_speaker_automute(codec);
4f5d1706 14117 alc_mic_automute(codec);
f53281e6
KY
14118}
14119
60db6b53
KY
14120/*
14121 * generic initialization of ADC, input mixers and output mixers
14122 */
14123static struct hda_verb alc269_init_verbs[] = {
14124 /*
14125 * Unmute ADC0 and set the default input to mic-in
14126 */
84898e87 14127 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14128
14129 /*
84898e87 14130 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14131 */
14132 /* set vol=0 to output mixers */
14133 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14134 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14135
14136 /* set up input amps for analog loopback */
14137 /* Amp Indices: DAC = 0, mixer = 1 */
14138 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14139 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14140 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14141 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14142 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14143 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14144
14145 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14146 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14147 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14148 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14149 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14150 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14151 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14152
14153 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14154 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14155
84898e87
KY
14156 /* FIXME: use Mux-type input source selection */
14157 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14158 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14159 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14160
84898e87
KY
14161 /* set EAPD */
14162 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14163 { }
14164};
14165
14166static struct hda_verb alc269vb_init_verbs[] = {
14167 /*
14168 * Unmute ADC0 and set the default input to mic-in
14169 */
14170 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14171
14172 /*
14173 * Set up output mixers (0x02 - 0x03)
14174 */
14175 /* set vol=0 to output mixers */
14176 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14177 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14178
14179 /* set up input amps for analog loopback */
14180 /* Amp Indices: DAC = 0, mixer = 1 */
14181 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14182 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14183 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14184 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14185 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14186 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14187
14188 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14189 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14190 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14191 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14192 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14193 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14194 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14195
14196 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14197 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14198
14199 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14200 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14201 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14202 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14203
14204 /* set EAPD */
14205 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14206 { }
14207};
14208
9d0b71b1
TI
14209#define alc269_auto_create_multi_out_ctls \
14210 alc268_auto_create_multi_out_ctls
05f5f477
TI
14211#define alc269_auto_create_input_ctls \
14212 alc268_auto_create_input_ctls
f6a92248
KY
14213
14214#ifdef CONFIG_SND_HDA_POWER_SAVE
14215#define alc269_loopbacks alc880_loopbacks
14216#endif
14217
def319f9 14218/* pcm configuration: identical with ALC880 */
f6a92248
KY
14219#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14220#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14221#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14222#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14223
f03d3115
TI
14224static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14225 .substreams = 1,
14226 .channels_min = 2,
14227 .channels_max = 8,
14228 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14229 /* NID is set in alc_build_pcms */
14230 .ops = {
14231 .open = alc880_playback_pcm_open,
14232 .prepare = alc880_playback_pcm_prepare,
14233 .cleanup = alc880_playback_pcm_cleanup
14234 },
14235};
14236
14237static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14238 .substreams = 1,
14239 .channels_min = 2,
14240 .channels_max = 2,
14241 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14242 /* NID is set in alc_build_pcms */
14243};
14244
ad35879a
TI
14245#ifdef CONFIG_SND_HDA_POWER_SAVE
14246static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14247{
14248 switch (codec->subsystem_id) {
14249 case 0x103c1586:
14250 return 1;
14251 }
14252 return 0;
14253}
14254
14255static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14256{
14257 /* update mute-LED according to the speaker mute state */
14258 if (nid == 0x01 || nid == 0x14) {
14259 int pinval;
14260 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14261 HDA_AMP_MUTE)
14262 pinval = 0x24;
14263 else
14264 pinval = 0x20;
14265 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14266 snd_hda_codec_update_cache(codec, 0x19, 0,
14267 AC_VERB_SET_PIN_WIDGET_CONTROL,
14268 pinval);
ad35879a
TI
14269 }
14270 return alc_check_power_status(codec, nid);
14271}
14272#endif /* CONFIG_SND_HDA_POWER_SAVE */
14273
840b64c0
TI
14274static int alc275_setup_dual_adc(struct hda_codec *codec)
14275{
14276 struct alc_spec *spec = codec->spec;
14277
14278 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14279 return 0;
14280 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14281 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14282 if (spec->ext_mic.pin <= 0x12) {
14283 spec->private_adc_nids[0] = 0x08;
14284 spec->private_adc_nids[1] = 0x11;
14285 spec->private_capsrc_nids[0] = 0x23;
14286 spec->private_capsrc_nids[1] = 0x22;
14287 } else {
14288 spec->private_adc_nids[0] = 0x11;
14289 spec->private_adc_nids[1] = 0x08;
14290 spec->private_capsrc_nids[0] = 0x22;
14291 spec->private_capsrc_nids[1] = 0x23;
14292 }
14293 spec->adc_nids = spec->private_adc_nids;
14294 spec->capsrc_nids = spec->private_capsrc_nids;
14295 spec->num_adc_nids = 2;
14296 spec->dual_adc_switch = 1;
14297 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14298 spec->adc_nids[0], spec->adc_nids[1]);
14299 return 1;
14300 }
14301 return 0;
14302}
14303
f6a92248
KY
14304/*
14305 * BIOS auto configuration
14306 */
14307static int alc269_parse_auto_config(struct hda_codec *codec)
14308{
14309 struct alc_spec *spec = codec->spec;
cfb9fb55 14310 int err;
f6a92248
KY
14311 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14312
14313 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14314 alc269_ignore);
14315 if (err < 0)
14316 return err;
14317
14318 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14319 if (err < 0)
14320 return err;
05f5f477 14321 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
f6a92248
KY
14322 if (err < 0)
14323 return err;
14324
14325 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14326
757899ac 14327 alc_auto_parse_digital(codec);
f6a92248 14328
603c4019 14329 if (spec->kctls.list)
d88897ea 14330 add_mixer(spec, spec->kctls.list);
f6a92248 14331
84898e87
KY
14332 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
14333 add_verb(spec, alc269vb_init_verbs);
6227cdce 14334 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14335 } else {
14336 add_verb(spec, alc269_init_verbs);
6227cdce 14337 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14338 }
14339
f6a92248 14340 spec->num_mux_defs = 1;
61b9b9b1 14341 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14342
14343 if (!alc275_setup_dual_adc(codec))
14344 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14345 sizeof(alc269_adc_candidates));
6694635d 14346
e01bf509 14347 /* set default input source */
840b64c0
TI
14348 if (!spec->dual_adc_switch)
14349 snd_hda_codec_write_cache(codec, spec->capsrc_nids[0],
e01bf509
TI
14350 0, AC_VERB_SET_CONNECT_SEL,
14351 spec->input_mux->items[0].index);
f6a92248
KY
14352
14353 err = alc_auto_add_mic_boost(codec);
14354 if (err < 0)
14355 return err;
14356
7e0e44d4 14357 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14358 set_capture_mixer(codec);
f53281e6 14359
f6a92248
KY
14360 return 1;
14361}
14362
e9af4f36
TI
14363#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14364#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14365#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14366
14367
14368/* init callback for auto-configuration model -- overriding the default init */
14369static void alc269_auto_init(struct hda_codec *codec)
14370{
f6c7e546 14371 struct alc_spec *spec = codec->spec;
f6a92248
KY
14372 alc269_auto_init_multi_out(codec);
14373 alc269_auto_init_hp_out(codec);
14374 alc269_auto_init_analog_input(codec);
757899ac 14375 alc_auto_init_digital(codec);
f6c7e546 14376 if (spec->unsol_event)
7fb0d78f 14377 alc_inithook(codec);
f6a92248
KY
14378}
14379
ff818c24
TI
14380enum {
14381 ALC269_FIXUP_SONY_VAIO,
14382};
14383
fbc25669 14384static const struct hda_verb alc269_sony_vaio_fixup_verbs[] = {
ff818c24
TI
14385 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14386 {}
14387};
14388
14389static const struct alc_fixup alc269_fixups[] = {
14390 [ALC269_FIXUP_SONY_VAIO] = {
14391 .verbs = alc269_sony_vaio_fixup_verbs
14392 },
14393};
14394
14395static struct snd_pci_quirk alc269_fixup_tbl[] = {
14396 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14397 {}
14398};
14399
14400
f6a92248
KY
14401/*
14402 * configuration and preset
14403 */
14404static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14405 [ALC269_BASIC] = "basic",
2922c9af 14406 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14407 [ALC269_AMIC] = "laptop-amic",
14408 [ALC269_DMIC] = "laptop-dmic",
64154835 14409 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14410 [ALC269_LIFEBOOK] = "lifebook",
14411 [ALC269_AUTO] = "auto",
f6a92248
KY
14412};
14413
14414static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14415 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
f53281e6 14416 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14417 ALC269_AMIC),
14418 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14419 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14420 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14421 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14422 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14423 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14424 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14425 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14426 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14427 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14428 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14429 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14430 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14431 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14432 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14433 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14434 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14435 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14436 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14437 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14438 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14439 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14440 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14441 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14442 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14443 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14444 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14445 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14446 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14447 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14448 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14449 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14450 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14451 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14452 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14453 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14454 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14455 ALC269_DMIC),
60db6b53 14456 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14457 ALC269_DMIC),
14458 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14459 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14460 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14461 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14462 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14463 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14464 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14465 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14466 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14467 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14468 {}
14469};
14470
14471static struct alc_config_preset alc269_presets[] = {
14472 [ALC269_BASIC] = {
f9e336f6 14473 .mixers = { alc269_base_mixer },
f6a92248
KY
14474 .init_verbs = { alc269_init_verbs },
14475 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14476 .dac_nids = alc269_dac_nids,
14477 .hp_nid = 0x03,
14478 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14479 .channel_mode = alc269_modes,
14480 .input_mux = &alc269_capture_source,
14481 },
60db6b53
KY
14482 [ALC269_QUANTA_FL1] = {
14483 .mixers = { alc269_quanta_fl1_mixer },
14484 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14485 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14486 .dac_nids = alc269_dac_nids,
14487 .hp_nid = 0x03,
14488 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14489 .channel_mode = alc269_modes,
14490 .input_mux = &alc269_capture_source,
14491 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 14492 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
14493 .init_hook = alc269_quanta_fl1_init_hook,
14494 },
84898e87
KY
14495 [ALC269_AMIC] = {
14496 .mixers = { alc269_laptop_mixer },
14497 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 14498 .init_verbs = { alc269_init_verbs,
84898e87 14499 alc269_laptop_amic_init_verbs },
f53281e6
KY
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,
84898e87
KY
14505 .unsol_event = alc269_laptop_unsol_event,
14506 .setup = alc269_laptop_amic_setup,
14507 .init_hook = alc269_laptop_inithook,
f53281e6 14508 },
84898e87
KY
14509 [ALC269_DMIC] = {
14510 .mixers = { alc269_laptop_mixer },
14511 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 14512 .init_verbs = { alc269_init_verbs,
84898e87
KY
14513 alc269_laptop_dmic_init_verbs },
14514 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14515 .dac_nids = alc269_dac_nids,
14516 .hp_nid = 0x03,
14517 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14518 .channel_mode = alc269_modes,
14519 .unsol_event = alc269_laptop_unsol_event,
14520 .setup = alc269_laptop_dmic_setup,
14521 .init_hook = alc269_laptop_inithook,
14522 },
14523 [ALC269VB_AMIC] = {
14524 .mixers = { alc269vb_laptop_mixer },
14525 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14526 .init_verbs = { alc269vb_init_verbs,
14527 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
14528 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14529 .dac_nids = alc269_dac_nids,
14530 .hp_nid = 0x03,
14531 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14532 .channel_mode = alc269_modes,
84898e87 14533 .unsol_event = alc269_laptop_unsol_event,
226b1ec8 14534 .setup = alc269vb_laptop_amic_setup,
84898e87
KY
14535 .init_hook = alc269_laptop_inithook,
14536 },
14537 [ALC269VB_DMIC] = {
14538 .mixers = { alc269vb_laptop_mixer },
14539 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14540 .init_verbs = { alc269vb_init_verbs,
14541 alc269vb_laptop_dmic_init_verbs },
14542 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14543 .dac_nids = alc269_dac_nids,
14544 .hp_nid = 0x03,
14545 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14546 .channel_mode = alc269_modes,
14547 .unsol_event = alc269_laptop_unsol_event,
14548 .setup = alc269vb_laptop_dmic_setup,
14549 .init_hook = alc269_laptop_inithook,
f53281e6 14550 },
26f5df26 14551 [ALC269_FUJITSU] = {
45bdd1c1 14552 .mixers = { alc269_fujitsu_mixer },
84898e87 14553 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 14554 .init_verbs = { alc269_init_verbs,
84898e87 14555 alc269_laptop_dmic_init_verbs },
26f5df26
TI
14556 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14557 .dac_nids = alc269_dac_nids,
14558 .hp_nid = 0x03,
14559 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14560 .channel_mode = alc269_modes,
84898e87
KY
14561 .unsol_event = alc269_laptop_unsol_event,
14562 .setup = alc269_laptop_dmic_setup,
14563 .init_hook = alc269_laptop_inithook,
26f5df26 14564 },
64154835
TV
14565 [ALC269_LIFEBOOK] = {
14566 .mixers = { alc269_lifebook_mixer },
14567 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14568 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14569 .dac_nids = alc269_dac_nids,
14570 .hp_nid = 0x03,
14571 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14572 .channel_mode = alc269_modes,
14573 .input_mux = &alc269_capture_source,
14574 .unsol_event = alc269_lifebook_unsol_event,
14575 .init_hook = alc269_lifebook_init_hook,
14576 },
f6a92248
KY
14577};
14578
14579static int patch_alc269(struct hda_codec *codec)
14580{
14581 struct alc_spec *spec;
14582 int board_config;
14583 int err;
84898e87 14584 int is_alc269vb = 0;
f6a92248
KY
14585
14586 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14587 if (spec == NULL)
14588 return -ENOMEM;
14589
14590 codec->spec = spec;
14591
da00c244
KY
14592 alc_auto_parse_customize_define(codec);
14593
274693f3 14594 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
c027ddcd
KY
14595 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
14596 spec->cdefine.platform_type == 1)
14597 alc_codec_rename(codec, "ALC271X");
14598 else
14599 alc_codec_rename(codec, "ALC259");
84898e87 14600 is_alc269vb = 1;
c027ddcd
KY
14601 } else
14602 alc_fix_pll_init(codec, 0x20, 0x04, 15);
274693f3 14603
f6a92248
KY
14604 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14605 alc269_models,
14606 alc269_cfg_tbl);
14607
14608 if (board_config < 0) {
9a11f1aa
TI
14609 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14610 codec->chip_name);
f6a92248
KY
14611 board_config = ALC269_AUTO;
14612 }
14613
ff818c24
TI
14614 if (board_config == ALC269_AUTO)
14615 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
14616
f6a92248
KY
14617 if (board_config == ALC269_AUTO) {
14618 /* automatic parse from the BIOS config */
14619 err = alc269_parse_auto_config(codec);
14620 if (err < 0) {
14621 alc_free(codec);
14622 return err;
14623 } else if (!err) {
14624 printk(KERN_INFO
14625 "hda_codec: Cannot set up configuration "
14626 "from BIOS. Using base mode...\n");
14627 board_config = ALC269_BASIC;
14628 }
14629 }
14630
dc1eae25 14631 if (has_cdefine_beep(codec)) {
8af2591d
TI
14632 err = snd_hda_attach_beep_device(codec, 0x1);
14633 if (err < 0) {
14634 alc_free(codec);
14635 return err;
14636 }
680cd536
KK
14637 }
14638
f6a92248 14639 if (board_config != ALC269_AUTO)
e9c364c0 14640 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 14641
84898e87 14642 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
14643 /* Due to a hardware problem on Lenovo Ideadpad, we need to
14644 * fix the sample rate of analog I/O to 44.1kHz
14645 */
14646 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
14647 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
14648 } else if (spec->dual_adc_switch) {
14649 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14650 /* switch ADC dynamically */
14651 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
14652 } else {
14653 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14654 spec->stream_analog_capture = &alc269_pcm_analog_capture;
14655 }
f6a92248
KY
14656 spec->stream_digital_playback = &alc269_pcm_digital_playback;
14657 spec->stream_digital_capture = &alc269_pcm_digital_capture;
14658
6694635d
TI
14659 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
14660 if (!is_alc269vb) {
14661 spec->adc_nids = alc269_adc_nids;
14662 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
14663 spec->capsrc_nids = alc269_capsrc_nids;
14664 } else {
14665 spec->adc_nids = alc269vb_adc_nids;
14666 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
14667 spec->capsrc_nids = alc269vb_capsrc_nids;
14668 }
84898e87
KY
14669 }
14670
f9e336f6 14671 if (!spec->cap_mixer)
b59bdf3b 14672 set_capture_mixer(codec);
dc1eae25 14673 if (has_cdefine_beep(codec))
da00c244 14674 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 14675
ff818c24
TI
14676 if (board_config == ALC269_AUTO)
14677 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
14678
100d5eb3
TI
14679 spec->vmaster_nid = 0x02;
14680
f6a92248
KY
14681 codec->patch_ops = alc_patch_ops;
14682 if (board_config == ALC269_AUTO)
14683 spec->init_hook = alc269_auto_init;
14684#ifdef CONFIG_SND_HDA_POWER_SAVE
14685 if (!spec->loopback.amplist)
14686 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
14687 if (alc269_mic2_for_mute_led(codec))
14688 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
14689#endif
14690
14691 return 0;
14692}
14693
df694daa
KY
14694/*
14695 * ALC861 channel source setting (2/6 channel selection for 3-stack)
14696 */
14697
14698/*
14699 * set the path ways for 2 channel output
14700 * need to set the codec line out and mic 1 pin widgets to inputs
14701 */
14702static struct hda_verb alc861_threestack_ch2_init[] = {
14703 /* set pin widget 1Ah (line in) for input */
14704 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14705 /* set pin widget 18h (mic1/2) for input, for mic also enable
14706 * the vref
14707 */
df694daa
KY
14708 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14709
9c7f852e
TI
14710 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14711#if 0
14712 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14713 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14714#endif
df694daa
KY
14715 { } /* end */
14716};
14717/*
14718 * 6ch mode
14719 * need to set the codec line out and mic 1 pin widgets to outputs
14720 */
14721static struct hda_verb alc861_threestack_ch6_init[] = {
14722 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14723 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14724 /* set pin widget 18h (mic1) for output (CLFE)*/
14725 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14726
14727 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 14728 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 14729
9c7f852e
TI
14730 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14731#if 0
14732 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14733 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14734#endif
df694daa
KY
14735 { } /* end */
14736};
14737
14738static struct hda_channel_mode alc861_threestack_modes[2] = {
14739 { 2, alc861_threestack_ch2_init },
14740 { 6, alc861_threestack_ch6_init },
14741};
22309c3e
TI
14742/* Set mic1 as input and unmute the mixer */
14743static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
14744 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14745 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14746 { } /* end */
14747};
14748/* Set mic1 as output and mute mixer */
14749static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
14750 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14751 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14752 { } /* end */
14753};
14754
14755static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
14756 { 2, alc861_uniwill_m31_ch2_init },
14757 { 4, alc861_uniwill_m31_ch4_init },
14758};
df694daa 14759
7cdbff94
MD
14760/* Set mic1 and line-in as input and unmute the mixer */
14761static struct hda_verb alc861_asus_ch2_init[] = {
14762 /* set pin widget 1Ah (line in) for input */
14763 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14764 /* set pin widget 18h (mic1/2) for input, for mic also enable
14765 * the vref
14766 */
7cdbff94
MD
14767 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14768
14769 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14770#if 0
14771 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14772 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14773#endif
14774 { } /* end */
14775};
14776/* Set mic1 nad line-in as output and mute mixer */
14777static struct hda_verb alc861_asus_ch6_init[] = {
14778 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14779 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14780 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14781 /* set pin widget 18h (mic1) for output (CLFE)*/
14782 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14783 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14784 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14785 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14786
14787 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14788#if 0
14789 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14790 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14791#endif
14792 { } /* end */
14793};
14794
14795static struct hda_channel_mode alc861_asus_modes[2] = {
14796 { 2, alc861_asus_ch2_init },
14797 { 6, alc861_asus_ch6_init },
14798};
14799
df694daa
KY
14800/* patch-ALC861 */
14801
14802static struct snd_kcontrol_new alc861_base_mixer[] = {
14803 /* output mixer control */
14804 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14805 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14806 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14807 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14808 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14809
14810 /*Input mixer control */
14811 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14812 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14813 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14814 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14815 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14816 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14817 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14818 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14819 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14820 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14821
df694daa
KY
14822 { } /* end */
14823};
14824
14825static struct snd_kcontrol_new alc861_3ST_mixer[] = {
14826 /* output mixer control */
14827 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14828 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14829 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14830 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14831 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14832
14833 /* Input mixer control */
14834 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14835 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14836 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14837 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14838 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14839 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14840 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14841 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14842 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14843 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14844
df694daa
KY
14845 {
14846 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14847 .name = "Channel Mode",
14848 .info = alc_ch_mode_info,
14849 .get = alc_ch_mode_get,
14850 .put = alc_ch_mode_put,
14851 .private_value = ARRAY_SIZE(alc861_threestack_modes),
14852 },
14853 { } /* end */
a53d1aec
TD
14854};
14855
d1d985f0 14856static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
14857 /* output mixer control */
14858 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14859 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14860 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 14861
a53d1aec 14862 { } /* end */
f12ab1e0 14863};
a53d1aec 14864
22309c3e
TI
14865static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
14866 /* output mixer control */
14867 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14868 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14869 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14870 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14871 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14872
14873 /* Input mixer control */
14874 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14875 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14876 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14877 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14878 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14879 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14880 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14881 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14882 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14883 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14884
22309c3e
TI
14885 {
14886 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14887 .name = "Channel Mode",
14888 .info = alc_ch_mode_info,
14889 .get = alc_ch_mode_get,
14890 .put = alc_ch_mode_put,
14891 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
14892 },
14893 { } /* end */
f12ab1e0 14894};
7cdbff94
MD
14895
14896static struct snd_kcontrol_new alc861_asus_mixer[] = {
14897 /* output mixer control */
14898 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14899 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14900 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14901 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14902 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14903
14904 /* Input mixer control */
14905 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14906 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14907 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14908 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14909 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14910 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14911 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14912 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14913 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
14914 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
14915
7cdbff94
MD
14916 {
14917 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14918 .name = "Channel Mode",
14919 .info = alc_ch_mode_info,
14920 .get = alc_ch_mode_get,
14921 .put = alc_ch_mode_put,
14922 .private_value = ARRAY_SIZE(alc861_asus_modes),
14923 },
14924 { }
56bb0cab
TI
14925};
14926
14927/* additional mixer */
d1d985f0 14928static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
14929 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14930 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
14931 { }
14932};
7cdbff94 14933
df694daa
KY
14934/*
14935 * generic initialization of ADC, input mixers and output mixers
14936 */
14937static struct hda_verb alc861_base_init_verbs[] = {
14938 /*
14939 * Unmute ADC0 and set the default input to mic-in
14940 */
14941 /* port-A for surround (rear panel) */
14942 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14943 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
14944 /* port-B for mic-in (rear panel) with vref */
14945 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14946 /* port-C for line-in (rear panel) */
14947 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14948 /* port-D for Front */
14949 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14950 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14951 /* port-E for HP out (front panel) */
14952 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
14953 /* route front PCM to HP */
9dece1d7 14954 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
14955 /* port-F for mic-in (front panel) with vref */
14956 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14957 /* port-G for CLFE (rear panel) */
14958 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14959 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14960 /* port-H for side (rear panel) */
14961 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14962 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
14963 /* CD-in */
14964 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14965 /* route front mic to ADC1*/
14966 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14967 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 14968
df694daa
KY
14969 /* Unmute DAC0~3 & spdif out*/
14970 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14971 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14972 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14973 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14974 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 14975
df694daa
KY
14976 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14977 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14978 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14979 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14980 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14981
df694daa
KY
14982 /* Unmute Stereo Mixer 15 */
14983 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14984 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14985 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 14986 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
14987
14988 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14989 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14990 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14991 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14992 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14993 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14994 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14995 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
14996 /* hp used DAC 3 (Front) */
14997 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
14998 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14999
15000 { }
15001};
15002
15003static struct hda_verb alc861_threestack_init_verbs[] = {
15004 /*
15005 * Unmute ADC0 and set the default input to mic-in
15006 */
15007 /* port-A for surround (rear panel) */
15008 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15009 /* port-B for mic-in (rear panel) with vref */
15010 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15011 /* port-C for line-in (rear panel) */
15012 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15013 /* port-D for Front */
15014 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15015 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15016 /* port-E for HP out (front panel) */
15017 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15018 /* route front PCM to HP */
9dece1d7 15019 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15020 /* port-F for mic-in (front panel) with vref */
15021 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15022 /* port-G for CLFE (rear panel) */
15023 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15024 /* port-H for side (rear panel) */
15025 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15026 /* CD-in */
15027 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15028 /* route front mic to ADC1*/
15029 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15030 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15031 /* Unmute DAC0~3 & spdif out*/
15032 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15033 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15034 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15035 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15036 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15037
df694daa
KY
15038 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15039 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15040 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15041 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15042 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15043
df694daa
KY
15044 /* Unmute Stereo Mixer 15 */
15045 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15046 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15047 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15048 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15049
15050 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15051 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15052 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15053 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15054 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15055 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15056 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15057 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15058 /* hp used DAC 3 (Front) */
15059 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15060 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15061 { }
15062};
22309c3e
TI
15063
15064static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15065 /*
15066 * Unmute ADC0 and set the default input to mic-in
15067 */
15068 /* port-A for surround (rear panel) */
15069 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15070 /* port-B for mic-in (rear panel) with vref */
15071 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15072 /* port-C for line-in (rear panel) */
15073 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15074 /* port-D for Front */
15075 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15076 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15077 /* port-E for HP out (front panel) */
f12ab1e0
TI
15078 /* this has to be set to VREF80 */
15079 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15080 /* route front PCM to HP */
9dece1d7 15081 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15082 /* port-F for mic-in (front panel) with vref */
15083 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15084 /* port-G for CLFE (rear panel) */
15085 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15086 /* port-H for side (rear panel) */
15087 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15088 /* CD-in */
15089 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15090 /* route front mic to ADC1*/
15091 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15092 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15093 /* Unmute DAC0~3 & spdif out*/
15094 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15095 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15096 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15097 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15098 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15099
22309c3e
TI
15100 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15101 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15102 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15103 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15104 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15105
22309c3e
TI
15106 /* Unmute Stereo Mixer 15 */
15107 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15108 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15109 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15110 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15111
15112 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15113 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15114 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15115 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15116 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15117 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15118 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15119 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15120 /* hp used DAC 3 (Front) */
15121 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15122 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15123 { }
15124};
15125
7cdbff94
MD
15126static struct hda_verb alc861_asus_init_verbs[] = {
15127 /*
15128 * Unmute ADC0 and set the default input to mic-in
15129 */
f12ab1e0
TI
15130 /* port-A for surround (rear panel)
15131 * according to codec#0 this is the HP jack
15132 */
7cdbff94
MD
15133 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15134 /* route front PCM to HP */
15135 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15136 /* port-B for mic-in (rear panel) with vref */
15137 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15138 /* port-C for line-in (rear panel) */
15139 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15140 /* port-D for Front */
15141 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15142 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15143 /* port-E for HP out (front panel) */
f12ab1e0
TI
15144 /* this has to be set to VREF80 */
15145 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15146 /* route front PCM to HP */
9dece1d7 15147 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15148 /* port-F for mic-in (front panel) with vref */
15149 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15150 /* port-G for CLFE (rear panel) */
15151 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15152 /* port-H for side (rear panel) */
15153 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15154 /* CD-in */
15155 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15156 /* route front mic to ADC1*/
15157 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15158 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15159 /* Unmute DAC0~3 & spdif out*/
15160 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15161 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15162 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15163 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15164 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15165 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15166 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15167 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15168 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15169 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15170
7cdbff94
MD
15171 /* Unmute Stereo Mixer 15 */
15172 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15173 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15174 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15175 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15176
15177 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15178 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15179 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15180 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15181 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15182 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15183 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15184 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15185 /* hp used DAC 3 (Front) */
15186 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15187 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15188 { }
15189};
15190
56bb0cab
TI
15191/* additional init verbs for ASUS laptops */
15192static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15193 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15194 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15195 { }
15196};
7cdbff94 15197
df694daa
KY
15198/*
15199 * generic initialization of ADC, input mixers and output mixers
15200 */
15201static struct hda_verb alc861_auto_init_verbs[] = {
15202 /*
15203 * Unmute ADC0 and set the default input to mic-in
15204 */
f12ab1e0 15205 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15206 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15207
df694daa
KY
15208 /* Unmute DAC0~3 & spdif out*/
15209 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15210 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15211 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15212 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15213 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15214
df694daa
KY
15215 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15216 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15217 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15218 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15219 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15220
df694daa
KY
15221 /* Unmute Stereo Mixer 15 */
15222 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15223 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15224 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15226
1c20930a
TI
15227 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15228 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15229 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15230 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15231 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15232 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15233 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15234 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15235
15236 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15237 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15238 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15239 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15240 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15241 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15242 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15243 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15244
f12ab1e0 15245 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15246
15247 { }
15248};
15249
a53d1aec
TD
15250static struct hda_verb alc861_toshiba_init_verbs[] = {
15251 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15252
a53d1aec
TD
15253 { }
15254};
15255
15256/* toggle speaker-output according to the hp-jack state */
15257static void alc861_toshiba_automute(struct hda_codec *codec)
15258{
864f92be 15259 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15260
47fd830a
TI
15261 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15262 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15263 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15264 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15265}
15266
15267static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15268 unsigned int res)
15269{
a53d1aec
TD
15270 if ((res >> 26) == ALC880_HP_EVENT)
15271 alc861_toshiba_automute(codec);
15272}
15273
def319f9 15274/* pcm configuration: identical with ALC880 */
df694daa
KY
15275#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15276#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15277#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15278#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15279
15280
15281#define ALC861_DIGOUT_NID 0x07
15282
15283static struct hda_channel_mode alc861_8ch_modes[1] = {
15284 { 8, NULL }
15285};
15286
15287static hda_nid_t alc861_dac_nids[4] = {
15288 /* front, surround, clfe, side */
15289 0x03, 0x06, 0x05, 0x04
15290};
15291
9c7f852e
TI
15292static hda_nid_t alc660_dac_nids[3] = {
15293 /* front, clfe, surround */
15294 0x03, 0x05, 0x06
15295};
15296
df694daa
KY
15297static hda_nid_t alc861_adc_nids[1] = {
15298 /* ADC0-2 */
15299 0x08,
15300};
15301
15302static struct hda_input_mux alc861_capture_source = {
15303 .num_items = 5,
15304 .items = {
15305 { "Mic", 0x0 },
15306 { "Front Mic", 0x3 },
15307 { "Line", 0x1 },
15308 { "CD", 0x4 },
15309 { "Mixer", 0x5 },
15310 },
15311};
15312
1c20930a
TI
15313static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15314{
15315 struct alc_spec *spec = codec->spec;
15316 hda_nid_t mix, srcs[5];
15317 int i, j, num;
15318
15319 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15320 return 0;
15321 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15322 if (num < 0)
15323 return 0;
15324 for (i = 0; i < num; i++) {
15325 unsigned int type;
a22d543a 15326 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15327 if (type != AC_WID_AUD_OUT)
15328 continue;
15329 for (j = 0; j < spec->multiout.num_dacs; j++)
15330 if (spec->multiout.dac_nids[j] == srcs[i])
15331 break;
15332 if (j >= spec->multiout.num_dacs)
15333 return srcs[i];
15334 }
15335 return 0;
15336}
15337
df694daa 15338/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15339static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15340 const struct auto_pin_cfg *cfg)
df694daa 15341{
1c20930a 15342 struct alc_spec *spec = codec->spec;
df694daa 15343 int i;
1c20930a 15344 hda_nid_t nid, dac;
df694daa
KY
15345
15346 spec->multiout.dac_nids = spec->private_dac_nids;
15347 for (i = 0; i < cfg->line_outs; i++) {
15348 nid = cfg->line_out_pins[i];
1c20930a
TI
15349 dac = alc861_look_for_dac(codec, nid);
15350 if (!dac)
15351 continue;
15352 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15353 }
df694daa
KY
15354 return 0;
15355}
15356
1c20930a
TI
15357static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15358 hda_nid_t nid, unsigned int chs)
15359{
0afe5f89 15360 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
1c20930a
TI
15361 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15362}
15363
df694daa 15364/* add playback controls from the parsed DAC table */
1c20930a 15365static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15366 const struct auto_pin_cfg *cfg)
15367{
1c20930a 15368 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
15369 static const char *chname[4] = {
15370 "Front", "Surround", NULL /*CLFE*/, "Side"
15371 };
df694daa 15372 hda_nid_t nid;
1c20930a
TI
15373 int i, err;
15374
15375 if (cfg->line_outs == 1) {
15376 const char *pfx = NULL;
15377 if (!cfg->hp_outs)
15378 pfx = "Master";
15379 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15380 pfx = "Speaker";
15381 if (pfx) {
15382 nid = spec->multiout.dac_nids[0];
15383 return alc861_create_out_sw(codec, pfx, nid, 3);
15384 }
15385 }
df694daa
KY
15386
15387 for (i = 0; i < cfg->line_outs; i++) {
15388 nid = spec->multiout.dac_nids[i];
f12ab1e0 15389 if (!nid)
df694daa 15390 continue;
1c20930a 15391 if (i == 2) {
df694daa 15392 /* Center/LFE */
1c20930a 15393 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15394 if (err < 0)
df694daa 15395 return err;
1c20930a 15396 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15397 if (err < 0)
df694daa
KY
15398 return err;
15399 } else {
1c20930a 15400 err = alc861_create_out_sw(codec, chname[i], nid, 3);
f12ab1e0 15401 if (err < 0)
df694daa
KY
15402 return err;
15403 }
15404 }
15405 return 0;
15406}
15407
1c20930a 15408static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 15409{
1c20930a 15410 struct alc_spec *spec = codec->spec;
df694daa
KY
15411 int err;
15412 hda_nid_t nid;
15413
f12ab1e0 15414 if (!pin)
df694daa
KY
15415 return 0;
15416
15417 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
15418 nid = alc861_look_for_dac(codec, pin);
15419 if (nid) {
15420 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15421 if (err < 0)
15422 return err;
15423 spec->multiout.hp_nid = nid;
15424 }
df694daa
KY
15425 }
15426 return 0;
15427}
15428
15429/* create playback/capture controls for input pins */
05f5f477 15430static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 15431 const struct auto_pin_cfg *cfg)
df694daa 15432{
05f5f477 15433 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
15434}
15435
f12ab1e0
TI
15436static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15437 hda_nid_t nid,
1c20930a 15438 int pin_type, hda_nid_t dac)
df694daa 15439{
1c20930a
TI
15440 hda_nid_t mix, srcs[5];
15441 int i, num;
15442
564c5bea
JL
15443 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15444 pin_type);
1c20930a 15445 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 15446 AMP_OUT_UNMUTE);
1c20930a
TI
15447 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15448 return;
15449 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15450 if (num < 0)
15451 return;
15452 for (i = 0; i < num; i++) {
15453 unsigned int mute;
15454 if (srcs[i] == dac || srcs[i] == 0x15)
15455 mute = AMP_IN_UNMUTE(i);
15456 else
15457 mute = AMP_IN_MUTE(i);
15458 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15459 mute);
15460 }
df694daa
KY
15461}
15462
15463static void alc861_auto_init_multi_out(struct hda_codec *codec)
15464{
15465 struct alc_spec *spec = codec->spec;
15466 int i;
15467
15468 for (i = 0; i < spec->autocfg.line_outs; i++) {
15469 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 15470 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 15471 if (nid)
baba8ee9 15472 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 15473 spec->multiout.dac_nids[i]);
df694daa
KY
15474 }
15475}
15476
15477static void alc861_auto_init_hp_out(struct hda_codec *codec)
15478{
15479 struct alc_spec *spec = codec->spec;
df694daa 15480
15870f05
TI
15481 if (spec->autocfg.hp_outs)
15482 alc861_auto_set_output_and_unmute(codec,
15483 spec->autocfg.hp_pins[0],
15484 PIN_HP,
1c20930a 15485 spec->multiout.hp_nid);
15870f05
TI
15486 if (spec->autocfg.speaker_outs)
15487 alc861_auto_set_output_and_unmute(codec,
15488 spec->autocfg.speaker_pins[0],
15489 PIN_OUT,
1c20930a 15490 spec->multiout.dac_nids[0]);
df694daa
KY
15491}
15492
15493static void alc861_auto_init_analog_input(struct hda_codec *codec)
15494{
15495 struct alc_spec *spec = codec->spec;
15496 int i;
15497
15498 for (i = 0; i < AUTO_PIN_LAST; i++) {
15499 hda_nid_t nid = spec->autocfg.input_pins[i];
23f0c048
TI
15500 if (nid >= 0x0c && nid <= 0x11)
15501 alc_set_input_pin(codec, nid, i);
df694daa
KY
15502 }
15503}
15504
15505/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
15506/* return 1 if successful, 0 if the proper config is not found,
15507 * or a negative error code
15508 */
df694daa
KY
15509static int alc861_parse_auto_config(struct hda_codec *codec)
15510{
15511 struct alc_spec *spec = codec->spec;
15512 int err;
15513 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
15514
f12ab1e0
TI
15515 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15516 alc861_ignore);
15517 if (err < 0)
df694daa 15518 return err;
f12ab1e0 15519 if (!spec->autocfg.line_outs)
df694daa
KY
15520 return 0; /* can't find valid BIOS pin config */
15521
1c20930a 15522 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
15523 if (err < 0)
15524 return err;
1c20930a 15525 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
15526 if (err < 0)
15527 return err;
1c20930a 15528 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
15529 if (err < 0)
15530 return err;
05f5f477 15531 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 15532 if (err < 0)
df694daa
KY
15533 return err;
15534
15535 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15536
757899ac 15537 alc_auto_parse_digital(codec);
df694daa 15538
603c4019 15539 if (spec->kctls.list)
d88897ea 15540 add_mixer(spec, spec->kctls.list);
df694daa 15541
d88897ea 15542 add_verb(spec, alc861_auto_init_verbs);
df694daa 15543
a1e8d2da 15544 spec->num_mux_defs = 1;
61b9b9b1 15545 spec->input_mux = &spec->private_imux[0];
df694daa
KY
15546
15547 spec->adc_nids = alc861_adc_nids;
15548 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 15549 set_capture_mixer(codec);
df694daa 15550
6227cdce 15551 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 15552
df694daa
KY
15553 return 1;
15554}
15555
ae6b813a
TI
15556/* additional initialization for auto-configuration model */
15557static void alc861_auto_init(struct hda_codec *codec)
df694daa 15558{
f6c7e546 15559 struct alc_spec *spec = codec->spec;
df694daa
KY
15560 alc861_auto_init_multi_out(codec);
15561 alc861_auto_init_hp_out(codec);
15562 alc861_auto_init_analog_input(codec);
757899ac 15563 alc_auto_init_digital(codec);
f6c7e546 15564 if (spec->unsol_event)
7fb0d78f 15565 alc_inithook(codec);
df694daa
KY
15566}
15567
cb53c626
TI
15568#ifdef CONFIG_SND_HDA_POWER_SAVE
15569static struct hda_amp_list alc861_loopbacks[] = {
15570 { 0x15, HDA_INPUT, 0 },
15571 { 0x15, HDA_INPUT, 1 },
15572 { 0x15, HDA_INPUT, 2 },
15573 { 0x15, HDA_INPUT, 3 },
15574 { } /* end */
15575};
15576#endif
15577
df694daa
KY
15578
15579/*
15580 * configuration and preset
15581 */
f5fcc13c
TI
15582static const char *alc861_models[ALC861_MODEL_LAST] = {
15583 [ALC861_3ST] = "3stack",
15584 [ALC660_3ST] = "3stack-660",
15585 [ALC861_3ST_DIG] = "3stack-dig",
15586 [ALC861_6ST_DIG] = "6stack-dig",
15587 [ALC861_UNIWILL_M31] = "uniwill-m31",
15588 [ALC861_TOSHIBA] = "toshiba",
15589 [ALC861_ASUS] = "asus",
15590 [ALC861_ASUS_LAPTOP] = "asus-laptop",
15591 [ALC861_AUTO] = "auto",
15592};
15593
15594static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 15595 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
15596 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15597 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15598 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 15599 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 15600 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 15601 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
15602 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
15603 * Any other models that need this preset?
15604 */
15605 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
15606 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
15607 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 15608 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
15609 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
15610 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
15611 /* FIXME: the below seems conflict */
15612 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 15613 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 15614 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
15615 {}
15616};
15617
15618static struct alc_config_preset alc861_presets[] = {
15619 [ALC861_3ST] = {
15620 .mixers = { alc861_3ST_mixer },
15621 .init_verbs = { alc861_threestack_init_verbs },
15622 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15623 .dac_nids = alc861_dac_nids,
15624 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15625 .channel_mode = alc861_threestack_modes,
4e195a7b 15626 .need_dac_fix = 1,
df694daa
KY
15627 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15628 .adc_nids = alc861_adc_nids,
15629 .input_mux = &alc861_capture_source,
15630 },
15631 [ALC861_3ST_DIG] = {
15632 .mixers = { alc861_base_mixer },
15633 .init_verbs = { alc861_threestack_init_verbs },
15634 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15635 .dac_nids = alc861_dac_nids,
15636 .dig_out_nid = ALC861_DIGOUT_NID,
15637 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15638 .channel_mode = alc861_threestack_modes,
4e195a7b 15639 .need_dac_fix = 1,
df694daa
KY
15640 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15641 .adc_nids = alc861_adc_nids,
15642 .input_mux = &alc861_capture_source,
15643 },
15644 [ALC861_6ST_DIG] = {
15645 .mixers = { alc861_base_mixer },
15646 .init_verbs = { alc861_base_init_verbs },
15647 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15648 .dac_nids = alc861_dac_nids,
15649 .dig_out_nid = ALC861_DIGOUT_NID,
15650 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
15651 .channel_mode = alc861_8ch_modes,
15652 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15653 .adc_nids = alc861_adc_nids,
15654 .input_mux = &alc861_capture_source,
15655 },
9c7f852e
TI
15656 [ALC660_3ST] = {
15657 .mixers = { alc861_3ST_mixer },
15658 .init_verbs = { alc861_threestack_init_verbs },
15659 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
15660 .dac_nids = alc660_dac_nids,
15661 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15662 .channel_mode = alc861_threestack_modes,
4e195a7b 15663 .need_dac_fix = 1,
9c7f852e
TI
15664 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15665 .adc_nids = alc861_adc_nids,
15666 .input_mux = &alc861_capture_source,
15667 },
22309c3e
TI
15668 [ALC861_UNIWILL_M31] = {
15669 .mixers = { alc861_uniwill_m31_mixer },
15670 .init_verbs = { alc861_uniwill_m31_init_verbs },
15671 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15672 .dac_nids = alc861_dac_nids,
15673 .dig_out_nid = ALC861_DIGOUT_NID,
15674 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
15675 .channel_mode = alc861_uniwill_m31_modes,
15676 .need_dac_fix = 1,
15677 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15678 .adc_nids = alc861_adc_nids,
15679 .input_mux = &alc861_capture_source,
15680 },
a53d1aec
TD
15681 [ALC861_TOSHIBA] = {
15682 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
15683 .init_verbs = { alc861_base_init_verbs,
15684 alc861_toshiba_init_verbs },
a53d1aec
TD
15685 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15686 .dac_nids = alc861_dac_nids,
15687 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15688 .channel_mode = alc883_3ST_2ch_modes,
15689 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15690 .adc_nids = alc861_adc_nids,
15691 .input_mux = &alc861_capture_source,
15692 .unsol_event = alc861_toshiba_unsol_event,
15693 .init_hook = alc861_toshiba_automute,
15694 },
7cdbff94
MD
15695 [ALC861_ASUS] = {
15696 .mixers = { alc861_asus_mixer },
15697 .init_verbs = { alc861_asus_init_verbs },
15698 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15699 .dac_nids = alc861_dac_nids,
15700 .dig_out_nid = ALC861_DIGOUT_NID,
15701 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
15702 .channel_mode = alc861_asus_modes,
15703 .need_dac_fix = 1,
15704 .hp_nid = 0x06,
15705 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15706 .adc_nids = alc861_adc_nids,
15707 .input_mux = &alc861_capture_source,
15708 },
56bb0cab
TI
15709 [ALC861_ASUS_LAPTOP] = {
15710 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
15711 .init_verbs = { alc861_asus_init_verbs,
15712 alc861_asus_laptop_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(alc883_3ST_2ch_modes),
15717 .channel_mode = alc883_3ST_2ch_modes,
15718 .need_dac_fix = 1,
15719 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15720 .adc_nids = alc861_adc_nids,
15721 .input_mux = &alc861_capture_source,
15722 },
15723};
df694daa 15724
cfc9b06f
TI
15725/* Pin config fixes */
15726enum {
15727 PINFIX_FSC_AMILO_PI1505,
15728};
15729
15730static struct alc_pincfg alc861_fsc_amilo_pi1505_pinfix[] = {
15731 { 0x0b, 0x0221101f }, /* HP */
15732 { 0x0f, 0x90170310 }, /* speaker */
15733 { }
15734};
15735
15736static const struct alc_fixup alc861_fixups[] = {
15737 [PINFIX_FSC_AMILO_PI1505] = {
15738 .pins = alc861_fsc_amilo_pi1505_pinfix
15739 },
15740};
15741
15742static struct snd_pci_quirk alc861_fixup_tbl[] = {
15743 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
15744 {}
15745};
df694daa
KY
15746
15747static int patch_alc861(struct hda_codec *codec)
15748{
15749 struct alc_spec *spec;
15750 int board_config;
15751 int err;
15752
dc041e0b 15753 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
15754 if (spec == NULL)
15755 return -ENOMEM;
15756
f12ab1e0 15757 codec->spec = spec;
df694daa 15758
f5fcc13c
TI
15759 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
15760 alc861_models,
15761 alc861_cfg_tbl);
9c7f852e 15762
f5fcc13c 15763 if (board_config < 0) {
9a11f1aa
TI
15764 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15765 codec->chip_name);
df694daa
KY
15766 board_config = ALC861_AUTO;
15767 }
15768
7fa90e87
TI
15769 if (board_config == ALC861_AUTO)
15770 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
cfc9b06f 15771
df694daa
KY
15772 if (board_config == ALC861_AUTO) {
15773 /* automatic parse from the BIOS config */
15774 err = alc861_parse_auto_config(codec);
15775 if (err < 0) {
15776 alc_free(codec);
15777 return err;
f12ab1e0 15778 } else if (!err) {
9c7f852e
TI
15779 printk(KERN_INFO
15780 "hda_codec: Cannot set up configuration "
15781 "from BIOS. Using base mode...\n");
df694daa
KY
15782 board_config = ALC861_3ST_DIG;
15783 }
15784 }
15785
680cd536
KK
15786 err = snd_hda_attach_beep_device(codec, 0x23);
15787 if (err < 0) {
15788 alc_free(codec);
15789 return err;
15790 }
15791
df694daa 15792 if (board_config != ALC861_AUTO)
e9c364c0 15793 setup_preset(codec, &alc861_presets[board_config]);
df694daa 15794
df694daa
KY
15795 spec->stream_analog_playback = &alc861_pcm_analog_playback;
15796 spec->stream_analog_capture = &alc861_pcm_analog_capture;
15797
df694daa
KY
15798 spec->stream_digital_playback = &alc861_pcm_digital_playback;
15799 spec->stream_digital_capture = &alc861_pcm_digital_capture;
15800
c7a8eb10
TI
15801 if (!spec->cap_mixer)
15802 set_capture_mixer(codec);
45bdd1c1
TI
15803 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
15804
2134ea4f
TI
15805 spec->vmaster_nid = 0x03;
15806
7fa90e87
TI
15807 if (board_config == ALC861_AUTO)
15808 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
15809
df694daa 15810 codec->patch_ops = alc_patch_ops;
c97259df 15811 if (board_config == ALC861_AUTO) {
ae6b813a 15812 spec->init_hook = alc861_auto_init;
c97259df
DC
15813#ifdef CONFIG_SND_HDA_POWER_SAVE
15814 spec->power_hook = alc_power_eapd;
15815#endif
15816 }
cb53c626
TI
15817#ifdef CONFIG_SND_HDA_POWER_SAVE
15818 if (!spec->loopback.amplist)
15819 spec->loopback.amplist = alc861_loopbacks;
15820#endif
ea1fb29a 15821
1da177e4
LT
15822 return 0;
15823}
15824
f32610ed
JS
15825/*
15826 * ALC861-VD support
15827 *
15828 * Based on ALC882
15829 *
15830 * In addition, an independent DAC
15831 */
15832#define ALC861VD_DIGOUT_NID 0x06
15833
15834static hda_nid_t alc861vd_dac_nids[4] = {
15835 /* front, surr, clfe, side surr */
15836 0x02, 0x03, 0x04, 0x05
15837};
15838
15839/* dac_nids for ALC660vd are in a different order - according to
15840 * Realtek's driver.
def319f9 15841 * This should probably result in a different mixer for 6stack models
f32610ed
JS
15842 * of ALC660vd codecs, but for now there is only 3stack mixer
15843 * - and it is the same as in 861vd.
15844 * adc_nids in ALC660vd are (is) the same as in 861vd
15845 */
15846static hda_nid_t alc660vd_dac_nids[3] = {
15847 /* front, rear, clfe, rear_surr */
15848 0x02, 0x04, 0x03
15849};
15850
15851static hda_nid_t alc861vd_adc_nids[1] = {
15852 /* ADC0 */
15853 0x09,
15854};
15855
e1406348
TI
15856static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
15857
f32610ed
JS
15858/* input MUX */
15859/* FIXME: should be a matrix-type input source selection */
15860static struct hda_input_mux alc861vd_capture_source = {
15861 .num_items = 4,
15862 .items = {
15863 { "Mic", 0x0 },
15864 { "Front Mic", 0x1 },
15865 { "Line", 0x2 },
15866 { "CD", 0x4 },
15867 },
15868};
15869
272a527c 15870static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 15871 .num_items = 2,
272a527c 15872 .items = {
b419f346
TD
15873 { "Ext Mic", 0x0 },
15874 { "Int Mic", 0x1 },
272a527c
KY
15875 },
15876};
15877
d1a991a6
KY
15878static struct hda_input_mux alc861vd_hp_capture_source = {
15879 .num_items = 2,
15880 .items = {
15881 { "Front Mic", 0x0 },
15882 { "ATAPI Mic", 0x1 },
15883 },
15884};
15885
f32610ed
JS
15886/*
15887 * 2ch mode
15888 */
15889static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
15890 { 2, NULL }
15891};
15892
15893/*
15894 * 6ch mode
15895 */
15896static struct hda_verb alc861vd_6stack_ch6_init[] = {
15897 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15898 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15899 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15900 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15901 { } /* end */
15902};
15903
15904/*
15905 * 8ch mode
15906 */
15907static struct hda_verb alc861vd_6stack_ch8_init[] = {
15908 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15909 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15910 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15911 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15912 { } /* end */
15913};
15914
15915static struct hda_channel_mode alc861vd_6stack_modes[2] = {
15916 { 6, alc861vd_6stack_ch6_init },
15917 { 8, alc861vd_6stack_ch8_init },
15918};
15919
15920static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
15921 {
15922 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15923 .name = "Channel Mode",
15924 .info = alc_ch_mode_info,
15925 .get = alc_ch_mode_get,
15926 .put = alc_ch_mode_put,
15927 },
15928 { } /* end */
15929};
15930
f32610ed
JS
15931/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15932 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15933 */
15934static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
15935 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15936 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15937
15938 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15939 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
15940
15941 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
15942 HDA_OUTPUT),
15943 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
15944 HDA_OUTPUT),
15945 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
15946 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
15947
15948 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
15949 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
15950
15951 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15952
15953 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15954 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15955 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15956
15957 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15958 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15959 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15960
15961 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15962 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15963
15964 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15965 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15966
f32610ed
JS
15967 { } /* end */
15968};
15969
15970static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
15971 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15972 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15973
15974 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15975
15976 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15977 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15978 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15979
15980 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15981 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15982 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15983
15984 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15985 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15986
15987 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15988 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15989
f32610ed
JS
15990 { } /* end */
15991};
15992
bdd148a3
KY
15993static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
15994 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15995 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
15996 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15997
15998 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15999
16000 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
16001 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16002 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16003
16004 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
16005 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16006 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16007
16008 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16009 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16010
16011 { } /* end */
16012};
16013
b419f346
TD
16014/* Pin assignment: Speaker=0x14, HP = 0x15,
16015 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
16016 */
16017static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16018 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16019 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16020 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16021 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
16022 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16023 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16024 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16025 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16026 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16027 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16028 { } /* end */
16029};
16030
d1a991a6
KY
16031/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16032 * Front Mic=0x18, ATAPI Mic = 0x19,
16033 */
16034static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16035 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16036 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16037 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16038 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16039 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16040 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16041 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16042 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16043
d1a991a6
KY
16044 { } /* end */
16045};
16046
f32610ed
JS
16047/*
16048 * generic initialization of ADC, input mixers and output mixers
16049 */
16050static struct hda_verb alc861vd_volume_init_verbs[] = {
16051 /*
16052 * Unmute ADC0 and set the default input to mic-in
16053 */
16054 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16055 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16056
16057 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16058 * the analog-loopback mixer widget
16059 */
16060 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16061 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16062 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16063 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16064 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16065 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16066
16067 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16068 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16069 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16070 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16071 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16072
16073 /*
16074 * Set up output mixers (0x02 - 0x05)
16075 */
16076 /* set vol=0 to output mixers */
16077 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16078 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16079 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16080 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16081
16082 /* set up input amps for analog loopback */
16083 /* Amp Indices: DAC = 0, mixer = 1 */
16084 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16085 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16086 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16087 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16088 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16089 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16090 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16091 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16092
16093 { }
16094};
16095
16096/*
16097 * 3-stack pin configuration:
16098 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16099 */
16100static struct hda_verb alc861vd_3stack_init_verbs[] = {
16101 /*
16102 * Set pin mode and muting
16103 */
16104 /* set front pin widgets 0x14 for output */
16105 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16106 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16107 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16108
16109 /* Mic (rear) pin: input vref at 80% */
16110 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16111 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16112 /* Front Mic pin: input vref at 80% */
16113 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16114 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16115 /* Line In pin: input */
16116 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16117 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16118 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16119 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16120 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16121 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16122 /* CD pin widget for input */
16123 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16124
16125 { }
16126};
16127
16128/*
16129 * 6-stack pin configuration:
16130 */
16131static struct hda_verb alc861vd_6stack_init_verbs[] = {
16132 /*
16133 * Set pin mode and muting
16134 */
16135 /* set front pin widgets 0x14 for output */
16136 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16137 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16138 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16139
16140 /* Rear Pin: output 1 (0x0d) */
16141 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16142 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16143 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16144 /* CLFE Pin: output 2 (0x0e) */
16145 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16146 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16147 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16148 /* Side Pin: output 3 (0x0f) */
16149 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16150 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16151 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16152
16153 /* Mic (rear) pin: input vref at 80% */
16154 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16155 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16156 /* Front Mic pin: input vref at 80% */
16157 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16158 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16159 /* Line In pin: input */
16160 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16161 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16162 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16163 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16164 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16165 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16166 /* CD pin widget for input */
16167 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16168
16169 { }
16170};
16171
bdd148a3
KY
16172static struct hda_verb alc861vd_eapd_verbs[] = {
16173 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16174 { }
16175};
16176
f9423e7a
KY
16177static struct hda_verb alc660vd_eapd_verbs[] = {
16178 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16179 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16180 { }
16181};
16182
bdd148a3
KY
16183static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16184 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16185 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16186 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16187 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16188 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16189 {}
16190};
16191
bdd148a3
KY
16192static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
16193{
16194 unsigned int present;
16195 unsigned char bits;
16196
864f92be 16197 present = snd_hda_jack_detect(codec, 0x18);
47fd830a 16198 bits = present ? HDA_AMP_MUTE : 0;
864f92be 16199
47fd830a
TI
16200 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
16201 HDA_AMP_MUTE, bits);
bdd148a3
KY
16202}
16203
4f5d1706 16204static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16205{
a9fd4f3f 16206 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16207 spec->autocfg.hp_pins[0] = 0x1b;
16208 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
16209}
16210
16211static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16212{
a9fd4f3f 16213 alc_automute_amp(codec);
bdd148a3
KY
16214 alc861vd_lenovo_mic_automute(codec);
16215}
16216
16217static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16218 unsigned int res)
16219{
16220 switch (res >> 26) {
bdd148a3
KY
16221 case ALC880_MIC_EVENT:
16222 alc861vd_lenovo_mic_automute(codec);
16223 break;
a9fd4f3f
TI
16224 default:
16225 alc_automute_amp_unsol_event(codec, res);
16226 break;
bdd148a3
KY
16227 }
16228}
16229
272a527c
KY
16230static struct hda_verb alc861vd_dallas_verbs[] = {
16231 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16232 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16233 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16234 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16235
16236 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16237 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16238 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16239 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16240 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16241 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16242 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16243 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16244
272a527c
KY
16245 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16246 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16247 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16248 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16249 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16250 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16251 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16252 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16253
16254 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16255 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16256 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16257 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16258 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16259 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16260 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16261 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16262
16263 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16264 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16265 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16266 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16267
16268 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16269 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16270 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16271
16272 { } /* end */
16273};
16274
16275/* toggle speaker-output according to the hp-jack state */
4f5d1706 16276static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16277{
a9fd4f3f 16278 struct alc_spec *spec = codec->spec;
272a527c 16279
a9fd4f3f
TI
16280 spec->autocfg.hp_pins[0] = 0x15;
16281 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
16282}
16283
cb53c626
TI
16284#ifdef CONFIG_SND_HDA_POWER_SAVE
16285#define alc861vd_loopbacks alc880_loopbacks
16286#endif
16287
def319f9 16288/* pcm configuration: identical with ALC880 */
f32610ed
JS
16289#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16290#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16291#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16292#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16293
16294/*
16295 * configuration and preset
16296 */
16297static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
16298 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16299 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16300 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16301 [ALC861VD_3ST] = "3stack",
16302 [ALC861VD_3ST_DIG] = "3stack-digout",
16303 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16304 [ALC861VD_LENOVO] = "lenovo",
272a527c 16305 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16306 [ALC861VD_HP] = "hp",
f32610ed
JS
16307 [ALC861VD_AUTO] = "auto",
16308};
16309
16310static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16311 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16312 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16313 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16314 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16315 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16316 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16317 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16318 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16319 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16320 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16321 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16322 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16323 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16324 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16325 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16326 {}
16327};
16328
16329static struct alc_config_preset alc861vd_presets[] = {
16330 [ALC660VD_3ST] = {
16331 .mixers = { alc861vd_3st_mixer },
16332 .init_verbs = { alc861vd_volume_init_verbs,
16333 alc861vd_3stack_init_verbs },
16334 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16335 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16336 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16337 .channel_mode = alc861vd_3stack_2ch_modes,
16338 .input_mux = &alc861vd_capture_source,
16339 },
6963f84c
MC
16340 [ALC660VD_3ST_DIG] = {
16341 .mixers = { alc861vd_3st_mixer },
16342 .init_verbs = { alc861vd_volume_init_verbs,
16343 alc861vd_3stack_init_verbs },
16344 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16345 .dac_nids = alc660vd_dac_nids,
16346 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16347 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16348 .channel_mode = alc861vd_3stack_2ch_modes,
16349 .input_mux = &alc861vd_capture_source,
16350 },
f32610ed
JS
16351 [ALC861VD_3ST] = {
16352 .mixers = { alc861vd_3st_mixer },
16353 .init_verbs = { alc861vd_volume_init_verbs,
16354 alc861vd_3stack_init_verbs },
16355 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16356 .dac_nids = alc861vd_dac_nids,
16357 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16358 .channel_mode = alc861vd_3stack_2ch_modes,
16359 .input_mux = &alc861vd_capture_source,
16360 },
16361 [ALC861VD_3ST_DIG] = {
16362 .mixers = { alc861vd_3st_mixer },
16363 .init_verbs = { alc861vd_volume_init_verbs,
16364 alc861vd_3stack_init_verbs },
16365 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16366 .dac_nids = alc861vd_dac_nids,
16367 .dig_out_nid = ALC861VD_DIGOUT_NID,
16368 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16369 .channel_mode = alc861vd_3stack_2ch_modes,
16370 .input_mux = &alc861vd_capture_source,
16371 },
16372 [ALC861VD_6ST_DIG] = {
16373 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16374 .init_verbs = { alc861vd_volume_init_verbs,
16375 alc861vd_6stack_init_verbs },
16376 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16377 .dac_nids = alc861vd_dac_nids,
16378 .dig_out_nid = ALC861VD_DIGOUT_NID,
16379 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16380 .channel_mode = alc861vd_6stack_modes,
16381 .input_mux = &alc861vd_capture_source,
16382 },
bdd148a3
KY
16383 [ALC861VD_LENOVO] = {
16384 .mixers = { alc861vd_lenovo_mixer },
16385 .init_verbs = { alc861vd_volume_init_verbs,
16386 alc861vd_3stack_init_verbs,
16387 alc861vd_eapd_verbs,
16388 alc861vd_lenovo_unsol_verbs },
16389 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16390 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16391 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16392 .channel_mode = alc861vd_3stack_2ch_modes,
16393 .input_mux = &alc861vd_capture_source,
16394 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16395 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16396 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16397 },
272a527c
KY
16398 [ALC861VD_DALLAS] = {
16399 .mixers = { alc861vd_dallas_mixer },
16400 .init_verbs = { alc861vd_dallas_verbs },
16401 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16402 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16403 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16404 .channel_mode = alc861vd_3stack_2ch_modes,
16405 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 16406 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16407 .setup = alc861vd_dallas_setup,
16408 .init_hook = alc_automute_amp,
d1a991a6
KY
16409 },
16410 [ALC861VD_HP] = {
16411 .mixers = { alc861vd_hp_mixer },
16412 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16413 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16414 .dac_nids = alc861vd_dac_nids,
d1a991a6 16415 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
16416 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16417 .channel_mode = alc861vd_3stack_2ch_modes,
16418 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 16419 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16420 .setup = alc861vd_dallas_setup,
16421 .init_hook = alc_automute_amp,
ea1fb29a 16422 },
13c94744
TI
16423 [ALC660VD_ASUS_V1S] = {
16424 .mixers = { alc861vd_lenovo_mixer },
16425 .init_verbs = { alc861vd_volume_init_verbs,
16426 alc861vd_3stack_init_verbs,
16427 alc861vd_eapd_verbs,
16428 alc861vd_lenovo_unsol_verbs },
16429 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16430 .dac_nids = alc660vd_dac_nids,
16431 .dig_out_nid = ALC861VD_DIGOUT_NID,
16432 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16433 .channel_mode = alc861vd_3stack_2ch_modes,
16434 .input_mux = &alc861vd_capture_source,
16435 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16436 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16437 .init_hook = alc861vd_lenovo_init_hook,
13c94744 16438 },
f32610ed
JS
16439};
16440
16441/*
16442 * BIOS auto configuration
16443 */
05f5f477
TI
16444static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16445 const struct auto_pin_cfg *cfg)
16446{
6227cdce 16447 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
05f5f477
TI
16448}
16449
16450
f32610ed
JS
16451static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
16452 hda_nid_t nid, int pin_type, int dac_idx)
16453{
f6c7e546 16454 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
16455}
16456
16457static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
16458{
16459 struct alc_spec *spec = codec->spec;
16460 int i;
16461
16462 for (i = 0; i <= HDA_SIDE; i++) {
16463 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16464 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
16465 if (nid)
16466 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 16467 pin_type, i);
f32610ed
JS
16468 }
16469}
16470
16471
16472static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
16473{
16474 struct alc_spec *spec = codec->spec;
16475 hda_nid_t pin;
16476
16477 pin = spec->autocfg.hp_pins[0];
def319f9 16478 if (pin) /* connect to front and use dac 0 */
f32610ed 16479 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
16480 pin = spec->autocfg.speaker_pins[0];
16481 if (pin)
16482 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
16483}
16484
f32610ed
JS
16485#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
16486
16487static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
16488{
16489 struct alc_spec *spec = codec->spec;
16490 int i;
16491
16492 for (i = 0; i < AUTO_PIN_LAST; i++) {
16493 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 16494 if (alc_is_input_pin(codec, nid)) {
23f0c048 16495 alc_set_input_pin(codec, nid, i);
e82c025b
TI
16496 if (nid != ALC861VD_PIN_CD_NID &&
16497 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
16498 snd_hda_codec_write(codec, nid, 0,
16499 AC_VERB_SET_AMP_GAIN_MUTE,
16500 AMP_OUT_MUTE);
16501 }
16502 }
16503}
16504
f511b01c
TI
16505#define alc861vd_auto_init_input_src alc882_auto_init_input_src
16506
f32610ed
JS
16507#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16508#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16509
16510/* add playback controls from the parsed DAC table */
16511/* Based on ALC880 version. But ALC861VD has separate,
16512 * different NIDs for mute/unmute switch and volume control */
16513static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16514 const struct auto_pin_cfg *cfg)
16515{
f32610ed
JS
16516 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
16517 hda_nid_t nid_v, nid_s;
16518 int i, err;
16519
16520 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 16521 if (!spec->multiout.dac_nids[i])
f32610ed
JS
16522 continue;
16523 nid_v = alc861vd_idx_to_mixer_vol(
16524 alc880_dac_to_idx(
16525 spec->multiout.dac_nids[i]));
16526 nid_s = alc861vd_idx_to_mixer_switch(
16527 alc880_dac_to_idx(
16528 spec->multiout.dac_nids[i]));
16529
16530 if (i == 2) {
16531 /* Center/LFE */
0afe5f89
TI
16532 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16533 "Center",
f12ab1e0
TI
16534 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16535 HDA_OUTPUT));
16536 if (err < 0)
f32610ed 16537 return err;
0afe5f89
TI
16538 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16539 "LFE",
f12ab1e0
TI
16540 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16541 HDA_OUTPUT));
16542 if (err < 0)
f32610ed 16543 return err;
0afe5f89
TI
16544 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16545 "Center",
f12ab1e0
TI
16546 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
16547 HDA_INPUT));
16548 if (err < 0)
f32610ed 16549 return err;
0afe5f89
TI
16550 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16551 "LFE",
f12ab1e0
TI
16552 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
16553 HDA_INPUT));
16554 if (err < 0)
f32610ed
JS
16555 return err;
16556 } else {
a4fcd491
TI
16557 const char *pfx;
16558 if (cfg->line_outs == 1 &&
16559 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
16560 if (!cfg->hp_pins)
16561 pfx = "Speaker";
16562 else
16563 pfx = "PCM";
16564 } else
16565 pfx = chname[i];
0afe5f89 16566 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16567 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16568 HDA_OUTPUT));
16569 if (err < 0)
f32610ed 16570 return err;
a4fcd491
TI
16571 if (cfg->line_outs == 1 &&
16572 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
16573 pfx = "Speaker";
0afe5f89 16574 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
bdd148a3 16575 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
16576 HDA_INPUT));
16577 if (err < 0)
f32610ed
JS
16578 return err;
16579 }
16580 }
16581 return 0;
16582}
16583
16584/* add playback controls for speaker and HP outputs */
16585/* Based on ALC880 version. But ALC861VD has separate,
16586 * different NIDs for mute/unmute switch and volume control */
16587static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16588 hda_nid_t pin, const char *pfx)
16589{
16590 hda_nid_t nid_v, nid_s;
16591 int err;
f32610ed 16592
f12ab1e0 16593 if (!pin)
f32610ed
JS
16594 return 0;
16595
16596 if (alc880_is_fixed_pin(pin)) {
16597 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16598 /* specify the DAC as the extra output */
f12ab1e0 16599 if (!spec->multiout.hp_nid)
f32610ed
JS
16600 spec->multiout.hp_nid = nid_v;
16601 else
16602 spec->multiout.extra_out_nid[0] = nid_v;
16603 /* control HP volume/switch on the output mixer amp */
16604 nid_v = alc861vd_idx_to_mixer_vol(
16605 alc880_fixed_pin_idx(pin));
16606 nid_s = alc861vd_idx_to_mixer_switch(
16607 alc880_fixed_pin_idx(pin));
16608
0afe5f89 16609 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16610 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
16611 if (err < 0)
f32610ed 16612 return err;
0afe5f89 16613 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
16614 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
16615 if (err < 0)
f32610ed
JS
16616 return err;
16617 } else if (alc880_is_multi_pin(pin)) {
16618 /* set manual connection */
16619 /* we have only a switch on HP-out PIN */
0afe5f89 16620 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
16621 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16622 if (err < 0)
f32610ed
JS
16623 return err;
16624 }
16625 return 0;
16626}
16627
16628/* parse the BIOS configuration and set up the alc_spec
16629 * return 1 if successful, 0 if the proper config is not found,
16630 * or a negative error code
16631 * Based on ALC880 version - had to change it to override
16632 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
16633static int alc861vd_parse_auto_config(struct hda_codec *codec)
16634{
16635 struct alc_spec *spec = codec->spec;
16636 int err;
16637 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
16638
f12ab1e0
TI
16639 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16640 alc861vd_ignore);
16641 if (err < 0)
f32610ed 16642 return err;
f12ab1e0 16643 if (!spec->autocfg.line_outs)
f32610ed
JS
16644 return 0; /* can't find valid BIOS pin config */
16645
f12ab1e0
TI
16646 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16647 if (err < 0)
16648 return err;
16649 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
16650 if (err < 0)
16651 return err;
16652 err = alc861vd_auto_create_extra_out(spec,
16653 spec->autocfg.speaker_pins[0],
16654 "Speaker");
16655 if (err < 0)
16656 return err;
16657 err = alc861vd_auto_create_extra_out(spec,
16658 spec->autocfg.hp_pins[0],
16659 "Headphone");
16660 if (err < 0)
16661 return err;
05f5f477 16662 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16663 if (err < 0)
f32610ed
JS
16664 return err;
16665
16666 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16667
757899ac 16668 alc_auto_parse_digital(codec);
f32610ed 16669
603c4019 16670 if (spec->kctls.list)
d88897ea 16671 add_mixer(spec, spec->kctls.list);
f32610ed 16672
d88897ea 16673 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
16674
16675 spec->num_mux_defs = 1;
61b9b9b1 16676 spec->input_mux = &spec->private_imux[0];
f32610ed 16677
776e184e
TI
16678 err = alc_auto_add_mic_boost(codec);
16679 if (err < 0)
16680 return err;
16681
6227cdce 16682 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 16683
f32610ed
JS
16684 return 1;
16685}
16686
16687/* additional initialization for auto-configuration model */
16688static void alc861vd_auto_init(struct hda_codec *codec)
16689{
f6c7e546 16690 struct alc_spec *spec = codec->spec;
f32610ed
JS
16691 alc861vd_auto_init_multi_out(codec);
16692 alc861vd_auto_init_hp_out(codec);
16693 alc861vd_auto_init_analog_input(codec);
f511b01c 16694 alc861vd_auto_init_input_src(codec);
757899ac 16695 alc_auto_init_digital(codec);
f6c7e546 16696 if (spec->unsol_event)
7fb0d78f 16697 alc_inithook(codec);
f32610ed
JS
16698}
16699
f8f25ba3
TI
16700enum {
16701 ALC660VD_FIX_ASUS_GPIO1
16702};
16703
16704/* reset GPIO1 */
16705static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
16706 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
16707 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
16708 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
16709 { }
16710};
16711
16712static const struct alc_fixup alc861vd_fixups[] = {
16713 [ALC660VD_FIX_ASUS_GPIO1] = {
16714 .verbs = alc660vd_fix_asus_gpio1_verbs,
16715 },
16716};
16717
16718static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
16719 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
16720 {}
16721};
16722
f32610ed
JS
16723static int patch_alc861vd(struct hda_codec *codec)
16724{
16725 struct alc_spec *spec;
16726 int err, board_config;
16727
16728 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16729 if (spec == NULL)
16730 return -ENOMEM;
16731
16732 codec->spec = spec;
16733
16734 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
16735 alc861vd_models,
16736 alc861vd_cfg_tbl);
16737
16738 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
16739 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16740 codec->chip_name);
f32610ed
JS
16741 board_config = ALC861VD_AUTO;
16742 }
16743
7fa90e87
TI
16744 if (board_config == ALC861VD_AUTO)
16745 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
f8f25ba3 16746
f32610ed
JS
16747 if (board_config == ALC861VD_AUTO) {
16748 /* automatic parse from the BIOS config */
16749 err = alc861vd_parse_auto_config(codec);
16750 if (err < 0) {
16751 alc_free(codec);
16752 return err;
f12ab1e0 16753 } else if (!err) {
f32610ed
JS
16754 printk(KERN_INFO
16755 "hda_codec: Cannot set up configuration "
16756 "from BIOS. Using base mode...\n");
16757 board_config = ALC861VD_3ST;
16758 }
16759 }
16760
680cd536
KK
16761 err = snd_hda_attach_beep_device(codec, 0x23);
16762 if (err < 0) {
16763 alc_free(codec);
16764 return err;
16765 }
16766
f32610ed 16767 if (board_config != ALC861VD_AUTO)
e9c364c0 16768 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 16769
2f893286 16770 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 16771 /* always turn on EAPD */
d88897ea 16772 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
16773 }
16774
f32610ed
JS
16775 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
16776 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
16777
f32610ed
JS
16778 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
16779 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
16780
dd704698
TI
16781 if (!spec->adc_nids) {
16782 spec->adc_nids = alc861vd_adc_nids;
16783 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
16784 }
16785 if (!spec->capsrc_nids)
16786 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 16787
b59bdf3b 16788 set_capture_mixer(codec);
45bdd1c1 16789 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 16790
2134ea4f
TI
16791 spec->vmaster_nid = 0x02;
16792
7fa90e87
TI
16793 if (board_config == ALC861VD_AUTO)
16794 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
16795
f32610ed
JS
16796 codec->patch_ops = alc_patch_ops;
16797
16798 if (board_config == ALC861VD_AUTO)
16799 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
16800#ifdef CONFIG_SND_HDA_POWER_SAVE
16801 if (!spec->loopback.amplist)
16802 spec->loopback.amplist = alc861vd_loopbacks;
16803#endif
f32610ed
JS
16804
16805 return 0;
16806}
16807
bc9f98a9
KY
16808/*
16809 * ALC662 support
16810 *
16811 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
16812 * configuration. Each pin widget can choose any input DACs and a mixer.
16813 * Each ADC is connected from a mixer of all inputs. This makes possible
16814 * 6-channel independent captures.
16815 *
16816 * In addition, an independent DAC for the multi-playback (not used in this
16817 * driver yet).
16818 */
16819#define ALC662_DIGOUT_NID 0x06
16820#define ALC662_DIGIN_NID 0x0a
16821
16822static hda_nid_t alc662_dac_nids[4] = {
16823 /* front, rear, clfe, rear_surr */
16824 0x02, 0x03, 0x04
16825};
16826
622e84cd
KY
16827static hda_nid_t alc272_dac_nids[2] = {
16828 0x02, 0x03
16829};
16830
b59bdf3b 16831static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 16832 /* ADC1-2 */
b59bdf3b 16833 0x09, 0x08
bc9f98a9 16834};
e1406348 16835
622e84cd
KY
16836static hda_nid_t alc272_adc_nids[1] = {
16837 /* ADC1-2 */
16838 0x08,
16839};
16840
b59bdf3b 16841static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
16842static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
16843
e1406348 16844
bc9f98a9
KY
16845/* input MUX */
16846/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
16847static struct hda_input_mux alc662_capture_source = {
16848 .num_items = 4,
16849 .items = {
16850 { "Mic", 0x0 },
16851 { "Front Mic", 0x1 },
16852 { "Line", 0x2 },
16853 { "CD", 0x4 },
16854 },
16855};
16856
16857static struct hda_input_mux alc662_lenovo_101e_capture_source = {
16858 .num_items = 2,
16859 .items = {
16860 { "Mic", 0x1 },
16861 { "Line", 0x2 },
16862 },
16863};
291702f0 16864
6dda9f4a
KY
16865static struct hda_input_mux alc663_capture_source = {
16866 .num_items = 3,
16867 .items = {
16868 { "Mic", 0x0 },
16869 { "Front Mic", 0x1 },
16870 { "Line", 0x2 },
16871 },
16872};
16873
4f5d1706 16874#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
16875static struct hda_input_mux alc272_nc10_capture_source = {
16876 .num_items = 16,
16877 .items = {
16878 { "Autoselect Mic", 0x0 },
16879 { "Internal Mic", 0x1 },
16880 { "In-0x02", 0x2 },
16881 { "In-0x03", 0x3 },
16882 { "In-0x04", 0x4 },
16883 { "In-0x05", 0x5 },
16884 { "In-0x06", 0x6 },
16885 { "In-0x07", 0x7 },
16886 { "In-0x08", 0x8 },
16887 { "In-0x09", 0x9 },
16888 { "In-0x0a", 0x0a },
16889 { "In-0x0b", 0x0b },
16890 { "In-0x0c", 0x0c },
16891 { "In-0x0d", 0x0d },
16892 { "In-0x0e", 0x0e },
16893 { "In-0x0f", 0x0f },
16894 },
16895};
16896#endif
16897
bc9f98a9
KY
16898/*
16899 * 2ch mode
16900 */
16901static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
16902 { 2, NULL }
16903};
16904
16905/*
16906 * 2ch mode
16907 */
16908static struct hda_verb alc662_3ST_ch2_init[] = {
16909 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
16910 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16911 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
16912 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16913 { } /* end */
16914};
16915
16916/*
16917 * 6ch mode
16918 */
16919static struct hda_verb alc662_3ST_ch6_init[] = {
16920 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16921 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16922 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
16923 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16924 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16925 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
16926 { } /* end */
16927};
16928
16929static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
16930 { 2, alc662_3ST_ch2_init },
16931 { 6, alc662_3ST_ch6_init },
16932};
16933
16934/*
16935 * 2ch mode
16936 */
16937static struct hda_verb alc662_sixstack_ch6_init[] = {
16938 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16939 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16940 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16941 { } /* end */
16942};
16943
16944/*
16945 * 6ch mode
16946 */
16947static struct hda_verb alc662_sixstack_ch8_init[] = {
16948 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16949 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16950 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16951 { } /* end */
16952};
16953
16954static struct hda_channel_mode alc662_5stack_modes[2] = {
16955 { 2, alc662_sixstack_ch6_init },
16956 { 6, alc662_sixstack_ch8_init },
16957};
16958
16959/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16960 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16961 */
16962
16963static struct snd_kcontrol_new alc662_base_mixer[] = {
16964 /* output mixer control */
16965 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 16966 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 16967 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 16968 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
16969 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16970 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
16971 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16972 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
16973 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16974
16975 /*Input mixer control */
16976 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
16977 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
16978 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
16979 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
16980 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
16981 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
16982 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
16983 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
16984 { } /* end */
16985};
16986
16987static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
16988 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 16989 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
16990 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16991 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16992 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16993 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16994 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16997 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16998 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
16999 { } /* end */
17000};
17001
17002static struct snd_kcontrol_new alc662_3ST_6ch_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 17005 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17006 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17007 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17008 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17009 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17010 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17011 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17012 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17013 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17014 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17015 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17016 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17017 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17018 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17019 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17020 { } /* end */
17021};
17022
17023static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17024 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17025 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17026 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17027 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17028 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
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, 0x1, HDA_INPUT),
17032 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17033 { } /* end */
17034};
17035
291702f0 17036static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17037 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17038 ALC262_HIPPO_MASTER_SWITCH,
291702f0
KY
17039
17040 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
17041 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17042 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17043
17044 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
17045 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17046 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17047 { } /* end */
17048};
17049
8c427226 17050static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17051 ALC262_HIPPO_MASTER_SWITCH,
17052 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17053 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17054 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17055 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17056 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17057 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17058 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17059 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17060 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17061 { } /* end */
17062};
17063
f1d4e28b
KY
17064static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17065 .ops = &snd_hda_bind_vol,
17066 .values = {
17067 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17068 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17069 0
17070 },
17071};
17072
17073static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17074 .ops = &snd_hda_bind_sw,
17075 .values = {
17076 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17077 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17078 0
17079 },
17080};
17081
6dda9f4a 17082static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17083 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17084 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17085 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17086 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17087 { } /* end */
17088};
17089
17090static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17091 .ops = &snd_hda_bind_sw,
17092 .values = {
17093 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17094 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17095 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17096 0
17097 },
17098};
17099
17100static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17101 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17102 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17103 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17104 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17105 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17106 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17107
17108 { } /* end */
17109};
17110
17111static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17112 .ops = &snd_hda_bind_sw,
17113 .values = {
17114 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17115 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17116 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17117 0
17118 },
17119};
17120
17121static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17122 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17123 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17124 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17125 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17126 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17127 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17128 { } /* end */
17129};
17130
17131static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17132 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17133 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17134 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17135 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17136 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17137 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17138 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17139 { } /* end */
17140};
17141
17142static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17143 .ops = &snd_hda_bind_vol,
17144 .values = {
17145 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17146 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17147 0
17148 },
17149};
17150
17151static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17152 .ops = &snd_hda_bind_sw,
17153 .values = {
17154 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17155 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17156 0
17157 },
17158};
17159
17160static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17161 HDA_BIND_VOL("Master Playback Volume",
17162 &alc663_asus_two_bind_master_vol),
17163 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17164 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17165 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17166 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17167 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17168 { } /* end */
17169};
17170
17171static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17172 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17173 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17174 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17175 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17176 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17177 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17178 { } /* end */
17179};
17180
17181static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17182 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17183 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17184 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17185 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17186 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17187
17188 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17189 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17190 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17191 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17192 { } /* end */
17193};
17194
17195static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17196 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17197 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17198 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17199
17200 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17201 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17202 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17203 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17204 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17205 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17206 { } /* end */
17207};
17208
ebb83eeb
KY
17209static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17210 .ops = &snd_hda_bind_sw,
17211 .values = {
17212 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17213 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17214 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17215 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17216 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17217 0
17218 },
17219};
17220
17221static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17222 .ops = &snd_hda_bind_sw,
17223 .values = {
17224 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17225 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17226 0
17227 },
17228};
17229
17230static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17231 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17232 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17233 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17234 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17235 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17236 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17237 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17238 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17239 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17240 { } /* end */
17241};
17242
17243static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17244 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17245 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17246 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17247 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17248 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17249 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17250 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17251 { } /* end */
17252};
17253
17254
bc9f98a9
KY
17255static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17256 {
17257 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17258 .name = "Channel Mode",
17259 .info = alc_ch_mode_info,
17260 .get = alc_ch_mode_get,
17261 .put = alc_ch_mode_put,
17262 },
17263 { } /* end */
17264};
17265
17266static struct hda_verb alc662_init_verbs[] = {
17267 /* ADC: mute amp left and right */
17268 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17269 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17270
b60dd394
KY
17271 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17272 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17273 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17274 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17275 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17276 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17277
17278 /* Front Pin: output 0 (0x0c) */
17279 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17280 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17281
17282 /* Rear Pin: output 1 (0x0d) */
17283 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17284 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17285
17286 /* CLFE Pin: output 2 (0x0e) */
17287 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17288 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17289
17290 /* Mic (rear) pin: input vref at 80% */
17291 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17292 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17293 /* Front Mic pin: input vref at 80% */
17294 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17295 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17296 /* Line In pin: input */
17297 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17298 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17299 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17300 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17301 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17302 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17303 /* CD pin widget for input */
17304 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17305
17306 /* FIXME: use matrix-type input source selection */
17307 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17308 /* Input mixer */
17309 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17310 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
17311
17312 /* always trun on EAPD */
17313 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17314 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17315
bc9f98a9
KY
17316 { }
17317};
17318
cec27c89
KY
17319static struct hda_verb alc663_init_verbs[] = {
17320 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17321 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17322 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17323 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17324 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17325 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17326 { }
17327};
17328
17329static struct hda_verb alc272_init_verbs[] = {
17330 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17331 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17332 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17333 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17334 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17335 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17336 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17337 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17338 { }
17339};
17340
bc9f98a9
KY
17341static struct hda_verb alc662_sue_init_verbs[] = {
17342 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17343 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17344 {}
17345};
17346
17347static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17348 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17349 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17350 {}
bc9f98a9
KY
17351};
17352
8c427226
KY
17353/* Set Unsolicited Event*/
17354static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17355 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17356 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17357 {}
17358};
17359
6dda9f4a 17360static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17361 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17362 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17363 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17364 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17365 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17366 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17367 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17368 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17369 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17370 {}
17371};
17372
17373static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17374 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17375 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17376 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17377 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17378 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17379 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17380 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17381 {}
17382};
17383
17384static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17385 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17386 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17387 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17388 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17389 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17390 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17391 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17392 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17393 {}
17394};
6dda9f4a 17395
f1d4e28b
KY
17396static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17397 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17398 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17399 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17400 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17401 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17402 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17403 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17404 {}
17405};
6dda9f4a 17406
f1d4e28b
KY
17407static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17408 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17409 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17410 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17411 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
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, 0x0}, /* 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)},
6dda9f4a
KY
17417 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17418 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
17419 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17420 {}
17421};
17422
17423static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17424 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17425 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17426 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17427 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17428 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17429 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17430 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17431 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17432 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17433 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17434 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17435 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
17436 {}
17437};
17438
17439static struct hda_verb alc663_g71v_init_verbs[] = {
17440 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17441 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17442 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17443
17444 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17445 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17446 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17447
17448 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17449 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17450 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17451 {}
17452};
17453
17454static struct hda_verb alc663_g50v_init_verbs[] = {
17455 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17456 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17457 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17458
17459 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17460 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17461 {}
17462};
17463
f1d4e28b
KY
17464static struct hda_verb alc662_ecs_init_verbs[] = {
17465 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17466 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17467 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17468 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17469 {}
17470};
17471
622e84cd
KY
17472static struct hda_verb alc272_dell_zm1_init_verbs[] = {
17473 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17474 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17475 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17476 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17477 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17478 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17479 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17480 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17481 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17482 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17483 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17484 {}
17485};
17486
17487static struct hda_verb alc272_dell_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 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17496 {0x23, 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
ebb83eeb
KY
17502static struct hda_verb alc663_mode7_init_verbs[] = {
17503 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17504 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17505 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17506 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17507 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17508 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17509 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17510 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17511 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17512 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17513 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17514 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17515 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17516 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17517 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17518 {}
17519};
17520
17521static struct hda_verb alc663_mode8_init_verbs[] = {
17522 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17523 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17524 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17525 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17526 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17527 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17528 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17529 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17530 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17531 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17532 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17533 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17534 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17535 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17536 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17537 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17538 {}
17539};
17540
f1d4e28b
KY
17541static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17542 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17543 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17544 { } /* end */
17545};
17546
622e84cd
KY
17547static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17548 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17549 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17550 { } /* end */
17551};
17552
bc9f98a9
KY
17553static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
17554{
17555 unsigned int present;
f12ab1e0 17556 unsigned char bits;
bc9f98a9 17557
864f92be 17558 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 17559 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17560
47fd830a
TI
17561 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17562 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17563}
17564
17565static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
17566{
17567 unsigned int present;
f12ab1e0 17568 unsigned char bits;
bc9f98a9 17569
864f92be 17570 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 17571 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17572
47fd830a
TI
17573 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17574 HDA_AMP_MUTE, bits);
17575 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17576 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17577}
17578
17579static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
17580 unsigned int res)
17581{
17582 if ((res >> 26) == ALC880_HP_EVENT)
17583 alc662_lenovo_101e_all_automute(codec);
17584 if ((res >> 26) == ALC880_FRONT_EVENT)
17585 alc662_lenovo_101e_ispeaker_automute(codec);
17586}
17587
291702f0
KY
17588/* unsolicited event for HP jack sensing */
17589static void alc662_eeepc_unsol_event(struct hda_codec *codec,
17590 unsigned int res)
17591{
291702f0 17592 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 17593 alc_mic_automute(codec);
42171c17
TI
17594 else
17595 alc262_hippo_unsol_event(codec, res);
291702f0
KY
17596}
17597
4f5d1706
TI
17598static void alc662_eeepc_setup(struct hda_codec *codec)
17599{
17600 struct alc_spec *spec = codec->spec;
17601
17602 alc262_hippo1_setup(codec);
17603 spec->ext_mic.pin = 0x18;
17604 spec->ext_mic.mux_idx = 0;
17605 spec->int_mic.pin = 0x19;
17606 spec->int_mic.mux_idx = 1;
17607 spec->auto_mic = 1;
17608}
17609
291702f0
KY
17610static void alc662_eeepc_inithook(struct hda_codec *codec)
17611{
4f5d1706
TI
17612 alc262_hippo_automute(codec);
17613 alc_mic_automute(codec);
291702f0
KY
17614}
17615
4f5d1706 17616static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 17617{
42171c17
TI
17618 struct alc_spec *spec = codec->spec;
17619
17620 spec->autocfg.hp_pins[0] = 0x14;
17621 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
17622}
17623
4f5d1706
TI
17624#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
17625
6dda9f4a
KY
17626static void alc663_m51va_speaker_automute(struct hda_codec *codec)
17627{
17628 unsigned int present;
17629 unsigned char bits;
17630
864f92be 17631 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 17632 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 17633 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17634 HDA_AMP_MUTE, bits);
f1d4e28b 17635 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17636 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17637}
17638
17639static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
17640{
17641 unsigned int present;
17642 unsigned char bits;
17643
864f92be 17644 present = snd_hda_jack_detect(codec, 0x21);
f1d4e28b
KY
17645 bits = present ? HDA_AMP_MUTE : 0;
17646 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17647 HDA_AMP_MUTE, bits);
f1d4e28b 17648 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17649 HDA_AMP_MUTE, bits);
f1d4e28b 17650 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 17651 HDA_AMP_MUTE, bits);
f1d4e28b 17652 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 17653 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17654}
17655
17656static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
17657{
17658 unsigned int present;
17659 unsigned char bits;
17660
864f92be 17661 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17662 bits = present ? HDA_AMP_MUTE : 0;
17663 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17664 HDA_AMP_MUTE, bits);
f1d4e28b 17665 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17666 HDA_AMP_MUTE, bits);
f1d4e28b 17667 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 17668 HDA_AMP_MUTE, bits);
f1d4e28b 17669 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 17670 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17671}
17672
17673static void alc662_f5z_speaker_automute(struct hda_codec *codec)
17674{
17675 unsigned int present;
17676 unsigned char bits;
17677
864f92be 17678 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
17679 bits = present ? 0 : PIN_OUT;
17680 snd_hda_codec_write(codec, 0x14, 0,
17681 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
17682}
17683
17684static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
17685{
17686 unsigned int present1, present2;
17687
864f92be
WF
17688 present1 = snd_hda_jack_detect(codec, 0x21);
17689 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17690
17691 if (present1 || present2) {
17692 snd_hda_codec_write_cache(codec, 0x14, 0,
17693 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17694 } else {
17695 snd_hda_codec_write_cache(codec, 0x14, 0,
17696 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17697 }
17698}
17699
17700static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
17701{
17702 unsigned int present1, present2;
17703
864f92be
WF
17704 present1 = snd_hda_jack_detect(codec, 0x1b);
17705 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17706
17707 if (present1 || present2) {
17708 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17709 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 17710 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17711 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
17712 } else {
17713 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17714 HDA_AMP_MUTE, 0);
f1d4e28b 17715 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17716 HDA_AMP_MUTE, 0);
f1d4e28b 17717 }
6dda9f4a
KY
17718}
17719
ebb83eeb
KY
17720static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
17721{
17722 unsigned int present1, present2;
17723
17724 present1 = snd_hda_codec_read(codec, 0x1b, 0,
17725 AC_VERB_GET_PIN_SENSE, 0)
17726 & AC_PINSENSE_PRESENCE;
17727 present2 = snd_hda_codec_read(codec, 0x21, 0,
17728 AC_VERB_GET_PIN_SENSE, 0)
17729 & AC_PINSENSE_PRESENCE;
17730
17731 if (present1 || present2) {
17732 snd_hda_codec_write_cache(codec, 0x14, 0,
17733 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17734 snd_hda_codec_write_cache(codec, 0x17, 0,
17735 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17736 } else {
17737 snd_hda_codec_write_cache(codec, 0x14, 0,
17738 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17739 snd_hda_codec_write_cache(codec, 0x17, 0,
17740 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17741 }
17742}
17743
17744static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
17745{
17746 unsigned int present1, present2;
17747
17748 present1 = snd_hda_codec_read(codec, 0x21, 0,
17749 AC_VERB_GET_PIN_SENSE, 0)
17750 & AC_PINSENSE_PRESENCE;
17751 present2 = snd_hda_codec_read(codec, 0x15, 0,
17752 AC_VERB_GET_PIN_SENSE, 0)
17753 & AC_PINSENSE_PRESENCE;
17754
17755 if (present1 || present2) {
17756 snd_hda_codec_write_cache(codec, 0x14, 0,
17757 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17758 snd_hda_codec_write_cache(codec, 0x17, 0,
17759 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17760 } else {
17761 snd_hda_codec_write_cache(codec, 0x14, 0,
17762 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17763 snd_hda_codec_write_cache(codec, 0x17, 0,
17764 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17765 }
17766}
17767
6dda9f4a
KY
17768static void alc663_m51va_unsol_event(struct hda_codec *codec,
17769 unsigned int res)
17770{
17771 switch (res >> 26) {
17772 case ALC880_HP_EVENT:
17773 alc663_m51va_speaker_automute(codec);
17774 break;
17775 case ALC880_MIC_EVENT:
4f5d1706 17776 alc_mic_automute(codec);
6dda9f4a
KY
17777 break;
17778 }
17779}
17780
4f5d1706
TI
17781static void alc663_m51va_setup(struct hda_codec *codec)
17782{
17783 struct alc_spec *spec = codec->spec;
17784 spec->ext_mic.pin = 0x18;
17785 spec->ext_mic.mux_idx = 0;
17786 spec->int_mic.pin = 0x12;
ebb83eeb 17787 spec->int_mic.mux_idx = 9;
4f5d1706
TI
17788 spec->auto_mic = 1;
17789}
17790
6dda9f4a
KY
17791static void alc663_m51va_inithook(struct hda_codec *codec)
17792{
17793 alc663_m51va_speaker_automute(codec);
4f5d1706 17794 alc_mic_automute(codec);
6dda9f4a
KY
17795}
17796
f1d4e28b 17797/* ***************** Mode1 ******************************/
4f5d1706 17798#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
17799
17800static void alc663_mode1_setup(struct hda_codec *codec)
17801{
17802 struct alc_spec *spec = codec->spec;
17803 spec->ext_mic.pin = 0x18;
17804 spec->ext_mic.mux_idx = 0;
17805 spec->int_mic.pin = 0x19;
17806 spec->int_mic.mux_idx = 1;
17807 spec->auto_mic = 1;
17808}
17809
4f5d1706 17810#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 17811
f1d4e28b
KY
17812/* ***************** Mode2 ******************************/
17813static void alc662_mode2_unsol_event(struct hda_codec *codec,
17814 unsigned int res)
17815{
17816 switch (res >> 26) {
17817 case ALC880_HP_EVENT:
17818 alc662_f5z_speaker_automute(codec);
17819 break;
17820 case ALC880_MIC_EVENT:
4f5d1706 17821 alc_mic_automute(codec);
f1d4e28b
KY
17822 break;
17823 }
17824}
17825
ebb83eeb 17826#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 17827
f1d4e28b
KY
17828static void alc662_mode2_inithook(struct hda_codec *codec)
17829{
17830 alc662_f5z_speaker_automute(codec);
4f5d1706 17831 alc_mic_automute(codec);
f1d4e28b
KY
17832}
17833/* ***************** Mode3 ******************************/
17834static void alc663_mode3_unsol_event(struct hda_codec *codec,
17835 unsigned int res)
17836{
17837 switch (res >> 26) {
17838 case ALC880_HP_EVENT:
17839 alc663_two_hp_m1_speaker_automute(codec);
17840 break;
17841 case ALC880_MIC_EVENT:
4f5d1706 17842 alc_mic_automute(codec);
f1d4e28b
KY
17843 break;
17844 }
17845}
17846
ebb83eeb 17847#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 17848
f1d4e28b
KY
17849static void alc663_mode3_inithook(struct hda_codec *codec)
17850{
17851 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 17852 alc_mic_automute(codec);
f1d4e28b
KY
17853}
17854/* ***************** Mode4 ******************************/
17855static void alc663_mode4_unsol_event(struct hda_codec *codec,
17856 unsigned int res)
17857{
17858 switch (res >> 26) {
17859 case ALC880_HP_EVENT:
17860 alc663_21jd_two_speaker_automute(codec);
17861 break;
17862 case ALC880_MIC_EVENT:
4f5d1706 17863 alc_mic_automute(codec);
f1d4e28b
KY
17864 break;
17865 }
17866}
17867
ebb83eeb 17868#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 17869
f1d4e28b
KY
17870static void alc663_mode4_inithook(struct hda_codec *codec)
17871{
17872 alc663_21jd_two_speaker_automute(codec);
4f5d1706 17873 alc_mic_automute(codec);
f1d4e28b
KY
17874}
17875/* ***************** Mode5 ******************************/
17876static void alc663_mode5_unsol_event(struct hda_codec *codec,
17877 unsigned int res)
17878{
17879 switch (res >> 26) {
17880 case ALC880_HP_EVENT:
17881 alc663_15jd_two_speaker_automute(codec);
17882 break;
17883 case ALC880_MIC_EVENT:
4f5d1706 17884 alc_mic_automute(codec);
f1d4e28b
KY
17885 break;
17886 }
17887}
17888
ebb83eeb 17889#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 17890
f1d4e28b
KY
17891static void alc663_mode5_inithook(struct hda_codec *codec)
17892{
17893 alc663_15jd_two_speaker_automute(codec);
4f5d1706 17894 alc_mic_automute(codec);
f1d4e28b
KY
17895}
17896/* ***************** Mode6 ******************************/
17897static void alc663_mode6_unsol_event(struct hda_codec *codec,
17898 unsigned int res)
17899{
17900 switch (res >> 26) {
17901 case ALC880_HP_EVENT:
17902 alc663_two_hp_m2_speaker_automute(codec);
17903 break;
17904 case ALC880_MIC_EVENT:
4f5d1706 17905 alc_mic_automute(codec);
f1d4e28b
KY
17906 break;
17907 }
17908}
17909
ebb83eeb 17910#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 17911
f1d4e28b
KY
17912static void alc663_mode6_inithook(struct hda_codec *codec)
17913{
17914 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 17915 alc_mic_automute(codec);
f1d4e28b
KY
17916}
17917
ebb83eeb
KY
17918/* ***************** Mode7 ******************************/
17919static void alc663_mode7_unsol_event(struct hda_codec *codec,
17920 unsigned int res)
17921{
17922 switch (res >> 26) {
17923 case ALC880_HP_EVENT:
17924 alc663_two_hp_m7_speaker_automute(codec);
17925 break;
17926 case ALC880_MIC_EVENT:
17927 alc_mic_automute(codec);
17928 break;
17929 }
17930}
17931
17932#define alc663_mode7_setup alc663_mode1_setup
17933
17934static void alc663_mode7_inithook(struct hda_codec *codec)
17935{
17936 alc663_two_hp_m7_speaker_automute(codec);
17937 alc_mic_automute(codec);
17938}
17939
17940/* ***************** Mode8 ******************************/
17941static void alc663_mode8_unsol_event(struct hda_codec *codec,
17942 unsigned int res)
17943{
17944 switch (res >> 26) {
17945 case ALC880_HP_EVENT:
17946 alc663_two_hp_m8_speaker_automute(codec);
17947 break;
17948 case ALC880_MIC_EVENT:
17949 alc_mic_automute(codec);
17950 break;
17951 }
17952}
17953
17954#define alc663_mode8_setup alc663_m51va_setup
17955
17956static void alc663_mode8_inithook(struct hda_codec *codec)
17957{
17958 alc663_two_hp_m8_speaker_automute(codec);
17959 alc_mic_automute(codec);
17960}
17961
6dda9f4a
KY
17962static void alc663_g71v_hp_automute(struct hda_codec *codec)
17963{
17964 unsigned int present;
17965 unsigned char bits;
17966
864f92be 17967 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
17968 bits = present ? HDA_AMP_MUTE : 0;
17969 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17970 HDA_AMP_MUTE, bits);
17971 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17972 HDA_AMP_MUTE, bits);
17973}
17974
17975static void alc663_g71v_front_automute(struct hda_codec *codec)
17976{
17977 unsigned int present;
17978 unsigned char bits;
17979
864f92be 17980 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
17981 bits = present ? HDA_AMP_MUTE : 0;
17982 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17983 HDA_AMP_MUTE, bits);
17984}
17985
17986static void alc663_g71v_unsol_event(struct hda_codec *codec,
17987 unsigned int res)
17988{
17989 switch (res >> 26) {
17990 case ALC880_HP_EVENT:
17991 alc663_g71v_hp_automute(codec);
17992 break;
17993 case ALC880_FRONT_EVENT:
17994 alc663_g71v_front_automute(codec);
17995 break;
17996 case ALC880_MIC_EVENT:
4f5d1706 17997 alc_mic_automute(codec);
6dda9f4a
KY
17998 break;
17999 }
18000}
18001
4f5d1706
TI
18002#define alc663_g71v_setup alc663_m51va_setup
18003
6dda9f4a
KY
18004static void alc663_g71v_inithook(struct hda_codec *codec)
18005{
18006 alc663_g71v_front_automute(codec);
18007 alc663_g71v_hp_automute(codec);
4f5d1706 18008 alc_mic_automute(codec);
6dda9f4a
KY
18009}
18010
18011static void alc663_g50v_unsol_event(struct hda_codec *codec,
18012 unsigned int res)
18013{
18014 switch (res >> 26) {
18015 case ALC880_HP_EVENT:
18016 alc663_m51va_speaker_automute(codec);
18017 break;
18018 case ALC880_MIC_EVENT:
4f5d1706 18019 alc_mic_automute(codec);
6dda9f4a
KY
18020 break;
18021 }
18022}
18023
4f5d1706
TI
18024#define alc663_g50v_setup alc663_m51va_setup
18025
6dda9f4a
KY
18026static void alc663_g50v_inithook(struct hda_codec *codec)
18027{
18028 alc663_m51va_speaker_automute(codec);
4f5d1706 18029 alc_mic_automute(codec);
6dda9f4a
KY
18030}
18031
f1d4e28b
KY
18032static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18033 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18034 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b
KY
18035
18036 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
18037 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18038 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18039
18040 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
18041 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18042 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18043 { } /* end */
18044};
18045
9541ba1d
CP
18046static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18047 /* Master Playback automatically created from Speaker and Headphone */
18048 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18049 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18050 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18051 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18052
18053 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18054 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18055 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
18056
18057 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18058 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18059 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
18060 { } /* end */
18061};
18062
cb53c626
TI
18063#ifdef CONFIG_SND_HDA_POWER_SAVE
18064#define alc662_loopbacks alc880_loopbacks
18065#endif
18066
bc9f98a9 18067
def319f9 18068/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18069#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18070#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18071#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18072#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18073
18074/*
18075 * configuration and preset
18076 */
18077static const char *alc662_models[ALC662_MODEL_LAST] = {
18078 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18079 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18080 [ALC662_3ST_6ch] = "3stack-6ch",
18081 [ALC662_5ST_DIG] = "6stack-dig",
18082 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18083 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18084 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18085 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18086 [ALC663_ASUS_M51VA] = "m51va",
18087 [ALC663_ASUS_G71V] = "g71v",
18088 [ALC663_ASUS_H13] = "h13",
18089 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18090 [ALC663_ASUS_MODE1] = "asus-mode1",
18091 [ALC662_ASUS_MODE2] = "asus-mode2",
18092 [ALC663_ASUS_MODE3] = "asus-mode3",
18093 [ALC663_ASUS_MODE4] = "asus-mode4",
18094 [ALC663_ASUS_MODE5] = "asus-mode5",
18095 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18096 [ALC663_ASUS_MODE7] = "asus-mode7",
18097 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18098 [ALC272_DELL] = "dell",
18099 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18100 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18101 [ALC662_AUTO] = "auto",
18102};
18103
18104static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18105 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18106 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18107 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18108 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18109 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18110 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18111 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18112 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18113 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18114 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18115 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18116 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18117 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18118 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18119 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18120 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18121 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18122 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18123 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18124 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18125 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18126 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18127 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18128 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18129 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18130 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18131 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18132 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18133 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18134 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18135 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18136 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18137 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18138 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18139 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18140 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18141 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18142 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18143 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18144 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18145 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18146 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18147 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18148 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18149 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18150 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18151 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18152 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18153 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18154 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18155 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18156 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18157 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18158 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18159 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18160 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18161 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18162 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18163 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18164 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18165 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18166 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18167 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18168 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18169 ALC662_3ST_6ch_DIG),
4dee8baa 18170 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18171 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
18172 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18173 ALC662_3ST_6ch_DIG),
6227cdce 18174 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18175 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18176 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18177 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18178 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18179 ALC662_3ST_6ch_DIG),
dea0a509
TI
18180 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18181 ALC663_ASUS_H13),
bc9f98a9
KY
18182 {}
18183};
18184
18185static struct alc_config_preset alc662_presets[] = {
18186 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18187 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
18188 .init_verbs = { alc662_init_verbs },
18189 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18190 .dac_nids = alc662_dac_nids,
18191 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18192 .dig_in_nid = ALC662_DIGIN_NID,
18193 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18194 .channel_mode = alc662_3ST_2ch_modes,
18195 .input_mux = &alc662_capture_source,
18196 },
18197 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18198 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18199 .init_verbs = { alc662_init_verbs },
18200 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18201 .dac_nids = alc662_dac_nids,
18202 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18203 .dig_in_nid = ALC662_DIGIN_NID,
18204 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18205 .channel_mode = alc662_3ST_6ch_modes,
18206 .need_dac_fix = 1,
18207 .input_mux = &alc662_capture_source,
f12ab1e0 18208 },
bc9f98a9 18209 [ALC662_3ST_6ch] = {
f9e336f6 18210 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18211 .init_verbs = { alc662_init_verbs },
18212 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18213 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18214 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18215 .channel_mode = alc662_3ST_6ch_modes,
18216 .need_dac_fix = 1,
18217 .input_mux = &alc662_capture_source,
f12ab1e0 18218 },
bc9f98a9 18219 [ALC662_5ST_DIG] = {
f9e336f6 18220 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18221 .init_verbs = { alc662_init_verbs },
18222 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18223 .dac_nids = alc662_dac_nids,
18224 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18225 .dig_in_nid = ALC662_DIGIN_NID,
18226 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18227 .channel_mode = alc662_5stack_modes,
18228 .input_mux = &alc662_capture_source,
18229 },
18230 [ALC662_LENOVO_101E] = {
f9e336f6 18231 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
18232 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18233 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18234 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18235 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18236 .channel_mode = alc662_3ST_2ch_modes,
18237 .input_mux = &alc662_lenovo_101e_capture_source,
18238 .unsol_event = alc662_lenovo_101e_unsol_event,
18239 .init_hook = alc662_lenovo_101e_all_automute,
18240 },
291702f0 18241 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18242 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
18243 .init_verbs = { alc662_init_verbs,
18244 alc662_eeepc_sue_init_verbs },
18245 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18246 .dac_nids = alc662_dac_nids,
291702f0
KY
18247 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18248 .channel_mode = alc662_3ST_2ch_modes,
291702f0 18249 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18250 .setup = alc662_eeepc_setup,
291702f0
KY
18251 .init_hook = alc662_eeepc_inithook,
18252 },
8c427226 18253 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18254 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18255 alc662_chmode_mixer },
18256 .init_verbs = { alc662_init_verbs,
18257 alc662_eeepc_ep20_sue_init_verbs },
18258 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18259 .dac_nids = alc662_dac_nids,
8c427226
KY
18260 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18261 .channel_mode = alc662_3ST_6ch_modes,
18262 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 18263 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18264 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
18265 .init_hook = alc662_eeepc_ep20_inithook,
18266 },
f1d4e28b 18267 [ALC662_ECS] = {
f9e336f6 18268 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
18269 .init_verbs = { alc662_init_verbs,
18270 alc662_ecs_init_verbs },
18271 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18272 .dac_nids = alc662_dac_nids,
18273 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18274 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18275 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18276 .setup = alc662_eeepc_setup,
f1d4e28b
KY
18277 .init_hook = alc662_eeepc_inithook,
18278 },
6dda9f4a 18279 [ALC663_ASUS_M51VA] = {
f9e336f6 18280 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18281 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18282 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18283 .dac_nids = alc662_dac_nids,
18284 .dig_out_nid = ALC662_DIGOUT_NID,
18285 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18286 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18287 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18288 .setup = alc663_m51va_setup,
6dda9f4a
KY
18289 .init_hook = alc663_m51va_inithook,
18290 },
18291 [ALC663_ASUS_G71V] = {
f9e336f6 18292 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
18293 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18294 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18295 .dac_nids = alc662_dac_nids,
18296 .dig_out_nid = ALC662_DIGOUT_NID,
18297 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18298 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18299 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 18300 .setup = alc663_g71v_setup,
6dda9f4a
KY
18301 .init_hook = alc663_g71v_inithook,
18302 },
18303 [ALC663_ASUS_H13] = {
f9e336f6 18304 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18305 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18306 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18307 .dac_nids = alc662_dac_nids,
18308 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18309 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
18310 .unsol_event = alc663_m51va_unsol_event,
18311 .init_hook = alc663_m51va_inithook,
18312 },
18313 [ALC663_ASUS_G50V] = {
f9e336f6 18314 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
18315 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18316 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18317 .dac_nids = alc662_dac_nids,
18318 .dig_out_nid = ALC662_DIGOUT_NID,
18319 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18320 .channel_mode = alc662_3ST_6ch_modes,
18321 .input_mux = &alc663_capture_source,
18322 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 18323 .setup = alc663_g50v_setup,
6dda9f4a
KY
18324 .init_hook = alc663_g50v_inithook,
18325 },
f1d4e28b 18326 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18327 .mixers = { alc663_m51va_mixer },
18328 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18329 .init_verbs = { alc662_init_verbs,
18330 alc663_21jd_amic_init_verbs },
18331 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18332 .hp_nid = 0x03,
18333 .dac_nids = alc662_dac_nids,
18334 .dig_out_nid = ALC662_DIGOUT_NID,
18335 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18336 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18337 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18338 .setup = alc663_mode1_setup,
f1d4e28b
KY
18339 .init_hook = alc663_mode1_inithook,
18340 },
18341 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18342 .mixers = { alc662_1bjd_mixer },
18343 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18344 .init_verbs = { alc662_init_verbs,
18345 alc662_1bjd_amic_init_verbs },
18346 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18347 .dac_nids = alc662_dac_nids,
18348 .dig_out_nid = ALC662_DIGOUT_NID,
18349 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18350 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18351 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18352 .setup = alc662_mode2_setup,
f1d4e28b
KY
18353 .init_hook = alc662_mode2_inithook,
18354 },
18355 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18356 .mixers = { alc663_two_hp_m1_mixer },
18357 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18358 .init_verbs = { alc662_init_verbs,
18359 alc663_two_hp_amic_m1_init_verbs },
18360 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18361 .hp_nid = 0x03,
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 = alc663_mode3_unsol_event,
4f5d1706 18367 .setup = alc663_mode3_setup,
f1d4e28b
KY
18368 .init_hook = alc663_mode3_inithook,
18369 },
18370 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18371 .mixers = { alc663_asus_21jd_clfe_mixer },
18372 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18373 .init_verbs = { alc662_init_verbs,
18374 alc663_21jd_amic_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_mode4_unsol_event,
4f5d1706 18382 .setup = alc663_mode4_setup,
f1d4e28b
KY
18383 .init_hook = alc663_mode4_inithook,
18384 },
18385 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18386 .mixers = { alc663_asus_15jd_clfe_mixer },
18387 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18388 .init_verbs = { alc662_init_verbs,
18389 alc663_15jd_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_mode5_unsol_event,
4f5d1706 18397 .setup = alc663_mode5_setup,
f1d4e28b
KY
18398 .init_hook = alc663_mode5_inithook,
18399 },
18400 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18401 .mixers = { alc663_two_hp_m2_mixer },
18402 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18403 .init_verbs = { alc662_init_verbs,
18404 alc663_two_hp_amic_m2_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_mode6_unsol_event,
4f5d1706 18412 .setup = alc663_mode6_setup,
f1d4e28b
KY
18413 .init_hook = alc663_mode6_inithook,
18414 },
ebb83eeb
KY
18415 [ALC663_ASUS_MODE7] = {
18416 .mixers = { alc663_mode7_mixer },
18417 .cap_mixer = alc662_auto_capture_mixer,
18418 .init_verbs = { alc662_init_verbs,
18419 alc663_mode7_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,
18426 .unsol_event = alc663_mode7_unsol_event,
18427 .setup = alc663_mode7_setup,
18428 .init_hook = alc663_mode7_inithook,
18429 },
18430 [ALC663_ASUS_MODE8] = {
18431 .mixers = { alc663_mode8_mixer },
18432 .cap_mixer = alc662_auto_capture_mixer,
18433 .init_verbs = { alc662_init_verbs,
18434 alc663_mode8_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_mode8_unsol_event,
18442 .setup = alc663_mode8_setup,
18443 .init_hook = alc663_mode8_inithook,
18444 },
622e84cd
KY
18445 [ALC272_DELL] = {
18446 .mixers = { alc663_m51va_mixer },
18447 .cap_mixer = alc272_auto_capture_mixer,
18448 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
18449 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18450 .dac_nids = alc662_dac_nids,
18451 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18452 .adc_nids = alc272_adc_nids,
18453 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18454 .capsrc_nids = alc272_capsrc_nids,
18455 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18456 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18457 .setup = alc663_m51va_setup,
622e84cd
KY
18458 .init_hook = alc663_m51va_inithook,
18459 },
18460 [ALC272_DELL_ZM1] = {
18461 .mixers = { alc663_m51va_mixer },
18462 .cap_mixer = alc662_auto_capture_mixer,
18463 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_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 = alc662_adc_nids,
b59bdf3b 18468 .num_adc_nids = 1,
622e84cd
KY
18469 .capsrc_nids = alc662_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 },
9541ba1d
CP
18475 [ALC272_SAMSUNG_NC10] = {
18476 .mixers = { alc272_nc10_mixer },
18477 .init_verbs = { alc662_init_verbs,
18478 alc663_21jd_amic_init_verbs },
18479 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18480 .dac_nids = alc272_dac_nids,
18481 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18482 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18483 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 18484 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18485 .setup = alc663_mode4_setup,
9541ba1d
CP
18486 .init_hook = alc663_mode4_inithook,
18487 },
bc9f98a9
KY
18488};
18489
18490
18491/*
18492 * BIOS auto configuration
18493 */
18494
7085ec12
TI
18495/* convert from MIX nid to DAC */
18496static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
18497{
18498 if (nid == 0x0f)
18499 return 0x02;
18500 else if (nid >= 0x0c && nid <= 0x0e)
18501 return nid - 0x0c + 0x02;
18502 else
18503 return 0;
18504}
18505
18506/* get MIX nid connected to the given pin targeted to DAC */
18507static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18508 hda_nid_t dac)
18509{
18510 hda_nid_t mix[4];
18511 int i, num;
18512
18513 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18514 for (i = 0; i < num; i++) {
18515 if (alc662_mix_to_dac(mix[i]) == dac)
18516 return mix[i];
18517 }
18518 return 0;
18519}
18520
18521/* look for an empty DAC slot */
18522static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18523{
18524 struct alc_spec *spec = codec->spec;
18525 hda_nid_t srcs[5];
18526 int i, j, num;
18527
18528 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18529 if (num < 0)
18530 return 0;
18531 for (i = 0; i < num; i++) {
18532 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
18533 if (!nid)
18534 continue;
18535 for (j = 0; j < spec->multiout.num_dacs; j++)
18536 if (spec->multiout.dac_nids[j] == nid)
18537 break;
18538 if (j >= spec->multiout.num_dacs)
18539 return nid;
18540 }
18541 return 0;
18542}
18543
18544/* fill in the dac_nids table from the parsed pin configuration */
18545static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18546 const struct auto_pin_cfg *cfg)
18547{
18548 struct alc_spec *spec = codec->spec;
18549 int i;
18550 hda_nid_t dac;
18551
18552 spec->multiout.dac_nids = spec->private_dac_nids;
18553 for (i = 0; i < cfg->line_outs; i++) {
18554 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
18555 if (!dac)
18556 continue;
18557 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
18558 }
18559 return 0;
18560}
18561
0afe5f89 18562static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18563 hda_nid_t nid, unsigned int chs)
18564{
0afe5f89 18565 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
7085ec12
TI
18566 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18567}
18568
0afe5f89 18569static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18570 hda_nid_t nid, unsigned int chs)
18571{
0afe5f89 18572 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12
TI
18573 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18574}
18575
18576#define alc662_add_stereo_vol(spec, pfx, nid) \
18577 alc662_add_vol_ctl(spec, pfx, nid, 3)
18578#define alc662_add_stereo_sw(spec, pfx, nid) \
18579 alc662_add_sw_ctl(spec, pfx, nid, 3)
18580
bc9f98a9 18581/* add playback controls from the parsed DAC table */
7085ec12 18582static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
18583 const struct auto_pin_cfg *cfg)
18584{
7085ec12 18585 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18586 static const char *chname[4] = {
18587 "Front", "Surround", NULL /*CLFE*/, "Side"
18588 };
7085ec12 18589 hda_nid_t nid, mix;
bc9f98a9
KY
18590 int i, err;
18591
18592 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
18593 nid = spec->multiout.dac_nids[i];
18594 if (!nid)
18595 continue;
18596 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
18597 if (!mix)
bc9f98a9 18598 continue;
bc9f98a9
KY
18599 if (i == 2) {
18600 /* Center/LFE */
7085ec12 18601 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
18602 if (err < 0)
18603 return err;
7085ec12 18604 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
18605 if (err < 0)
18606 return err;
7085ec12 18607 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
18608 if (err < 0)
18609 return err;
7085ec12 18610 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
18611 if (err < 0)
18612 return err;
18613 } else {
0d884cb9
TI
18614 const char *pfx;
18615 if (cfg->line_outs == 1 &&
18616 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
7085ec12 18617 if (cfg->hp_outs)
0d884cb9
TI
18618 pfx = "Speaker";
18619 else
18620 pfx = "PCM";
18621 } else
18622 pfx = chname[i];
7085ec12 18623 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
bc9f98a9
KY
18624 if (err < 0)
18625 return err;
0d884cb9
TI
18626 if (cfg->line_outs == 1 &&
18627 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
18628 pfx = "Speaker";
7085ec12 18629 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
bc9f98a9
KY
18630 if (err < 0)
18631 return err;
18632 }
18633 }
18634 return 0;
18635}
18636
18637/* add playback controls for speaker and HP outputs */
7085ec12
TI
18638/* return DAC nid if any new DAC is assigned */
18639static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
18640 const char *pfx)
18641{
7085ec12
TI
18642 struct alc_spec *spec = codec->spec;
18643 hda_nid_t nid, mix;
bc9f98a9 18644 int err;
bc9f98a9
KY
18645
18646 if (!pin)
18647 return 0;
7085ec12
TI
18648 nid = alc662_look_for_dac(codec, pin);
18649 if (!nid) {
7085ec12
TI
18650 /* the corresponding DAC is already occupied */
18651 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18652 return 0; /* no way */
18653 /* create a switch only */
0afe5f89 18654 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 18655 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
18656 }
18657
7085ec12
TI
18658 mix = alc662_dac_to_mix(codec, pin, nid);
18659 if (!mix)
18660 return 0;
18661 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
18662 if (err < 0)
18663 return err;
18664 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
18665 if (err < 0)
18666 return err;
18667 return nid;
bc9f98a9
KY
18668}
18669
18670/* create playback/capture controls for input pins */
05f5f477 18671#define alc662_auto_create_input_ctls \
4b7348a1 18672 alc882_auto_create_input_ctls
bc9f98a9
KY
18673
18674static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
18675 hda_nid_t nid, int pin_type,
7085ec12 18676 hda_nid_t dac)
bc9f98a9 18677{
7085ec12 18678 int i, num;
ce503f38 18679 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 18680
f6c7e546 18681 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 18682 /* need the manual connection? */
7085ec12
TI
18683 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
18684 if (num <= 1)
18685 return;
18686 for (i = 0; i < num; i++) {
18687 if (alc662_mix_to_dac(srcs[i]) != dac)
18688 continue;
18689 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
18690 return;
bc9f98a9
KY
18691 }
18692}
18693
18694static void alc662_auto_init_multi_out(struct hda_codec *codec)
18695{
18696 struct alc_spec *spec = codec->spec;
7085ec12 18697 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
18698 int i;
18699
18700 for (i = 0; i <= HDA_SIDE; i++) {
18701 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18702 if (nid)
baba8ee9 18703 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 18704 spec->multiout.dac_nids[i]);
bc9f98a9
KY
18705 }
18706}
18707
18708static void alc662_auto_init_hp_out(struct hda_codec *codec)
18709{
18710 struct alc_spec *spec = codec->spec;
18711 hda_nid_t pin;
18712
18713 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
18714 if (pin)
18715 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
18716 spec->multiout.hp_nid);
f6c7e546
TI
18717 pin = spec->autocfg.speaker_pins[0];
18718 if (pin)
7085ec12
TI
18719 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
18720 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
18721}
18722
bc9f98a9
KY
18723#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
18724
18725static void alc662_auto_init_analog_input(struct hda_codec *codec)
18726{
18727 struct alc_spec *spec = codec->spec;
18728 int i;
18729
18730 for (i = 0; i < AUTO_PIN_LAST; i++) {
18731 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 18732 if (alc_is_input_pin(codec, nid)) {
23f0c048 18733 alc_set_input_pin(codec, nid, i);
52ca15b7 18734 if (nid != ALC662_PIN_CD_NID &&
e82c025b 18735 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
18736 snd_hda_codec_write(codec, nid, 0,
18737 AC_VERB_SET_AMP_GAIN_MUTE,
18738 AMP_OUT_MUTE);
18739 }
18740 }
18741}
18742
f511b01c
TI
18743#define alc662_auto_init_input_src alc882_auto_init_input_src
18744
bc9f98a9
KY
18745static int alc662_parse_auto_config(struct hda_codec *codec)
18746{
18747 struct alc_spec *spec = codec->spec;
18748 int err;
18749 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
18750
18751 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
18752 alc662_ignore);
18753 if (err < 0)
18754 return err;
18755 if (!spec->autocfg.line_outs)
18756 return 0; /* can't find valid BIOS pin config */
18757
7085ec12 18758 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
18759 if (err < 0)
18760 return err;
7085ec12 18761 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
18762 if (err < 0)
18763 return err;
7085ec12 18764 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
18765 spec->autocfg.speaker_pins[0],
18766 "Speaker");
18767 if (err < 0)
18768 return err;
7085ec12
TI
18769 if (err)
18770 spec->multiout.extra_out_nid[0] = err;
18771 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
18772 "Headphone");
18773 if (err < 0)
18774 return err;
7085ec12
TI
18775 if (err)
18776 spec->multiout.hp_nid = err;
05f5f477 18777 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 18778 if (err < 0)
bc9f98a9
KY
18779 return err;
18780
18781 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
18782
757899ac 18783 alc_auto_parse_digital(codec);
bc9f98a9 18784
603c4019 18785 if (spec->kctls.list)
d88897ea 18786 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
18787
18788 spec->num_mux_defs = 1;
61b9b9b1 18789 spec->input_mux = &spec->private_imux[0];
ea1fb29a 18790
cec27c89
KY
18791 add_verb(spec, alc662_init_verbs);
18792 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
d1eb57f4 18793 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
cec27c89
KY
18794 add_verb(spec, alc663_init_verbs);
18795
18796 if (codec->vendor_id == 0x10ec0272)
18797 add_verb(spec, alc272_init_verbs);
ee979a14
TI
18798
18799 err = alc_auto_add_mic_boost(codec);
18800 if (err < 0)
18801 return err;
18802
6227cdce
KY
18803 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18804 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18805 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18806 else
18807 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 18808
8c87286f 18809 return 1;
bc9f98a9
KY
18810}
18811
18812/* additional initialization for auto-configuration model */
18813static void alc662_auto_init(struct hda_codec *codec)
18814{
f6c7e546 18815 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18816 alc662_auto_init_multi_out(codec);
18817 alc662_auto_init_hp_out(codec);
18818 alc662_auto_init_analog_input(codec);
f511b01c 18819 alc662_auto_init_input_src(codec);
757899ac 18820 alc_auto_init_digital(codec);
f6c7e546 18821 if (spec->unsol_event)
7fb0d78f 18822 alc_inithook(codec);
bc9f98a9
KY
18823}
18824
18825static int patch_alc662(struct hda_codec *codec)
18826{
18827 struct alc_spec *spec;
18828 int err, board_config;
18829
18830 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
18831 if (!spec)
18832 return -ENOMEM;
18833
18834 codec->spec = spec;
18835
da00c244
KY
18836 alc_auto_parse_customize_define(codec);
18837
2c3bf9ab
TI
18838 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18839
c027ddcd
KY
18840 if (alc_read_coef_idx(codec, 0) == 0x8020)
18841 alc_codec_rename(codec, "ALC661");
18842 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) &&
18843 codec->bus->pci->subsystem_vendor == 0x1025 &&
18844 spec->cdefine.platform_type == 1)
18845 alc_codec_rename(codec, "ALC272X");
274693f3 18846
bc9f98a9
KY
18847 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
18848 alc662_models,
18849 alc662_cfg_tbl);
18850 if (board_config < 0) {
9a11f1aa
TI
18851 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
18852 codec->chip_name);
bc9f98a9
KY
18853 board_config = ALC662_AUTO;
18854 }
18855
18856 if (board_config == ALC662_AUTO) {
18857 /* automatic parse from the BIOS config */
18858 err = alc662_parse_auto_config(codec);
18859 if (err < 0) {
18860 alc_free(codec);
18861 return err;
8c87286f 18862 } else if (!err) {
bc9f98a9
KY
18863 printk(KERN_INFO
18864 "hda_codec: Cannot set up configuration "
18865 "from BIOS. Using base mode...\n");
18866 board_config = ALC662_3ST_2ch_DIG;
18867 }
18868 }
18869
dc1eae25 18870 if (has_cdefine_beep(codec)) {
8af2591d
TI
18871 err = snd_hda_attach_beep_device(codec, 0x1);
18872 if (err < 0) {
18873 alc_free(codec);
18874 return err;
18875 }
680cd536
KK
18876 }
18877
bc9f98a9 18878 if (board_config != ALC662_AUTO)
e9c364c0 18879 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 18880
bc9f98a9
KY
18881 spec->stream_analog_playback = &alc662_pcm_analog_playback;
18882 spec->stream_analog_capture = &alc662_pcm_analog_capture;
18883
bc9f98a9
KY
18884 spec->stream_digital_playback = &alc662_pcm_digital_playback;
18885 spec->stream_digital_capture = &alc662_pcm_digital_capture;
18886
dd704698
TI
18887 if (!spec->adc_nids) {
18888 spec->adc_nids = alc662_adc_nids;
18889 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
18890 }
18891 if (!spec->capsrc_nids)
18892 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 18893
f9e336f6 18894 if (!spec->cap_mixer)
b59bdf3b 18895 set_capture_mixer(codec);
cec27c89 18896
dc1eae25 18897 if (has_cdefine_beep(codec)) {
da00c244
KY
18898 switch (codec->vendor_id) {
18899 case 0x10ec0662:
18900 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18901 break;
18902 case 0x10ec0272:
18903 case 0x10ec0663:
18904 case 0x10ec0665:
18905 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18906 break;
18907 case 0x10ec0273:
18908 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18909 break;
18910 }
cec27c89 18911 }
2134ea4f
TI
18912 spec->vmaster_nid = 0x02;
18913
bc9f98a9
KY
18914 codec->patch_ops = alc_patch_ops;
18915 if (board_config == ALC662_AUTO)
18916 spec->init_hook = alc662_auto_init;
cb53c626
TI
18917#ifdef CONFIG_SND_HDA_POWER_SAVE
18918 if (!spec->loopback.amplist)
18919 spec->loopback.amplist = alc662_loopbacks;
18920#endif
bc9f98a9
KY
18921
18922 return 0;
18923}
18924
274693f3
KY
18925static int patch_alc888(struct hda_codec *codec)
18926{
18927 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
18928 kfree(codec->chip_name);
18929 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
18930 if (!codec->chip_name) {
18931 alc_free(codec);
274693f3 18932 return -ENOMEM;
ac2c92e0
TI
18933 }
18934 return patch_alc662(codec);
274693f3 18935 }
ac2c92e0 18936 return patch_alc882(codec);
274693f3
KY
18937}
18938
d1eb57f4
KY
18939/*
18940 * ALC680 support
18941 */
18942#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
18943#define alc680_modes alc260_modes
18944
18945static hda_nid_t alc680_dac_nids[3] = {
18946 /* Lout1, Lout2, hp */
18947 0x02, 0x03, 0x04
18948};
18949
18950static hda_nid_t alc680_adc_nids[3] = {
18951 /* ADC0-2 */
18952 /* DMIC, MIC, Line-in*/
18953 0x07, 0x08, 0x09
18954};
18955
18956static struct snd_kcontrol_new alc680_base_mixer[] = {
18957 /* output mixer control */
18958 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
18959 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18960 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
18961 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
18962 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
18963 { }
18964};
18965
18966static struct snd_kcontrol_new alc680_capture_mixer[] = {
18967 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
18968 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
18969 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
18970 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
18971 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
18972 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
18973 { } /* end */
18974};
18975
18976/*
18977 * generic initialization of ADC, input mixers and output mixers
18978 */
18979static struct hda_verb alc680_init_verbs[] = {
18980 /* Unmute DAC0-1 and set vol = 0 */
18981 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
18982 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
18983 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
18984
18985 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
18986 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
18987 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
18988 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
18989 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
18990
18991 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
18992 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
18993 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
18994 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
18995 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
18996 { }
18997};
18998
18999/* create input playback/capture controls for the given pin */
19000static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19001 const char *ctlname, int idx)
19002{
19003 hda_nid_t dac;
19004 int err;
19005
19006 switch (nid) {
19007 case 0x14:
19008 dac = 0x02;
19009 break;
19010 case 0x15:
19011 dac = 0x03;
19012 break;
19013 case 0x16:
19014 dac = 0x04;
19015 break;
19016 default:
19017 return 0;
19018 }
19019 if (spec->multiout.dac_nids[0] != dac &&
19020 spec->multiout.dac_nids[1] != dac) {
19021 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19022 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19023 HDA_OUTPUT));
19024 if (err < 0)
19025 return err;
19026
19027 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19028 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19029
19030 if (err < 0)
19031 return err;
19032 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19033 }
19034
19035 return 0;
19036}
19037
19038/* add playback controls from the parsed DAC table */
19039static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19040 const struct auto_pin_cfg *cfg)
19041{
19042 hda_nid_t nid;
19043 int err;
19044
19045 spec->multiout.dac_nids = spec->private_dac_nids;
19046
19047 nid = cfg->line_out_pins[0];
19048 if (nid) {
19049 const char *name;
19050 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19051 name = "Speaker";
19052 else
19053 name = "Front";
19054 err = alc680_new_analog_output(spec, nid, name, 0);
19055 if (err < 0)
19056 return err;
19057 }
19058
19059 nid = cfg->speaker_pins[0];
19060 if (nid) {
19061 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19062 if (err < 0)
19063 return err;
19064 }
19065 nid = cfg->hp_pins[0];
19066 if (nid) {
19067 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19068 if (err < 0)
19069 return err;
19070 }
19071
19072 return 0;
19073}
19074
19075static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19076 hda_nid_t nid, int pin_type)
19077{
19078 alc_set_pin_output(codec, nid, pin_type);
19079}
19080
19081static void alc680_auto_init_multi_out(struct hda_codec *codec)
19082{
19083 struct alc_spec *spec = codec->spec;
19084 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19085 if (nid) {
19086 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19087 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19088 }
19089}
19090
19091static void alc680_auto_init_hp_out(struct hda_codec *codec)
19092{
19093 struct alc_spec *spec = codec->spec;
19094 hda_nid_t pin;
19095
19096 pin = spec->autocfg.hp_pins[0];
19097 if (pin)
19098 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19099 pin = spec->autocfg.speaker_pins[0];
19100 if (pin)
19101 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19102}
19103
19104/* pcm configuration: identical with ALC880 */
19105#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19106#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19107#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19108#define alc680_pcm_digital_playback alc880_pcm_digital_playback
19109
19110static struct hda_input_mux alc680_capture_source = {
19111 .num_items = 1,
19112 .items = {
19113 { "Mic", 0x0 },
19114 },
19115};
19116
19117/*
19118 * BIOS auto configuration
19119 */
19120static int alc680_parse_auto_config(struct hda_codec *codec)
19121{
19122 struct alc_spec *spec = codec->spec;
19123 int err;
19124 static hda_nid_t alc680_ignore[] = { 0 };
19125
19126 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19127 alc680_ignore);
19128 if (err < 0)
19129 return err;
19130 if (!spec->autocfg.line_outs) {
19131 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19132 spec->multiout.max_channels = 2;
19133 spec->no_analog = 1;
19134 goto dig_only;
19135 }
19136 return 0; /* can't find valid BIOS pin config */
19137 }
19138 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19139 if (err < 0)
19140 return err;
19141
19142 spec->multiout.max_channels = 2;
19143
19144 dig_only:
19145 /* digital only support output */
757899ac 19146 alc_auto_parse_digital(codec);
d1eb57f4
KY
19147 if (spec->kctls.list)
19148 add_mixer(spec, spec->kctls.list);
19149
19150 add_verb(spec, alc680_init_verbs);
19151 spec->num_mux_defs = 1;
19152 spec->input_mux = &alc680_capture_source;
19153
19154 err = alc_auto_add_mic_boost(codec);
19155 if (err < 0)
19156 return err;
19157
19158 return 1;
19159}
19160
19161#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19162
19163/* init callback for auto-configuration model -- overriding the default init */
19164static void alc680_auto_init(struct hda_codec *codec)
19165{
19166 struct alc_spec *spec = codec->spec;
19167 alc680_auto_init_multi_out(codec);
19168 alc680_auto_init_hp_out(codec);
19169 alc680_auto_init_analog_input(codec);
757899ac 19170 alc_auto_init_digital(codec);
d1eb57f4
KY
19171 if (spec->unsol_event)
19172 alc_inithook(codec);
19173}
19174
19175/*
19176 * configuration and preset
19177 */
19178static const char *alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19179 [ALC680_BASE] = "base",
19180 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19181};
19182
19183static struct snd_pci_quirk alc680_cfg_tbl[] = {
19184 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19185 {}
19186};
19187
19188static struct alc_config_preset alc680_presets[] = {
19189 [ALC680_BASE] = {
19190 .mixers = { alc680_base_mixer },
19191 .cap_mixer = alc680_capture_mixer,
19192 .init_verbs = { alc680_init_verbs },
19193 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19194 .dac_nids = alc680_dac_nids,
19195 .num_adc_nids = ARRAY_SIZE(alc680_adc_nids),
19196 .adc_nids = alc680_adc_nids,
19197 .hp_nid = 0x04,
19198 .dig_out_nid = ALC680_DIGOUT_NID,
19199 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19200 .channel_mode = alc680_modes,
19201 .input_mux = &alc680_capture_source,
19202 },
19203};
19204
19205static int patch_alc680(struct hda_codec *codec)
19206{
19207 struct alc_spec *spec;
19208 int board_config;
19209 int err;
19210
19211 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19212 if (spec == NULL)
19213 return -ENOMEM;
19214
19215 codec->spec = spec;
19216
19217 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19218 alc680_models,
19219 alc680_cfg_tbl);
19220
19221 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19222 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19223 codec->chip_name);
19224 board_config = ALC680_AUTO;
19225 }
19226
19227 if (board_config == ALC680_AUTO) {
19228 /* automatic parse from the BIOS config */
19229 err = alc680_parse_auto_config(codec);
19230 if (err < 0) {
19231 alc_free(codec);
19232 return err;
19233 } else if (!err) {
19234 printk(KERN_INFO
19235 "hda_codec: Cannot set up configuration "
19236 "from BIOS. Using base mode...\n");
19237 board_config = ALC680_BASE;
19238 }
19239 }
19240
19241 if (board_config != ALC680_AUTO)
19242 setup_preset(codec, &alc680_presets[board_config]);
19243
19244 spec->stream_analog_playback = &alc680_pcm_analog_playback;
19245 spec->stream_analog_capture = &alc680_pcm_analog_capture;
19246 spec->stream_analog_alt_capture = &alc680_pcm_analog_alt_capture;
19247 spec->stream_digital_playback = &alc680_pcm_digital_playback;
19248
19249 if (!spec->adc_nids) {
19250 spec->adc_nids = alc680_adc_nids;
19251 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19252 }
19253
19254 if (!spec->cap_mixer)
19255 set_capture_mixer(codec);
19256
19257 spec->vmaster_nid = 0x02;
19258
19259 codec->patch_ops = alc_patch_ops;
19260 if (board_config == ALC680_AUTO)
19261 spec->init_hook = alc680_auto_init;
19262
19263 return 0;
19264}
19265
1da177e4
LT
19266/*
19267 * patch entries
19268 */
1289e9e8 19269static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 19270 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 19271 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 19272 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 19273 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 19274 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 19275 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 19276 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 19277 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 19278 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 19279 .patch = patch_alc861 },
f32610ed
JS
19280 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19281 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19282 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 19283 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 19284 .patch = patch_alc882 },
bc9f98a9
KY
19285 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19286 .patch = patch_alc662 },
6dda9f4a 19287 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 19288 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 19289 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 19290 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 19291 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 19292 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 19293 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 19294 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 19295 .patch = patch_alc882 },
cb308f97 19296 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 19297 .patch = patch_alc882 },
df694daa 19298 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
4953550a 19299 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
4442608d 19300 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 19301 .patch = patch_alc882 },
274693f3 19302 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 19303 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 19304 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
19305 {} /* terminator */
19306};
1289e9e8
TI
19307
19308MODULE_ALIAS("snd-hda-codec-id:10ec*");
19309
19310MODULE_LICENSE("GPL");
19311MODULE_DESCRIPTION("Realtek HD-audio codec");
19312
19313static struct hda_codec_preset_list realtek_list = {
19314 .preset = snd_hda_preset_realtek,
19315 .owner = THIS_MODULE,
19316};
19317
19318static int __init patch_realtek_init(void)
19319{
19320 return snd_hda_add_codec_preset(&realtek_list);
19321}
19322
19323static void __exit patch_realtek_exit(void)
19324{
19325 snd_hda_delete_codec_preset(&realtek_list);
19326}
19327
19328module_init(patch_realtek_init)
19329module_exit(patch_realtek_exit)