]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Add a warning for ignored pins with ALC259/268/269
[mirror_ubuntu-jammy-kernel.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
31#include "hda_codec.h"
32#include "hda_local.h"
680cd536 33#include "hda_beep.h"
1da177e4 34
ccc656ce
KY
35#define ALC880_FRONT_EVENT 0x01
36#define ALC880_DCVOL_EVENT 0x02
37#define ALC880_HP_EVENT 0x04
38#define ALC880_MIC_EVENT 0x08
1da177e4
LT
39
40/* ALC880 board config type */
41enum {
1da177e4
LT
42 ALC880_3ST,
43 ALC880_3ST_DIG,
44 ALC880_5ST,
45 ALC880_5ST_DIG,
46 ALC880_W810,
dfc0ff62 47 ALC880_Z71V,
b6482d48 48 ALC880_6ST,
16ded525
TI
49 ALC880_6ST_DIG,
50 ALC880_F1734,
51 ALC880_ASUS,
52 ALC880_ASUS_DIG,
53 ALC880_ASUS_W1V,
df694daa 54 ALC880_ASUS_DIG2,
2cf9f0fc 55 ALC880_FUJITSU,
16ded525 56 ALC880_UNIWILL_DIG,
ccc656ce
KY
57 ALC880_UNIWILL,
58 ALC880_UNIWILL_P53,
df694daa
KY
59 ALC880_CLEVO,
60 ALC880_TCL_S700,
ae6b813a 61 ALC880_LG,
d681518a 62 ALC880_LG_LW,
df99cd33 63 ALC880_MEDION_RIM,
e9edcee0
TI
64#ifdef CONFIG_SND_DEBUG
65 ALC880_TEST,
66#endif
df694daa 67 ALC880_AUTO,
16ded525
TI
68 ALC880_MODEL_LAST /* last tag */
69};
70
71/* ALC260 models */
72enum {
73 ALC260_BASIC,
74 ALC260_HP,
3f878308 75 ALC260_HP_DC7600,
df694daa
KY
76 ALC260_HP_3013,
77 ALC260_FUJITSU_S702X,
0bfc90e9 78 ALC260_ACER,
bc9f98a9
KY
79 ALC260_WILL,
80 ALC260_REPLACER_672V,
cc959489 81 ALC260_FAVORIT100,
7cf51e48
JW
82#ifdef CONFIG_SND_DEBUG
83 ALC260_TEST,
84#endif
df694daa 85 ALC260_AUTO,
16ded525 86 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
87};
88
df694daa
KY
89/* ALC262 models */
90enum {
91 ALC262_BASIC,
ccc656ce
KY
92 ALC262_HIPPO,
93 ALC262_HIPPO_1,
834be88d 94 ALC262_FUJITSU,
9c7f852e 95 ALC262_HP_BPC,
cd7509a4
KY
96 ALC262_HP_BPC_D7000_WL,
97 ALC262_HP_BPC_D7000_WF,
66d2a9d6 98 ALC262_HP_TC_T5735,
8c427226 99 ALC262_HP_RP5700,
304dcaac 100 ALC262_BENQ_ED8,
272a527c 101 ALC262_SONY_ASSAMD,
83c34218 102 ALC262_BENQ_T31,
f651b50b 103 ALC262_ULTRA,
0e31daf7 104 ALC262_LENOVO_3000,
e8f9ae2a 105 ALC262_NEC,
4e555fe5 106 ALC262_TOSHIBA_S06,
9f99a638 107 ALC262_TOSHIBA_RX1,
ba340e82 108 ALC262_TYAN,
df694daa
KY
109 ALC262_AUTO,
110 ALC262_MODEL_LAST /* last tag */
111};
112
a361d84b
KY
113/* ALC268 models */
114enum {
eb5a6621 115 ALC267_QUANTA_IL1,
a361d84b 116 ALC268_3ST,
d1a991a6 117 ALC268_TOSHIBA,
d273809e 118 ALC268_ACER,
c238b4f4 119 ALC268_ACER_DMIC,
8ef355da 120 ALC268_ACER_ASPIRE_ONE,
3866f0b0 121 ALC268_DELL,
f12462c5 122 ALC268_ZEPTO,
86c53bd2
JW
123#ifdef CONFIG_SND_DEBUG
124 ALC268_TEST,
125#endif
a361d84b
KY
126 ALC268_AUTO,
127 ALC268_MODEL_LAST /* last tag */
128};
129
f6a92248
KY
130/* ALC269 models */
131enum {
132 ALC269_BASIC,
60db6b53 133 ALC269_QUANTA_FL1,
84898e87
KY
134 ALC269_AMIC,
135 ALC269_DMIC,
136 ALC269VB_AMIC,
137 ALC269VB_DMIC,
26f5df26 138 ALC269_FUJITSU,
64154835 139 ALC269_LIFEBOOK,
f6a92248
KY
140 ALC269_AUTO,
141 ALC269_MODEL_LAST /* last tag */
142};
143
df694daa
KY
144/* ALC861 models */
145enum {
146 ALC861_3ST,
9c7f852e 147 ALC660_3ST,
df694daa
KY
148 ALC861_3ST_DIG,
149 ALC861_6ST_DIG,
22309c3e 150 ALC861_UNIWILL_M31,
a53d1aec 151 ALC861_TOSHIBA,
7cdbff94 152 ALC861_ASUS,
56bb0cab 153 ALC861_ASUS_LAPTOP,
df694daa
KY
154 ALC861_AUTO,
155 ALC861_MODEL_LAST,
156};
157
f32610ed
JS
158/* ALC861-VD models */
159enum {
160 ALC660VD_3ST,
6963f84c 161 ALC660VD_3ST_DIG,
13c94744 162 ALC660VD_ASUS_V1S,
f32610ed
JS
163 ALC861VD_3ST,
164 ALC861VD_3ST_DIG,
165 ALC861VD_6ST_DIG,
bdd148a3 166 ALC861VD_LENOVO,
272a527c 167 ALC861VD_DALLAS,
d1a991a6 168 ALC861VD_HP,
f32610ed
JS
169 ALC861VD_AUTO,
170 ALC861VD_MODEL_LAST,
171};
172
bc9f98a9
KY
173/* ALC662 models */
174enum {
175 ALC662_3ST_2ch_DIG,
176 ALC662_3ST_6ch_DIG,
177 ALC662_3ST_6ch,
178 ALC662_5ST_DIG,
179 ALC662_LENOVO_101E,
291702f0 180 ALC662_ASUS_EEEPC_P701,
8c427226 181 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
182 ALC663_ASUS_M51VA,
183 ALC663_ASUS_G71V,
184 ALC663_ASUS_H13,
185 ALC663_ASUS_G50V,
f1d4e28b
KY
186 ALC662_ECS,
187 ALC663_ASUS_MODE1,
188 ALC662_ASUS_MODE2,
189 ALC663_ASUS_MODE3,
190 ALC663_ASUS_MODE4,
191 ALC663_ASUS_MODE5,
192 ALC663_ASUS_MODE6,
ebb83eeb
KY
193 ALC663_ASUS_MODE7,
194 ALC663_ASUS_MODE8,
622e84cd
KY
195 ALC272_DELL,
196 ALC272_DELL_ZM1,
9541ba1d 197 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
198 ALC662_AUTO,
199 ALC662_MODEL_LAST,
200};
201
df694daa
KY
202/* ALC882 models */
203enum {
204 ALC882_3ST_DIG,
205 ALC882_6ST_DIG,
4b146cb0 206 ALC882_ARIMA,
bdd148a3 207 ALC882_W2JC,
272a527c
KY
208 ALC882_TARGA,
209 ALC882_ASUS_A7J,
914759b7 210 ALC882_ASUS_A7M,
9102cd1c 211 ALC885_MACPRO,
76e6f5a9 212 ALC885_MBA21,
87350ad0 213 ALC885_MBP3,
41d5545d 214 ALC885_MB5,
e458b1fa 215 ALC885_MACMINI3,
c54728d8 216 ALC885_IMAC24,
4b7e1803 217 ALC885_IMAC91,
9c7f852e
TI
218 ALC883_3ST_2ch_DIG,
219 ALC883_3ST_6ch_DIG,
220 ALC883_3ST_6ch,
221 ALC883_6ST_DIG,
ccc656ce
KY
222 ALC883_TARGA_DIG,
223 ALC883_TARGA_2ch_DIG,
64a8be74 224 ALC883_TARGA_8ch_DIG,
bab282b9 225 ALC883_ACER,
2880a867 226 ALC883_ACER_ASPIRE,
5b2d1eca 227 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 228 ALC888_ACER_ASPIRE_6530G,
3b315d70 229 ALC888_ACER_ASPIRE_8930G,
fc86f954 230 ALC888_ACER_ASPIRE_7730G,
c07584c8 231 ALC883_MEDION,
ea1fb29a 232 ALC883_MEDION_MD2,
7ad7b218 233 ALC883_MEDION_WIM2160,
b373bdeb 234 ALC883_LAPTOP_EAPD,
bc9f98a9 235 ALC883_LENOVO_101E_2ch,
272a527c 236 ALC883_LENOVO_NB0763,
189609ae 237 ALC888_LENOVO_MS7195_DIG,
e2757d5e 238 ALC888_LENOVO_SKY,
ea1fb29a 239 ALC883_HAIER_W66,
4723c022 240 ALC888_3ST_HP,
5795b9e6 241 ALC888_6ST_DELL,
a8848bd6 242 ALC883_MITAC,
a65cc60f 243 ALC883_CLEVO_M540R,
0c4cc443 244 ALC883_CLEVO_M720,
fb97dc67 245 ALC883_FUJITSU_PI2515,
ef8ef5fb 246 ALC888_FUJITSU_XA3530,
17bba1b7 247 ALC883_3ST_6ch_INTEL,
87a8c370
JK
248 ALC889A_INTEL,
249 ALC889_INTEL,
e2757d5e
KY
250 ALC888_ASUS_M90V,
251 ALC888_ASUS_EEE1601,
eb4c41d3 252 ALC889A_MB31,
3ab90935 253 ALC1200_ASUS_P5Q,
3e1647c5 254 ALC883_SONY_VAIO_TT,
4953550a
TI
255 ALC882_AUTO,
256 ALC882_MODEL_LAST,
9c7f852e
TI
257};
258
d4a86d81
TI
259/* ALC680 models */
260enum {
261 ALC680_BASE,
262 ALC680_AUTO,
263 ALC680_MODEL_LAST,
264};
265
df694daa
KY
266/* for GPIO Poll */
267#define GPIO_MASK 0x03
268
4a79ba34
TI
269/* extra amp-initialization sequence types */
270enum {
271 ALC_INIT_NONE,
272 ALC_INIT_DEFAULT,
273 ALC_INIT_GPIO1,
274 ALC_INIT_GPIO2,
275 ALC_INIT_GPIO3,
276};
277
6c819492
TI
278struct alc_mic_route {
279 hda_nid_t pin;
280 unsigned char mux_idx;
281 unsigned char amix_idx;
282};
283
284#define MUX_IDX_UNDEF ((unsigned char)-1)
285
da00c244
KY
286struct alc_customize_define {
287 unsigned int sku_cfg;
288 unsigned char port_connectivity;
289 unsigned char check_sum;
290 unsigned char customization;
291 unsigned char external_amp;
292 unsigned int enable_pcbeep:1;
293 unsigned int platform_type:1;
294 unsigned int swap:1;
295 unsigned int override:1;
296};
297
1da177e4
LT
298struct alc_spec {
299 /* codec parameterization */
df694daa 300 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 301 unsigned int num_mixers;
f9e336f6 302 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 303 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 304
2d9c6482 305 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
306 * don't forget NULL
307 * termination!
e9edcee0
TI
308 */
309 unsigned int num_init_verbs;
1da177e4 310
aa563af7 311 char stream_name_analog[32]; /* analog PCM stream */
1da177e4
LT
312 struct hda_pcm_stream *stream_analog_playback;
313 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
314 struct hda_pcm_stream *stream_analog_alt_playback;
315 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 316
aa563af7 317 char stream_name_digital[32]; /* digital PCM stream */
1da177e4
LT
318 struct hda_pcm_stream *stream_digital_playback;
319 struct hda_pcm_stream *stream_digital_capture;
320
321 /* playback */
16ded525
TI
322 struct hda_multi_out multiout; /* playback set-up
323 * max_channels, dacs must be set
324 * dig_out_nid and hp_nid are optional
325 */
6330079f 326 hda_nid_t alt_dac_nid;
6a05ac4a 327 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 328 int dig_out_type;
1da177e4
LT
329
330 /* capture */
331 unsigned int num_adc_nids;
332 hda_nid_t *adc_nids;
e1406348 333 hda_nid_t *capsrc_nids;
16ded525 334 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4 335
840b64c0
TI
336 /* capture setup for dynamic dual-adc switch */
337 unsigned int cur_adc_idx;
338 hda_nid_t cur_adc;
339 unsigned int cur_adc_stream_tag;
340 unsigned int cur_adc_format;
341
1da177e4 342 /* capture source */
a1e8d2da 343 unsigned int num_mux_defs;
1da177e4
LT
344 const struct hda_input_mux *input_mux;
345 unsigned int cur_mux[3];
6c819492
TI
346 struct alc_mic_route ext_mic;
347 struct alc_mic_route int_mic;
1da177e4
LT
348
349 /* channel model */
d2a6d7dc 350 const struct hda_channel_mode *channel_mode;
1da177e4 351 int num_channel_mode;
4e195a7b 352 int need_dac_fix;
3b315d70
HM
353 int const_channel_count;
354 int ext_channel_count;
1da177e4
LT
355
356 /* PCM information */
4c5186ed 357 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 358
e9edcee0
TI
359 /* dynamic controls, init_verbs and input_mux */
360 struct auto_pin_cfg autocfg;
da00c244 361 struct alc_customize_define cdefine;
603c4019 362 struct snd_array kctls;
61b9b9b1 363 struct hda_input_mux private_imux[3];
41923e44 364 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
365 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
366 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 367
ae6b813a
TI
368 /* hooks */
369 void (*init_hook)(struct hda_codec *codec);
370 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 371#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 372 void (*power_hook)(struct hda_codec *codec);
f5de24b0 373#endif
ae6b813a 374
834be88d
TI
375 /* for pin sensing */
376 unsigned int sense_updated: 1;
377 unsigned int jack_present: 1;
bec15c3a 378 unsigned int master_sw: 1;
6c819492 379 unsigned int auto_mic:1;
cb53c626 380
e64f14f4
TI
381 /* other flags */
382 unsigned int no_analog :1; /* digital I/O only */
840b64c0 383 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
4a79ba34 384 int init_amp;
e64f14f4 385
2134ea4f
TI
386 /* for virtual master */
387 hda_nid_t vmaster_nid;
cb53c626
TI
388#ifdef CONFIG_SND_HDA_POWER_SAVE
389 struct hda_loopback_check loopback;
390#endif
2c3bf9ab
TI
391
392 /* for PLL fix */
393 hda_nid_t pll_nid;
394 unsigned int pll_coef_idx, pll_coef_bit;
df694daa
KY
395};
396
397/*
398 * configuration template - to be copied to the spec instance
399 */
400struct alc_config_preset {
9c7f852e
TI
401 struct snd_kcontrol_new *mixers[5]; /* should be identical size
402 * with spec
403 */
f9e336f6 404 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
405 const struct hda_verb *init_verbs[5];
406 unsigned int num_dacs;
407 hda_nid_t *dac_nids;
408 hda_nid_t dig_out_nid; /* optional */
409 hda_nid_t hp_nid; /* optional */
b25c9da1 410 hda_nid_t *slave_dig_outs;
df694daa
KY
411 unsigned int num_adc_nids;
412 hda_nid_t *adc_nids;
e1406348 413 hda_nid_t *capsrc_nids;
df694daa
KY
414 hda_nid_t dig_in_nid;
415 unsigned int num_channel_mode;
416 const struct hda_channel_mode *channel_mode;
4e195a7b 417 int need_dac_fix;
3b315d70 418 int const_channel_count;
a1e8d2da 419 unsigned int num_mux_defs;
df694daa 420 const struct hda_input_mux *input_mux;
ae6b813a 421 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 422 void (*setup)(struct hda_codec *);
ae6b813a 423 void (*init_hook)(struct hda_codec *);
cb53c626
TI
424#ifdef CONFIG_SND_HDA_POWER_SAVE
425 struct hda_amp_list *loopbacks;
c97259df 426 void (*power_hook)(struct hda_codec *codec);
cb53c626 427#endif
1da177e4
LT
428};
429
1da177e4
LT
430
431/*
432 * input MUX handling
433 */
9c7f852e
TI
434static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
435 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
436{
437 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
438 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
439 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
440 if (mux_idx >= spec->num_mux_defs)
441 mux_idx = 0;
5311114d
TI
442 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
443 mux_idx = 0;
a1e8d2da 444 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
445}
446
9c7f852e
TI
447static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
448 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
449{
450 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
451 struct alc_spec *spec = codec->spec;
452 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
453
454 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
455 return 0;
456}
457
9c7f852e
TI
458static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
459 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
460{
461 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
462 struct alc_spec *spec = codec->spec;
cd896c33 463 const struct hda_input_mux *imux;
1da177e4 464 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 465 unsigned int mux_idx;
e1406348
TI
466 hda_nid_t nid = spec->capsrc_nids ?
467 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 468 unsigned int type;
1da177e4 469
cd896c33
TI
470 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
471 imux = &spec->input_mux[mux_idx];
5311114d
TI
472 if (!imux->num_items && mux_idx > 0)
473 imux = &spec->input_mux[0];
cd896c33 474
a22d543a 475 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 476 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
477 /* Matrix-mixer style (e.g. ALC882) */
478 unsigned int *cur_val = &spec->cur_mux[adc_idx];
479 unsigned int i, idx;
480
481 idx = ucontrol->value.enumerated.item[0];
482 if (idx >= imux->num_items)
483 idx = imux->num_items - 1;
484 if (*cur_val == idx)
485 return 0;
486 for (i = 0; i < imux->num_items; i++) {
487 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
488 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
489 imux->items[i].index,
490 HDA_AMP_MUTE, v);
491 }
492 *cur_val = idx;
493 return 1;
494 } else {
495 /* MUX style (e.g. ALC880) */
cd896c33 496 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
497 &spec->cur_mux[adc_idx]);
498 }
499}
e9edcee0 500
1da177e4
LT
501/*
502 * channel mode setting
503 */
9c7f852e
TI
504static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
505 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
506{
507 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
508 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
509 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
510 spec->num_channel_mode);
1da177e4
LT
511}
512
9c7f852e
TI
513static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
514 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
515{
516 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
517 struct alc_spec *spec = codec->spec;
d2a6d7dc 518 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 519 spec->num_channel_mode,
3b315d70 520 spec->ext_channel_count);
1da177e4
LT
521}
522
9c7f852e
TI
523static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
524 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
525{
526 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
527 struct alc_spec *spec = codec->spec;
4e195a7b
TI
528 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
529 spec->num_channel_mode,
3b315d70
HM
530 &spec->ext_channel_count);
531 if (err >= 0 && !spec->const_channel_count) {
532 spec->multiout.max_channels = spec->ext_channel_count;
533 if (spec->need_dac_fix)
534 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
535 }
4e195a7b 536 return err;
1da177e4
LT
537}
538
a9430dd8 539/*
4c5186ed 540 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 541 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
542 * being part of a format specifier. Maximum allowed length of a value is
543 * 63 characters plus NULL terminator.
7cf51e48
JW
544 *
545 * Note: some retasking pin complexes seem to ignore requests for input
546 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
547 * are requested. Therefore order this list so that this behaviour will not
548 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
549 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
550 * March 2006.
4c5186ed
JW
551 */
552static char *alc_pin_mode_names[] = {
7cf51e48
JW
553 "Mic 50pc bias", "Mic 80pc bias",
554 "Line in", "Line out", "Headphone out",
4c5186ed
JW
555};
556static unsigned char alc_pin_mode_values[] = {
7cf51e48 557 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
558};
559/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
560 * in the pin being assumed to be exclusively an input or an output pin. In
561 * addition, "input" pins may or may not process the mic bias option
562 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
563 * accept requests for bias as of chip versions up to March 2006) and/or
564 * wiring in the computer.
a9430dd8 565 */
a1e8d2da
JW
566#define ALC_PIN_DIR_IN 0x00
567#define ALC_PIN_DIR_OUT 0x01
568#define ALC_PIN_DIR_INOUT 0x02
569#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
570#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 571
ea1fb29a 572/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
573 * For each direction the minimum and maximum values are given.
574 */
a1e8d2da 575static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
576 { 0, 2 }, /* ALC_PIN_DIR_IN */
577 { 3, 4 }, /* ALC_PIN_DIR_OUT */
578 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
579 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
580 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
581};
582#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
583#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
584#define alc_pin_mode_n_items(_dir) \
585 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
586
9c7f852e
TI
587static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
588 struct snd_ctl_elem_info *uinfo)
a9430dd8 589{
4c5186ed
JW
590 unsigned int item_num = uinfo->value.enumerated.item;
591 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
592
593 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 594 uinfo->count = 1;
4c5186ed
JW
595 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
596
597 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
598 item_num = alc_pin_mode_min(dir);
599 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
600 return 0;
601}
602
9c7f852e
TI
603static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
604 struct snd_ctl_elem_value *ucontrol)
a9430dd8 605{
4c5186ed 606 unsigned int i;
a9430dd8
JW
607 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
608 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 609 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 610 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
611 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
612 AC_VERB_GET_PIN_WIDGET_CONTROL,
613 0x00);
a9430dd8 614
4c5186ed
JW
615 /* Find enumerated value for current pinctl setting */
616 i = alc_pin_mode_min(dir);
4b35d2ca 617 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 618 i++;
9c7f852e 619 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
620 return 0;
621}
622
9c7f852e
TI
623static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
624 struct snd_ctl_elem_value *ucontrol)
a9430dd8 625{
4c5186ed 626 signed int change;
a9430dd8
JW
627 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
628 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
629 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
630 long val = *ucontrol->value.integer.value;
9c7f852e
TI
631 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
632 AC_VERB_GET_PIN_WIDGET_CONTROL,
633 0x00);
a9430dd8 634
f12ab1e0 635 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
636 val = alc_pin_mode_min(dir);
637
638 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
639 if (change) {
640 /* Set pin mode to that requested */
82beb8fd
TI
641 snd_hda_codec_write_cache(codec, nid, 0,
642 AC_VERB_SET_PIN_WIDGET_CONTROL,
643 alc_pin_mode_values[val]);
cdcd9268 644
ea1fb29a 645 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
646 * for the requested pin mode. Enum values of 2 or less are
647 * input modes.
648 *
649 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
650 * reduces noise slightly (particularly on input) so we'll
651 * do it. However, having both input and output buffers
652 * enabled simultaneously doesn't seem to be problematic if
653 * this turns out to be necessary in the future.
cdcd9268
JW
654 */
655 if (val <= 2) {
47fd830a
TI
656 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
657 HDA_AMP_MUTE, HDA_AMP_MUTE);
658 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
659 HDA_AMP_MUTE, 0);
cdcd9268 660 } else {
47fd830a
TI
661 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
662 HDA_AMP_MUTE, HDA_AMP_MUTE);
663 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
664 HDA_AMP_MUTE, 0);
cdcd9268
JW
665 }
666 }
a9430dd8
JW
667 return change;
668}
669
4c5186ed 670#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 671 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 672 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
673 .info = alc_pin_mode_info, \
674 .get = alc_pin_mode_get, \
675 .put = alc_pin_mode_put, \
676 .private_value = nid | (dir<<16) }
df694daa 677
5c8f858d
JW
678/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
679 * together using a mask with more than one bit set. This control is
680 * currently used only by the ALC260 test model. At this stage they are not
681 * needed for any "production" models.
682 */
683#ifdef CONFIG_SND_DEBUG
a5ce8890 684#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 685
9c7f852e
TI
686static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
687 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
688{
689 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
690 hda_nid_t nid = kcontrol->private_value & 0xffff;
691 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
692 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
693 unsigned int val = snd_hda_codec_read(codec, nid, 0,
694 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
695
696 *valp = (val & mask) != 0;
697 return 0;
698}
9c7f852e
TI
699static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
700 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
701{
702 signed int change;
703 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
704 hda_nid_t nid = kcontrol->private_value & 0xffff;
705 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
706 long val = *ucontrol->value.integer.value;
9c7f852e
TI
707 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
708 AC_VERB_GET_GPIO_DATA,
709 0x00);
5c8f858d
JW
710
711 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
712 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
713 if (val == 0)
5c8f858d
JW
714 gpio_data &= ~mask;
715 else
716 gpio_data |= mask;
82beb8fd
TI
717 snd_hda_codec_write_cache(codec, nid, 0,
718 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
719
720 return change;
721}
722#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
723 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 724 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
725 .info = alc_gpio_data_info, \
726 .get = alc_gpio_data_get, \
727 .put = alc_gpio_data_put, \
728 .private_value = nid | (mask<<16) }
729#endif /* CONFIG_SND_DEBUG */
730
92621f13
JW
731/* A switch control to allow the enabling of the digital IO pins on the
732 * ALC260. This is incredibly simplistic; the intention of this control is
733 * to provide something in the test model allowing digital outputs to be
734 * identified if present. If models are found which can utilise these
735 * outputs a more complete mixer control can be devised for those models if
736 * necessary.
737 */
738#ifdef CONFIG_SND_DEBUG
a5ce8890 739#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 740
9c7f852e
TI
741static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
742 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
743{
744 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
745 hda_nid_t nid = kcontrol->private_value & 0xffff;
746 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
747 long *valp = ucontrol->value.integer.value;
9c7f852e 748 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 749 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
750
751 *valp = (val & mask) != 0;
752 return 0;
753}
9c7f852e
TI
754static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
755 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
756{
757 signed int change;
758 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
759 hda_nid_t nid = kcontrol->private_value & 0xffff;
760 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
761 long val = *ucontrol->value.integer.value;
9c7f852e 762 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 763 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 764 0x00);
92621f13
JW
765
766 /* Set/unset the masked control bit(s) as needed */
9c7f852e 767 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
768 if (val==0)
769 ctrl_data &= ~mask;
770 else
771 ctrl_data |= mask;
82beb8fd
TI
772 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
773 ctrl_data);
92621f13
JW
774
775 return change;
776}
777#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
778 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 779 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
780 .info = alc_spdif_ctrl_info, \
781 .get = alc_spdif_ctrl_get, \
782 .put = alc_spdif_ctrl_put, \
783 .private_value = nid | (mask<<16) }
784#endif /* CONFIG_SND_DEBUG */
785
f8225f6d
JW
786/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
787 * Again, this is only used in the ALC26x test models to help identify when
788 * the EAPD line must be asserted for features to work.
789 */
790#ifdef CONFIG_SND_DEBUG
791#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
792
793static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
794 struct snd_ctl_elem_value *ucontrol)
795{
796 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
797 hda_nid_t nid = kcontrol->private_value & 0xffff;
798 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
799 long *valp = ucontrol->value.integer.value;
800 unsigned int val = snd_hda_codec_read(codec, nid, 0,
801 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
802
803 *valp = (val & mask) != 0;
804 return 0;
805}
806
807static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
808 struct snd_ctl_elem_value *ucontrol)
809{
810 int change;
811 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
812 hda_nid_t nid = kcontrol->private_value & 0xffff;
813 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
814 long val = *ucontrol->value.integer.value;
815 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
816 AC_VERB_GET_EAPD_BTLENABLE,
817 0x00);
818
819 /* Set/unset the masked control bit(s) as needed */
820 change = (!val ? 0 : mask) != (ctrl_data & mask);
821 if (!val)
822 ctrl_data &= ~mask;
823 else
824 ctrl_data |= mask;
825 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
826 ctrl_data);
827
828 return change;
829}
830
831#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
832 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 833 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
834 .info = alc_eapd_ctrl_info, \
835 .get = alc_eapd_ctrl_get, \
836 .put = alc_eapd_ctrl_put, \
837 .private_value = nid | (mask<<16) }
838#endif /* CONFIG_SND_DEBUG */
839
23f0c048
TI
840/*
841 * set up the input pin config (depending on the given auto-pin type)
842 */
843static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
844 int auto_pin_type)
845{
846 unsigned int val = PIN_IN;
847
848 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
849 unsigned int pincap;
954a29c8
TI
850 unsigned int oldval;
851 oldval = snd_hda_codec_read(codec, nid, 0,
852 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1327a32b 853 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048 854 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
954a29c8
TI
855 /* if the default pin setup is vref50, we give it priority */
856 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
23f0c048 857 val = PIN_VREF80;
461c6c3a
TI
858 else if (pincap & AC_PINCAP_VREF_50)
859 val = PIN_VREF50;
860 else if (pincap & AC_PINCAP_VREF_100)
861 val = PIN_VREF100;
862 else if (pincap & AC_PINCAP_VREF_GRD)
863 val = PIN_VREFGRD;
23f0c048
TI
864 }
865 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
866}
867
d88897ea
TI
868/*
869 */
870static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
871{
872 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
873 return;
874 spec->mixers[spec->num_mixers++] = mix;
875}
876
877static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
878{
879 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
880 return;
881 spec->init_verbs[spec->num_init_verbs++] = verb;
882}
883
df694daa
KY
884/*
885 * set up from the preset table
886 */
e9c364c0 887static void setup_preset(struct hda_codec *codec,
9c7f852e 888 const struct alc_config_preset *preset)
df694daa 889{
e9c364c0 890 struct alc_spec *spec = codec->spec;
df694daa
KY
891 int i;
892
893 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 894 add_mixer(spec, preset->mixers[i]);
f9e336f6 895 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
896 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
897 i++)
d88897ea 898 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 899
df694daa
KY
900 spec->channel_mode = preset->channel_mode;
901 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 902 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 903 spec->const_channel_count = preset->const_channel_count;
df694daa 904
3b315d70
HM
905 if (preset->const_channel_count)
906 spec->multiout.max_channels = preset->const_channel_count;
907 else
908 spec->multiout.max_channels = spec->channel_mode[0].channels;
909 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
910
911 spec->multiout.num_dacs = preset->num_dacs;
912 spec->multiout.dac_nids = preset->dac_nids;
913 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 914 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 915 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 916
a1e8d2da 917 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 918 if (!spec->num_mux_defs)
a1e8d2da 919 spec->num_mux_defs = 1;
df694daa
KY
920 spec->input_mux = preset->input_mux;
921
922 spec->num_adc_nids = preset->num_adc_nids;
923 spec->adc_nids = preset->adc_nids;
e1406348 924 spec->capsrc_nids = preset->capsrc_nids;
df694daa 925 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
926
927 spec->unsol_event = preset->unsol_event;
928 spec->init_hook = preset->init_hook;
cb53c626 929#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 930 spec->power_hook = preset->power_hook;
cb53c626
TI
931 spec->loopback.amplist = preset->loopbacks;
932#endif
e9c364c0
TI
933
934 if (preset->setup)
935 preset->setup(codec);
df694daa
KY
936}
937
bc9f98a9
KY
938/* Enable GPIO mask and set output */
939static struct hda_verb alc_gpio1_init_verbs[] = {
940 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
941 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
942 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
943 { }
944};
945
946static struct hda_verb alc_gpio2_init_verbs[] = {
947 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
948 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
949 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
950 { }
951};
952
bdd148a3
KY
953static struct hda_verb alc_gpio3_init_verbs[] = {
954 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
955 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
956 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
957 { }
958};
959
2c3bf9ab
TI
960/*
961 * Fix hardware PLL issue
962 * On some codecs, the analog PLL gating control must be off while
963 * the default value is 1.
964 */
965static void alc_fix_pll(struct hda_codec *codec)
966{
967 struct alc_spec *spec = codec->spec;
968 unsigned int val;
969
970 if (!spec->pll_nid)
971 return;
972 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
973 spec->pll_coef_idx);
974 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
975 AC_VERB_GET_PROC_COEF, 0);
976 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
977 spec->pll_coef_idx);
978 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
979 val & ~(1 << spec->pll_coef_bit));
980}
981
982static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
983 unsigned int coef_idx, unsigned int coef_bit)
984{
985 struct alc_spec *spec = codec->spec;
986 spec->pll_nid = nid;
987 spec->pll_coef_idx = coef_idx;
988 spec->pll_coef_bit = coef_bit;
989 alc_fix_pll(codec);
990}
991
a9fd4f3f 992static void alc_automute_pin(struct hda_codec *codec)
c9b58006
KY
993{
994 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
995 unsigned int nid = spec->autocfg.hp_pins[0];
996 int i;
c9b58006 997
ad87c64f
TI
998 if (!nid)
999 return;
864f92be 1000 spec->jack_present = snd_hda_jack_detect(codec, nid);
a9fd4f3f
TI
1001 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1002 nid = spec->autocfg.speaker_pins[i];
1003 if (!nid)
1004 break;
1005 snd_hda_codec_write(codec, nid, 0,
1006 AC_VERB_SET_PIN_WIDGET_CONTROL,
1007 spec->jack_present ? 0 : PIN_OUT);
1008 }
c9b58006
KY
1009}
1010
6c819492
TI
1011static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1012 hda_nid_t nid)
1013{
1014 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1015 int i, nums;
1016
1017 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1018 for (i = 0; i < nums; i++)
1019 if (conn[i] == nid)
1020 return i;
1021 return -1;
1022}
1023
840b64c0
TI
1024/* switch the current ADC according to the jack state */
1025static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1026{
1027 struct alc_spec *spec = codec->spec;
1028 unsigned int present;
1029 hda_nid_t new_adc;
1030
1031 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1032 if (present)
1033 spec->cur_adc_idx = 1;
1034 else
1035 spec->cur_adc_idx = 0;
1036 new_adc = spec->adc_nids[spec->cur_adc_idx];
1037 if (spec->cur_adc && spec->cur_adc != new_adc) {
1038 /* stream is running, let's swap the current ADC */
1039 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
1040 spec->cur_adc = new_adc;
1041 snd_hda_codec_setup_stream(codec, new_adc,
1042 spec->cur_adc_stream_tag, 0,
1043 spec->cur_adc_format);
1044 }
1045}
1046
7fb0d78f
KY
1047static void alc_mic_automute(struct hda_codec *codec)
1048{
1049 struct alc_spec *spec = codec->spec;
6c819492
TI
1050 struct alc_mic_route *dead, *alive;
1051 unsigned int present, type;
1052 hda_nid_t cap_nid;
1053
b59bdf3b
TI
1054 if (!spec->auto_mic)
1055 return;
6c819492
TI
1056 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1057 return;
1058 if (snd_BUG_ON(!spec->adc_nids))
1059 return;
1060
840b64c0
TI
1061 if (spec->dual_adc_switch) {
1062 alc_dual_mic_adc_auto_switch(codec);
1063 return;
1064 }
1065
6c819492
TI
1066 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1067
864f92be 1068 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1069 if (present) {
1070 alive = &spec->ext_mic;
1071 dead = &spec->int_mic;
1072 } else {
1073 alive = &spec->int_mic;
1074 dead = &spec->ext_mic;
1075 }
1076
6c819492
TI
1077 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1078 if (type == AC_WID_AUD_MIX) {
1079 /* Matrix-mixer style (e.g. ALC882) */
1080 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1081 alive->mux_idx,
1082 HDA_AMP_MUTE, 0);
1083 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1084 dead->mux_idx,
1085 HDA_AMP_MUTE, HDA_AMP_MUTE);
1086 } else {
1087 /* MUX style (e.g. ALC880) */
1088 snd_hda_codec_write_cache(codec, cap_nid, 0,
1089 AC_VERB_SET_CONNECT_SEL,
1090 alive->mux_idx);
1091 }
1092
1093 /* FIXME: analog mixer */
7fb0d78f
KY
1094}
1095
c9b58006
KY
1096/* unsolicited event for HP jack sensing */
1097static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1098{
1099 if (codec->vendor_id == 0x10ec0880)
1100 res >>= 28;
1101 else
1102 res >>= 26;
a9fd4f3f
TI
1103 switch (res) {
1104 case ALC880_HP_EVENT:
1105 alc_automute_pin(codec);
1106 break;
1107 case ALC880_MIC_EVENT:
7fb0d78f 1108 alc_mic_automute(codec);
a9fd4f3f
TI
1109 break;
1110 }
7fb0d78f
KY
1111}
1112
1113static void alc_inithook(struct hda_codec *codec)
1114{
a9fd4f3f 1115 alc_automute_pin(codec);
7fb0d78f 1116 alc_mic_automute(codec);
c9b58006
KY
1117}
1118
f9423e7a
KY
1119/* additional initialization for ALC888 variants */
1120static void alc888_coef_init(struct hda_codec *codec)
1121{
1122 unsigned int tmp;
1123
1124 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1125 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1126 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1127 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1128 /* alc888S-VC */
1129 snd_hda_codec_read(codec, 0x20, 0,
1130 AC_VERB_SET_PROC_COEF, 0x830);
1131 else
1132 /* alc888-VB */
1133 snd_hda_codec_read(codec, 0x20, 0,
1134 AC_VERB_SET_PROC_COEF, 0x3030);
1135}
1136
87a8c370
JK
1137static void alc889_coef_init(struct hda_codec *codec)
1138{
1139 unsigned int tmp;
1140
1141 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1142 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1143 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1144 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1145}
1146
3fb4a508
TI
1147/* turn on/off EAPD control (only if available) */
1148static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1149{
1150 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1151 return;
1152 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1153 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1154 on ? 2 : 0);
1155}
1156
4a79ba34 1157static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1158{
4a79ba34 1159 unsigned int tmp;
bc9f98a9 1160
4a79ba34
TI
1161 switch (type) {
1162 case ALC_INIT_GPIO1:
bc9f98a9
KY
1163 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1164 break;
4a79ba34 1165 case ALC_INIT_GPIO2:
bc9f98a9
KY
1166 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1167 break;
4a79ba34 1168 case ALC_INIT_GPIO3:
bdd148a3
KY
1169 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1170 break;
4a79ba34 1171 case ALC_INIT_DEFAULT:
bdd148a3 1172 switch (codec->vendor_id) {
c9b58006 1173 case 0x10ec0260:
3fb4a508
TI
1174 set_eapd(codec, 0x0f, 1);
1175 set_eapd(codec, 0x10, 1);
c9b58006
KY
1176 break;
1177 case 0x10ec0262:
bdd148a3
KY
1178 case 0x10ec0267:
1179 case 0x10ec0268:
c9b58006 1180 case 0x10ec0269:
3fb4a508 1181 case 0x10ec0270:
c6e8f2da 1182 case 0x10ec0272:
f9423e7a
KY
1183 case 0x10ec0660:
1184 case 0x10ec0662:
1185 case 0x10ec0663:
c9b58006 1186 case 0x10ec0862:
20a3a05d 1187 case 0x10ec0889:
3fb4a508
TI
1188 set_eapd(codec, 0x14, 1);
1189 set_eapd(codec, 0x15, 1);
c9b58006 1190 break;
bdd148a3 1191 }
c9b58006
KY
1192 switch (codec->vendor_id) {
1193 case 0x10ec0260:
1194 snd_hda_codec_write(codec, 0x1a, 0,
1195 AC_VERB_SET_COEF_INDEX, 7);
1196 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1197 AC_VERB_GET_PROC_COEF, 0);
1198 snd_hda_codec_write(codec, 0x1a, 0,
1199 AC_VERB_SET_COEF_INDEX, 7);
1200 snd_hda_codec_write(codec, 0x1a, 0,
1201 AC_VERB_SET_PROC_COEF,
1202 tmp | 0x2010);
1203 break;
1204 case 0x10ec0262:
1205 case 0x10ec0880:
1206 case 0x10ec0882:
1207 case 0x10ec0883:
1208 case 0x10ec0885:
4a5a4c56 1209 case 0x10ec0887:
20a3a05d 1210 case 0x10ec0889:
87a8c370 1211 alc889_coef_init(codec);
c9b58006 1212 break;
f9423e7a 1213 case 0x10ec0888:
4a79ba34 1214 alc888_coef_init(codec);
f9423e7a 1215 break;
0aea778e 1216#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1217 case 0x10ec0267:
1218 case 0x10ec0268:
1219 snd_hda_codec_write(codec, 0x20, 0,
1220 AC_VERB_SET_COEF_INDEX, 7);
1221 tmp = snd_hda_codec_read(codec, 0x20, 0,
1222 AC_VERB_GET_PROC_COEF, 0);
1223 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1224 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1225 snd_hda_codec_write(codec, 0x20, 0,
1226 AC_VERB_SET_PROC_COEF,
1227 tmp | 0x3000);
1228 break;
0aea778e 1229#endif /* XXX */
bc9f98a9 1230 }
4a79ba34
TI
1231 break;
1232 }
1233}
1234
1235static void alc_init_auto_hp(struct hda_codec *codec)
1236{
1237 struct alc_spec *spec = codec->spec;
1238
1239 if (!spec->autocfg.hp_pins[0])
1240 return;
1241
1242 if (!spec->autocfg.speaker_pins[0]) {
2a2ed0df
TI
1243 if (spec->autocfg.line_out_pins[0] &&
1244 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
4a79ba34
TI
1245 spec->autocfg.speaker_pins[0] =
1246 spec->autocfg.line_out_pins[0];
1247 else
1248 return;
1249 }
1250
2a2ed0df
TI
1251 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1252 spec->autocfg.hp_pins[0]);
4a79ba34
TI
1253 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1254 AC_VERB_SET_UNSOLICITED_ENABLE,
1255 AC_USRSP_EN | ALC880_HP_EVENT);
1256 spec->unsol_event = alc_sku_unsol_event;
1257}
1258
6c819492
TI
1259static void alc_init_auto_mic(struct hda_codec *codec)
1260{
1261 struct alc_spec *spec = codec->spec;
1262 struct auto_pin_cfg *cfg = &spec->autocfg;
1263 hda_nid_t fixed, ext;
1264 int i;
1265
1266 /* there must be only two mic inputs exclusively */
1267 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++)
1268 if (cfg->input_pins[i])
1269 return;
1270
1271 fixed = ext = 0;
1272 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) {
1273 hda_nid_t nid = cfg->input_pins[i];
1274 unsigned int defcfg;
1275 if (!nid)
1276 return;
1277 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1278 switch (get_defcfg_connect(defcfg)) {
1279 case AC_JACK_PORT_FIXED:
1280 if (fixed)
1281 return; /* already occupied */
1282 fixed = nid;
1283 break;
1284 case AC_JACK_PORT_COMPLEX:
1285 if (ext)
1286 return; /* already occupied */
1287 ext = nid;
1288 break;
1289 default:
1290 return; /* invalid entry */
1291 }
1292 }
eaa9b3a7
TI
1293 if (!ext || !fixed)
1294 return;
6c819492
TI
1295 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1296 return; /* no unsol support */
1297 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1298 ext, fixed);
1299 spec->ext_mic.pin = ext;
1300 spec->int_mic.pin = fixed;
1301 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1302 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1303 spec->auto_mic = 1;
1304 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1305 AC_VERB_SET_UNSOLICITED_ENABLE,
1306 AC_USRSP_EN | ALC880_MIC_EVENT);
1307 spec->unsol_event = alc_sku_unsol_event;
1308}
1309
da00c244
KY
1310static int alc_auto_parse_customize_define(struct hda_codec *codec)
1311{
1312 unsigned int ass, tmp, i;
7fb56223 1313 unsigned nid = 0;
da00c244
KY
1314 struct alc_spec *spec = codec->spec;
1315
b6cbe517
TI
1316 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1317
da00c244 1318 ass = codec->subsystem_id & 0xffff;
b6cbe517 1319 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1320 goto do_sku;
1321
1322 nid = 0x1d;
1323 if (codec->vendor_id == 0x10ec0260)
1324 nid = 0x17;
1325 ass = snd_hda_codec_get_pincfg(codec, nid);
1326
1327 if (!(ass & 1)) {
1328 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1329 codec->chip_name, ass);
1330 return -1;
1331 }
1332
1333 /* check sum */
1334 tmp = 0;
1335 for (i = 1; i < 16; i++) {
1336 if ((ass >> i) & 1)
1337 tmp++;
1338 }
1339 if (((ass >> 16) & 0xf) != tmp)
1340 return -1;
1341
1342 spec->cdefine.port_connectivity = ass >> 30;
1343 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1344 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1345 spec->cdefine.customization = ass >> 8;
1346do_sku:
1347 spec->cdefine.sku_cfg = ass;
1348 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1349 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1350 spec->cdefine.swap = (ass & 0x2) >> 1;
1351 spec->cdefine.override = ass & 0x1;
1352
1353 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1354 nid, spec->cdefine.sku_cfg);
1355 snd_printd("SKU: port_connectivity=0x%x\n",
1356 spec->cdefine.port_connectivity);
1357 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1358 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1359 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1360 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1361 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1362 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1363 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1364
1365 return 0;
1366}
1367
4a79ba34
TI
1368/* check subsystem ID and set up device-specific initialization;
1369 * return 1 if initialized, 0 if invalid SSID
1370 */
1371/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1372 * 31 ~ 16 : Manufacture ID
1373 * 15 ~ 8 : SKU ID
1374 * 7 ~ 0 : Assembly ID
1375 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1376 */
1377static int alc_subsystem_id(struct hda_codec *codec,
1378 hda_nid_t porta, hda_nid_t porte,
6227cdce 1379 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1380{
1381 unsigned int ass, tmp, i;
1382 unsigned nid;
1383 struct alc_spec *spec = codec->spec;
1384
1385 ass = codec->subsystem_id & 0xffff;
1386 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1387 goto do_sku;
1388
1389 /* invalid SSID, check the special NID pin defcfg instead */
1390 /*
def319f9 1391 * 31~30 : port connectivity
4a79ba34
TI
1392 * 29~21 : reserve
1393 * 20 : PCBEEP input
1394 * 19~16 : Check sum (15:1)
1395 * 15~1 : Custom
1396 * 0 : override
1397 */
1398 nid = 0x1d;
1399 if (codec->vendor_id == 0x10ec0260)
1400 nid = 0x17;
1401 ass = snd_hda_codec_get_pincfg(codec, nid);
1402 snd_printd("realtek: No valid SSID, "
1403 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1404 ass, nid);
6227cdce 1405 if (!(ass & 1))
4a79ba34
TI
1406 return 0;
1407 if ((ass >> 30) != 1) /* no physical connection */
1408 return 0;
1409
1410 /* check sum */
1411 tmp = 0;
1412 for (i = 1; i < 16; i++) {
1413 if ((ass >> i) & 1)
1414 tmp++;
1415 }
1416 if (((ass >> 16) & 0xf) != tmp)
1417 return 0;
1418do_sku:
1419 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1420 ass & 0xffff, codec->vendor_id);
1421 /*
1422 * 0 : override
1423 * 1 : Swap Jack
1424 * 2 : 0 --> Desktop, 1 --> Laptop
1425 * 3~5 : External Amplifier control
1426 * 7~6 : Reserved
1427 */
1428 tmp = (ass & 0x38) >> 3; /* external Amp control */
1429 switch (tmp) {
1430 case 1:
1431 spec->init_amp = ALC_INIT_GPIO1;
1432 break;
1433 case 3:
1434 spec->init_amp = ALC_INIT_GPIO2;
1435 break;
1436 case 7:
1437 spec->init_amp = ALC_INIT_GPIO3;
1438 break;
1439 case 5:
1440 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1441 break;
1442 }
ea1fb29a 1443
8c427226 1444 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1445 * when the external headphone out jack is plugged"
1446 */
8c427226 1447 if (!(ass & 0x8000))
4a79ba34 1448 return 1;
c9b58006
KY
1449 /*
1450 * 10~8 : Jack location
1451 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1452 * 14~13: Resvered
1453 * 15 : 1 --> enable the function "Mute internal speaker
1454 * when the external headphone out jack is plugged"
1455 */
c9b58006 1456 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1457 hda_nid_t nid;
c9b58006
KY
1458 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1459 if (tmp == 0)
01d4825d 1460 nid = porta;
c9b58006 1461 else if (tmp == 1)
01d4825d 1462 nid = porte;
c9b58006 1463 else if (tmp == 2)
01d4825d 1464 nid = portd;
6227cdce
KY
1465 else if (tmp == 3)
1466 nid = porti;
c9b58006 1467 else
4a79ba34 1468 return 1;
01d4825d
TI
1469 for (i = 0; i < spec->autocfg.line_outs; i++)
1470 if (spec->autocfg.line_out_pins[i] == nid)
1471 return 1;
1472 spec->autocfg.hp_pins[0] = nid;
c9b58006
KY
1473 }
1474
4a79ba34 1475 alc_init_auto_hp(codec);
6c819492 1476 alc_init_auto_mic(codec);
4a79ba34
TI
1477 return 1;
1478}
ea1fb29a 1479
4a79ba34 1480static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1481 hda_nid_t porta, hda_nid_t porte,
1482 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1483{
6227cdce 1484 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1485 struct alc_spec *spec = codec->spec;
1486 snd_printd("realtek: "
1487 "Enable default setup for auto mode as fallback\n");
1488 spec->init_amp = ALC_INIT_DEFAULT;
1489 alc_init_auto_hp(codec);
6c819492 1490 alc_init_auto_mic(codec);
4a79ba34 1491 }
bc9f98a9
KY
1492}
1493
f95474ec 1494/*
f8f25ba3 1495 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1496 */
1497
1498struct alc_pincfg {
1499 hda_nid_t nid;
1500 u32 val;
1501};
1502
f8f25ba3
TI
1503struct alc_fixup {
1504 const struct alc_pincfg *pins;
1505 const struct hda_verb *verbs;
1506};
1507
1508static void alc_pick_fixup(struct hda_codec *codec,
f95474ec 1509 const struct snd_pci_quirk *quirk,
7fa90e87
TI
1510 const struct alc_fixup *fix,
1511 int pre_init)
f95474ec
TI
1512{
1513 const struct alc_pincfg *cfg;
1514
1515 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1516 if (!quirk)
1517 return;
f8f25ba3
TI
1518 fix += quirk->value;
1519 cfg = fix->pins;
7fa90e87
TI
1520 if (pre_init && cfg) {
1521#ifdef CONFIG_SND_DEBUG_VERBOSE
1522 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
1523 codec->chip_name, quirk->name);
1524#endif
f8f25ba3
TI
1525 for (; cfg->nid; cfg++)
1526 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1527 }
7fa90e87
TI
1528 if (!pre_init && fix->verbs) {
1529#ifdef CONFIG_SND_DEBUG_VERBOSE
1530 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
1531 codec->chip_name, quirk->name);
1532#endif
f8f25ba3 1533 add_verb(codec->spec, fix->verbs);
7fa90e87 1534 }
f95474ec
TI
1535}
1536
274693f3
KY
1537static int alc_read_coef_idx(struct hda_codec *codec,
1538 unsigned int coef_idx)
1539{
1540 unsigned int val;
1541 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1542 coef_idx);
1543 val = snd_hda_codec_read(codec, 0x20, 0,
1544 AC_VERB_GET_PROC_COEF, 0);
1545 return val;
1546}
1547
757899ac
TI
1548/* set right pin controls for digital I/O */
1549static void alc_auto_init_digital(struct hda_codec *codec)
1550{
1551 struct alc_spec *spec = codec->spec;
1552 int i;
1553 hda_nid_t pin;
1554
1555 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1556 pin = spec->autocfg.dig_out_pins[i];
1557 if (pin) {
1558 snd_hda_codec_write(codec, pin, 0,
1559 AC_VERB_SET_PIN_WIDGET_CONTROL,
1560 PIN_OUT);
1561 }
1562 }
1563 pin = spec->autocfg.dig_in_pin;
1564 if (pin)
1565 snd_hda_codec_write(codec, pin, 0,
1566 AC_VERB_SET_PIN_WIDGET_CONTROL,
1567 PIN_IN);
1568}
1569
1570/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1571static void alc_auto_parse_digital(struct hda_codec *codec)
1572{
1573 struct alc_spec *spec = codec->spec;
1574 int i, err;
1575 hda_nid_t dig_nid;
1576
1577 /* support multiple SPDIFs; the secondary is set up as a slave */
1578 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1579 err = snd_hda_get_connections(codec,
1580 spec->autocfg.dig_out_pins[i],
1581 &dig_nid, 1);
1582 if (err < 0)
1583 continue;
1584 if (!i) {
1585 spec->multiout.dig_out_nid = dig_nid;
1586 spec->dig_out_type = spec->autocfg.dig_out_type[0];
1587 } else {
1588 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1589 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1590 break;
1591 spec->slave_dig_outs[i - 1] = dig_nid;
1592 }
1593 }
1594
1595 if (spec->autocfg.dig_in_pin) {
1596 hda_nid_t dig_nid;
1597 err = snd_hda_get_connections(codec,
1598 spec->autocfg.dig_in_pin,
1599 &dig_nid, 1);
1600 if (err > 0)
1601 spec->dig_in_nid = dig_nid;
1602 }
1603}
1604
ef8ef5fb
VP
1605/*
1606 * ALC888
1607 */
1608
1609/*
1610 * 2ch mode
1611 */
1612static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1613/* Mic-in jack as mic in */
1614 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1615 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1616/* Line-in jack as Line in */
1617 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1618 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1619/* Line-Out as Front */
1620 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1621 { } /* end */
1622};
1623
1624/*
1625 * 4ch mode
1626 */
1627static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1628/* Mic-in jack as mic in */
1629 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1630 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1631/* Line-in jack as Surround */
1632 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1633 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1634/* Line-Out as Front */
1635 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1636 { } /* end */
1637};
1638
1639/*
1640 * 6ch mode
1641 */
1642static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1643/* Mic-in jack as CLFE */
1644 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1645 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1646/* Line-in jack as Surround */
1647 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1648 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1649/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1650 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1651 { } /* end */
1652};
1653
1654/*
1655 * 8ch mode
1656 */
1657static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1658/* Mic-in jack as CLFE */
1659 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1660 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1661/* Line-in jack as Surround */
1662 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1663 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1664/* Line-Out as Side */
1665 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1666 { } /* end */
1667};
1668
1669static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1670 { 2, alc888_4ST_ch2_intel_init },
1671 { 4, alc888_4ST_ch4_intel_init },
1672 { 6, alc888_4ST_ch6_intel_init },
1673 { 8, alc888_4ST_ch8_intel_init },
1674};
1675
1676/*
1677 * ALC888 Fujitsu Siemens Amillo xa3530
1678 */
1679
1680static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1681/* Front Mic: set to PIN_IN (empty by default) */
1682 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1683/* Connect Internal HP to Front */
1684 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1685 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1686 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1687/* Connect Bass HP to Front */
1688 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1689 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1690 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1691/* Connect Line-Out side jack (SPDIF) to Side */
1692 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1693 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1694 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1695/* Connect Mic jack to CLFE */
1696 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1697 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1698 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1699/* Connect Line-in jack to Surround */
1700 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1701 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1702 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1703/* Connect HP out jack to Front */
1704 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1705 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1706 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1707/* Enable unsolicited event for HP jack and Line-out jack */
1708 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1709 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1710 {}
1711};
1712
a9fd4f3f 1713static void alc_automute_amp(struct hda_codec *codec)
ef8ef5fb 1714{
a9fd4f3f 1715 struct alc_spec *spec = codec->spec;
864f92be 1716 unsigned int mute;
a9fd4f3f
TI
1717 hda_nid_t nid;
1718 int i;
1719
1720 spec->jack_present = 0;
1721 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1722 nid = spec->autocfg.hp_pins[i];
1723 if (!nid)
1724 break;
864f92be 1725 if (snd_hda_jack_detect(codec, nid)) {
a9fd4f3f
TI
1726 spec->jack_present = 1;
1727 break;
1728 }
1729 }
1730
1731 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
ef8ef5fb 1732 /* Toggle internal speakers muting */
a9fd4f3f
TI
1733 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1734 nid = spec->autocfg.speaker_pins[i];
1735 if (!nid)
1736 break;
1737 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1738 HDA_AMP_MUTE, mute);
1739 }
ef8ef5fb
VP
1740}
1741
a9fd4f3f
TI
1742static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1743 unsigned int res)
ef8ef5fb 1744{
a9fd4f3f
TI
1745 if (codec->vendor_id == 0x10ec0880)
1746 res >>= 28;
1747 else
1748 res >>= 26;
1749 if (res == ALC880_HP_EVENT)
1750 alc_automute_amp(codec);
ef8ef5fb
VP
1751}
1752
4f5d1706 1753static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
1754{
1755 struct alc_spec *spec = codec->spec;
1756
1757 spec->autocfg.hp_pins[0] = 0x15;
1758 spec->autocfg.speaker_pins[0] = 0x14;
1759 spec->autocfg.speaker_pins[1] = 0x16;
1760 spec->autocfg.speaker_pins[2] = 0x17;
1761 spec->autocfg.speaker_pins[3] = 0x19;
1762 spec->autocfg.speaker_pins[4] = 0x1a;
6732bd0d
WF
1763}
1764
1765static void alc889_intel_init_hook(struct hda_codec *codec)
1766{
1767 alc889_coef_init(codec);
4f5d1706 1768 alc_automute_amp(codec);
6732bd0d
WF
1769}
1770
4f5d1706 1771static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
1772{
1773 struct alc_spec *spec = codec->spec;
1774
1775 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1776 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1777 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1778 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
a9fd4f3f 1779}
ef8ef5fb 1780
5b2d1eca
VP
1781/*
1782 * ALC888 Acer Aspire 4930G model
1783 */
1784
1785static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1786/* Front Mic: set to PIN_IN (empty by default) */
1787 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1788/* Unselect Front Mic by default in input mixer 3 */
1789 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 1790/* Enable unsolicited event for HP jack */
5b2d1eca
VP
1791 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1792/* Connect Internal HP to front */
1793 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1794 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1795 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1796/* Connect HP out to front */
1797 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1798 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1799 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1800 { }
1801};
1802
d2fd4b09
TV
1803/*
1804 * ALC888 Acer Aspire 6530G model
1805 */
1806
1807static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
1808/* Route to built-in subwoofer as well as speakers */
1809 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1810 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1811 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1812 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
1813/* Bias voltage on for external mic port */
1814 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
1815/* Front Mic: set to PIN_IN (empty by default) */
1816 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1817/* Unselect Front Mic by default in input mixer 3 */
1818 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
1819/* Enable unsolicited event for HP jack */
1820 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1821/* Enable speaker output */
1822 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1823 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 1824 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
1825/* Enable headphone output */
1826 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1827 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1828 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 1829 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
1830 { }
1831};
1832
3b315d70 1833/*
018df418 1834 * ALC889 Acer Aspire 8930G model
3b315d70
HM
1835 */
1836
018df418 1837static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
1838/* Front Mic: set to PIN_IN (empty by default) */
1839 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1840/* Unselect Front Mic by default in input mixer 3 */
1841 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1842/* Enable unsolicited event for HP jack */
1843 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1844/* Connect Internal Front to Front */
1845 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1846 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1847 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1848/* Connect Internal Rear to Rear */
1849 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1850 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1851 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1852/* Connect Internal CLFE to CLFE */
1853 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1854 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1855 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1856/* Connect HP out to Front */
018df418 1857 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
1858 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1859 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1860/* Enable all DACs */
1861/* DAC DISABLE/MUTE 1? */
1862/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1863 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1864 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1865/* DAC DISABLE/MUTE 2? */
1866/* some bit here disables the other DACs. Init=0x4900 */
1867 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1868 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
1869/* DMIC fix
1870 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1871 * which makes the stereo useless. However, either the mic or the ALC889
1872 * makes the signal become a difference/sum signal instead of standard
1873 * stereo, which is annoying. So instead we flip this bit which makes the
1874 * codec replicate the sum signal to both channels, turning it into a
1875 * normal mono mic.
1876 */
1877/* DMIC_CONTROL? Init value = 0x0001 */
1878 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1879 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
1880 { }
1881};
1882
ef8ef5fb 1883static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
1884 /* Front mic only available on one ADC */
1885 {
1886 .num_items = 4,
1887 .items = {
1888 { "Mic", 0x0 },
1889 { "Line", 0x2 },
1890 { "CD", 0x4 },
1891 { "Front Mic", 0xb },
1892 },
1893 },
1894 {
1895 .num_items = 3,
1896 .items = {
1897 { "Mic", 0x0 },
1898 { "Line", 0x2 },
1899 { "CD", 0x4 },
1900 },
1901 }
1902};
1903
d2fd4b09
TV
1904static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1905 /* Interal mic only available on one ADC */
1906 {
684a8842 1907 .num_items = 5,
d2fd4b09
TV
1908 .items = {
1909 { "Ext Mic", 0x0 },
684a8842 1910 { "Line In", 0x2 },
d2fd4b09 1911 { "CD", 0x4 },
684a8842 1912 { "Input Mix", 0xa },
d2fd4b09
TV
1913 { "Int Mic", 0xb },
1914 },
1915 },
1916 {
684a8842 1917 .num_items = 4,
d2fd4b09
TV
1918 .items = {
1919 { "Ext Mic", 0x0 },
684a8842 1920 { "Line In", 0x2 },
d2fd4b09 1921 { "CD", 0x4 },
684a8842 1922 { "Input Mix", 0xa },
d2fd4b09
TV
1923 },
1924 }
1925};
1926
018df418
HM
1927static struct hda_input_mux alc889_capture_sources[3] = {
1928 /* Digital mic only available on first "ADC" */
1929 {
1930 .num_items = 5,
1931 .items = {
1932 { "Mic", 0x0 },
1933 { "Line", 0x2 },
1934 { "CD", 0x4 },
1935 { "Front Mic", 0xb },
1936 { "Input Mix", 0xa },
1937 },
1938 },
1939 {
1940 .num_items = 4,
1941 .items = {
1942 { "Mic", 0x0 },
1943 { "Line", 0x2 },
1944 { "CD", 0x4 },
1945 { "Input Mix", 0xa },
1946 },
1947 },
1948 {
1949 .num_items = 4,
1950 .items = {
1951 { "Mic", 0x0 },
1952 { "Line", 0x2 },
1953 { "CD", 0x4 },
1954 { "Input Mix", 0xa },
1955 },
1956 }
1957};
1958
ef8ef5fb 1959static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
1960 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1961 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1962 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1963 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1964 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1965 HDA_OUTPUT),
1966 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1967 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1968 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1969 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1970 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1971 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1972 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1973 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1974 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1975 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1976 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1977 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
1978 { } /* end */
1979};
1980
556eea9a
HM
1981static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
1982 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1983 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1984 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1985 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1986 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1987 HDA_OUTPUT),
1988 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1989 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1990 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1991 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1992 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1993 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1994 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1995 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1996 { } /* end */
1997};
1998
1999
4f5d1706 2000static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2001{
a9fd4f3f 2002 struct alc_spec *spec = codec->spec;
5b2d1eca 2003
a9fd4f3f
TI
2004 spec->autocfg.hp_pins[0] = 0x15;
2005 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2006 spec->autocfg.speaker_pins[1] = 0x16;
2007 spec->autocfg.speaker_pins[2] = 0x17;
5b2d1eca
VP
2008}
2009
4f5d1706 2010static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2011{
2012 struct alc_spec *spec = codec->spec;
2013
2014 spec->autocfg.hp_pins[0] = 0x15;
2015 spec->autocfg.speaker_pins[0] = 0x14;
2016 spec->autocfg.speaker_pins[1] = 0x16;
2017 spec->autocfg.speaker_pins[2] = 0x17;
320d5920
EL
2018}
2019
4f5d1706 2020static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2021{
2022 struct alc_spec *spec = codec->spec;
2023
2024 spec->autocfg.hp_pins[0] = 0x15;
2025 spec->autocfg.speaker_pins[0] = 0x14;
2026 spec->autocfg.speaker_pins[1] = 0x16;
2027 spec->autocfg.speaker_pins[2] = 0x1b;
3b315d70
HM
2028}
2029
1da177e4 2030/*
e9edcee0
TI
2031 * ALC880 3-stack model
2032 *
2033 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2034 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2035 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2036 */
2037
e9edcee0
TI
2038static hda_nid_t alc880_dac_nids[4] = {
2039 /* front, rear, clfe, rear_surr */
2040 0x02, 0x05, 0x04, 0x03
2041};
2042
2043static hda_nid_t alc880_adc_nids[3] = {
2044 /* ADC0-2 */
2045 0x07, 0x08, 0x09,
2046};
2047
2048/* The datasheet says the node 0x07 is connected from inputs,
2049 * but it shows zero connection in the real implementation on some devices.
df694daa 2050 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2051 */
e9edcee0
TI
2052static hda_nid_t alc880_adc_nids_alt[2] = {
2053 /* ADC1-2 */
2054 0x08, 0x09,
2055};
2056
2057#define ALC880_DIGOUT_NID 0x06
2058#define ALC880_DIGIN_NID 0x0a
2059
2060static struct hda_input_mux alc880_capture_source = {
2061 .num_items = 4,
2062 .items = {
2063 { "Mic", 0x0 },
2064 { "Front Mic", 0x3 },
2065 { "Line", 0x2 },
2066 { "CD", 0x4 },
2067 },
2068};
2069
2070/* channel source setting (2/6 channel selection for 3-stack) */
2071/* 2ch mode */
2072static struct hda_verb alc880_threestack_ch2_init[] = {
2073 /* set line-in to input, mute it */
2074 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2075 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2076 /* set mic-in to input vref 80%, mute it */
2077 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2078 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2079 { } /* end */
2080};
2081
2082/* 6ch mode */
2083static struct hda_verb alc880_threestack_ch6_init[] = {
2084 /* set line-in to output, unmute it */
2085 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2086 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2087 /* set mic-in to output, unmute it */
2088 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2089 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2090 { } /* end */
2091};
2092
d2a6d7dc 2093static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2094 { 2, alc880_threestack_ch2_init },
2095 { 6, alc880_threestack_ch6_init },
2096};
2097
c8b6bf9b 2098static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2099 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2100 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2101 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2102 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2103 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2104 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2105 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2106 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2107 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2108 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2109 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2110 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2111 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2112 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2113 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2114 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2115 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2116 {
2117 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2118 .name = "Channel Mode",
df694daa
KY
2119 .info = alc_ch_mode_info,
2120 .get = alc_ch_mode_get,
2121 .put = alc_ch_mode_put,
e9edcee0
TI
2122 },
2123 { } /* end */
2124};
2125
2126/* capture mixer elements */
f9e336f6
TI
2127static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2128 struct snd_ctl_elem_info *uinfo)
2129{
2130 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2131 struct alc_spec *spec = codec->spec;
2132 int err;
1da177e4 2133
5a9e02e9 2134 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2135 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2136 HDA_INPUT);
2137 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2138 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2139 return err;
2140}
2141
2142static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2143 unsigned int size, unsigned int __user *tlv)
2144{
2145 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2146 struct alc_spec *spec = codec->spec;
2147 int err;
1da177e4 2148
5a9e02e9 2149 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2150 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2151 HDA_INPUT);
2152 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2153 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2154 return err;
2155}
2156
2157typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2158 struct snd_ctl_elem_value *ucontrol);
2159
2160static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2161 struct snd_ctl_elem_value *ucontrol,
2162 getput_call_t func)
2163{
2164 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2165 struct alc_spec *spec = codec->spec;
2166 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2167 int err;
2168
5a9e02e9 2169 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2170 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2171 3, 0, HDA_INPUT);
2172 err = func(kcontrol, ucontrol);
5a9e02e9 2173 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2174 return err;
2175}
2176
2177static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2178 struct snd_ctl_elem_value *ucontrol)
2179{
2180 return alc_cap_getput_caller(kcontrol, ucontrol,
2181 snd_hda_mixer_amp_volume_get);
2182}
2183
2184static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2185 struct snd_ctl_elem_value *ucontrol)
2186{
2187 return alc_cap_getput_caller(kcontrol, ucontrol,
2188 snd_hda_mixer_amp_volume_put);
2189}
2190
2191/* capture mixer elements */
2192#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2193
2194static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2195 struct snd_ctl_elem_value *ucontrol)
2196{
2197 return alc_cap_getput_caller(kcontrol, ucontrol,
2198 snd_hda_mixer_amp_switch_get);
2199}
2200
2201static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2202 struct snd_ctl_elem_value *ucontrol)
2203{
2204 return alc_cap_getput_caller(kcontrol, ucontrol,
2205 snd_hda_mixer_amp_switch_put);
2206}
2207
a23b688f 2208#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2209 { \
2210 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2211 .name = "Capture Switch", \
2212 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2213 .count = num, \
2214 .info = alc_cap_sw_info, \
2215 .get = alc_cap_sw_get, \
2216 .put = alc_cap_sw_put, \
2217 }, \
2218 { \
2219 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2220 .name = "Capture Volume", \
2221 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2222 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2223 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2224 .count = num, \
2225 .info = alc_cap_vol_info, \
2226 .get = alc_cap_vol_get, \
2227 .put = alc_cap_vol_put, \
2228 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2229 }
2230
2231#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2232 { \
2233 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2234 /* .name = "Capture Source", */ \
2235 .name = "Input Source", \
2236 .count = num, \
2237 .info = alc_mux_enum_info, \
2238 .get = alc_mux_enum_get, \
2239 .put = alc_mux_enum_put, \
a23b688f
TI
2240 }
2241
2242#define DEFINE_CAPMIX(num) \
2243static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2244 _DEFINE_CAPMIX(num), \
2245 _DEFINE_CAPSRC(num), \
2246 { } /* end */ \
2247}
2248
2249#define DEFINE_CAPMIX_NOSRC(num) \
2250static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2251 _DEFINE_CAPMIX(num), \
2252 { } /* end */ \
f9e336f6
TI
2253}
2254
2255/* up to three ADCs */
2256DEFINE_CAPMIX(1);
2257DEFINE_CAPMIX(2);
2258DEFINE_CAPMIX(3);
a23b688f
TI
2259DEFINE_CAPMIX_NOSRC(1);
2260DEFINE_CAPMIX_NOSRC(2);
2261DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2262
2263/*
2264 * ALC880 5-stack model
2265 *
9c7f852e
TI
2266 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2267 * Side = 0x02 (0xd)
e9edcee0
TI
2268 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2269 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2270 */
2271
2272/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 2273static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2274 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2275 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2276 { } /* end */
2277};
2278
e9edcee0
TI
2279/* channel source setting (6/8 channel selection for 5-stack) */
2280/* 6ch mode */
2281static struct hda_verb alc880_fivestack_ch6_init[] = {
2282 /* set line-in to input, mute it */
2283 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2284 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2285 { } /* end */
2286};
2287
e9edcee0
TI
2288/* 8ch mode */
2289static struct hda_verb alc880_fivestack_ch8_init[] = {
2290 /* set line-in to output, unmute it */
2291 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2292 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2293 { } /* end */
2294};
2295
d2a6d7dc 2296static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2297 { 6, alc880_fivestack_ch6_init },
2298 { 8, alc880_fivestack_ch8_init },
2299};
2300
2301
2302/*
2303 * ALC880 6-stack model
2304 *
9c7f852e
TI
2305 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2306 * Side = 0x05 (0x0f)
e9edcee0
TI
2307 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2308 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2309 */
2310
2311static hda_nid_t alc880_6st_dac_nids[4] = {
2312 /* front, rear, clfe, rear_surr */
2313 0x02, 0x03, 0x04, 0x05
f12ab1e0 2314};
e9edcee0
TI
2315
2316static struct hda_input_mux alc880_6stack_capture_source = {
2317 .num_items = 4,
2318 .items = {
2319 { "Mic", 0x0 },
2320 { "Front Mic", 0x1 },
2321 { "Line", 0x2 },
2322 { "CD", 0x4 },
2323 },
2324};
2325
2326/* fixed 8-channels */
d2a6d7dc 2327static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2328 { 8, NULL },
2329};
2330
c8b6bf9b 2331static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2332 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2333 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2334 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2335 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2336 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2337 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2338 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2339 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2340 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2341 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2342 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2343 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2344 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2345 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2346 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2347 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2348 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2349 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2350 {
2351 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2352 .name = "Channel Mode",
df694daa
KY
2353 .info = alc_ch_mode_info,
2354 .get = alc_ch_mode_get,
2355 .put = alc_ch_mode_put,
16ded525
TI
2356 },
2357 { } /* end */
2358};
2359
e9edcee0
TI
2360
2361/*
2362 * ALC880 W810 model
2363 *
2364 * W810 has rear IO for:
2365 * Front (DAC 02)
2366 * Surround (DAC 03)
2367 * Center/LFE (DAC 04)
2368 * Digital out (06)
2369 *
2370 * The system also has a pair of internal speakers, and a headphone jack.
2371 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2372 *
e9edcee0
TI
2373 * There is a variable resistor to control the speaker or headphone
2374 * volume. This is a hardware-only device without a software API.
2375 *
2376 * Plugging headphones in will disable the internal speakers. This is
2377 * implemented in hardware, not via the driver using jack sense. In
2378 * a similar fashion, plugging into the rear socket marked "front" will
2379 * disable both the speakers and headphones.
2380 *
2381 * For input, there's a microphone jack, and an "audio in" jack.
2382 * These may not do anything useful with this driver yet, because I
2383 * haven't setup any initialization verbs for these yet...
2384 */
2385
2386static hda_nid_t alc880_w810_dac_nids[3] = {
2387 /* front, rear/surround, clfe */
2388 0x02, 0x03, 0x04
16ded525
TI
2389};
2390
e9edcee0 2391/* fixed 6 channels */
d2a6d7dc 2392static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2393 { 6, NULL }
2394};
2395
2396/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 2397static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2398 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2399 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2400 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2401 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2402 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2403 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2404 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2405 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2406 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2407 { } /* end */
2408};
2409
2410
2411/*
2412 * Z710V model
2413 *
2414 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2415 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2416 * Line = 0x1a
e9edcee0
TI
2417 */
2418
2419static hda_nid_t alc880_z71v_dac_nids[1] = {
2420 0x02
2421};
2422#define ALC880_Z71V_HP_DAC 0x03
2423
2424/* fixed 2 channels */
d2a6d7dc 2425static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2426 { 2, NULL }
2427};
2428
c8b6bf9b 2429static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2430 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2431 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2432 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2433 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2434 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2435 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2436 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2437 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2438 { } /* end */
2439};
2440
e9edcee0 2441
e9edcee0
TI
2442/*
2443 * ALC880 F1734 model
2444 *
2445 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2446 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2447 */
2448
2449static hda_nid_t alc880_f1734_dac_nids[1] = {
2450 0x03
2451};
2452#define ALC880_F1734_HP_DAC 0x02
2453
c8b6bf9b 2454static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2455 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2456 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2457 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2458 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2459 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2460 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2461 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2462 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2463 { } /* end */
2464};
2465
937b4160
TI
2466static struct hda_input_mux alc880_f1734_capture_source = {
2467 .num_items = 2,
2468 .items = {
2469 { "Mic", 0x1 },
2470 { "CD", 0x4 },
2471 },
2472};
2473
e9edcee0 2474
e9edcee0
TI
2475/*
2476 * ALC880 ASUS model
2477 *
2478 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2479 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2480 * Mic = 0x18, Line = 0x1a
2481 */
2482
2483#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2484#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2485
c8b6bf9b 2486static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2487 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2488 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2489 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2490 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2491 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2492 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2493 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2494 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2495 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2496 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2497 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2498 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2499 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2500 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2501 {
2502 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2503 .name = "Channel Mode",
df694daa
KY
2504 .info = alc_ch_mode_info,
2505 .get = alc_ch_mode_get,
2506 .put = alc_ch_mode_put,
16ded525
TI
2507 },
2508 { } /* end */
2509};
e9edcee0 2510
e9edcee0
TI
2511/*
2512 * ALC880 ASUS W1V model
2513 *
2514 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2515 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2516 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2517 */
2518
2519/* additional mixers to alc880_asus_mixer */
c8b6bf9b 2520static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
2521 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2522 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2523 { } /* end */
2524};
2525
df694daa
KY
2526/* TCL S700 */
2527static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2528 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2529 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2530 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2531 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2532 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2533 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2534 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2535 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2536 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2537 { } /* end */
2538};
2539
ccc656ce
KY
2540/* Uniwill */
2541static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2542 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2543 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2544 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2545 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2546 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2547 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2548 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2549 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2550 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2551 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2552 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2553 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2554 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2555 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2556 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2557 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2558 {
2559 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2560 .name = "Channel Mode",
2561 .info = alc_ch_mode_info,
2562 .get = alc_ch_mode_get,
2563 .put = alc_ch_mode_put,
2564 },
2565 { } /* end */
2566};
2567
2cf9f0fc
TD
2568static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2569 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2570 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2571 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2572 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2573 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2574 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2575 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2576 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2577 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2578 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2579 { } /* end */
2580};
2581
ccc656ce 2582static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2583 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2584 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2585 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2586 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2587 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2588 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2589 { } /* end */
2590};
2591
2134ea4f
TI
2592/*
2593 * virtual master controls
2594 */
2595
2596/*
2597 * slave controls for virtual master
2598 */
2599static const char *alc_slave_vols[] = {
2600 "Front Playback Volume",
2601 "Surround Playback Volume",
2602 "Center Playback Volume",
2603 "LFE Playback Volume",
2604 "Side Playback Volume",
2605 "Headphone Playback Volume",
2606 "Speaker Playback Volume",
2607 "Mono Playback Volume",
2134ea4f 2608 "Line-Out Playback Volume",
26f5df26 2609 "PCM Playback Volume",
2134ea4f
TI
2610 NULL,
2611};
2612
2613static const char *alc_slave_sws[] = {
2614 "Front Playback Switch",
2615 "Surround Playback Switch",
2616 "Center Playback Switch",
2617 "LFE Playback Switch",
2618 "Side Playback Switch",
2619 "Headphone Playback Switch",
2620 "Speaker Playback Switch",
2621 "Mono Playback Switch",
edb54a55 2622 "IEC958 Playback Switch",
23033b2b
TI
2623 "Line-Out Playback Switch",
2624 "PCM Playback Switch",
2134ea4f
TI
2625 NULL,
2626};
2627
1da177e4 2628/*
e9edcee0 2629 * build control elements
1da177e4 2630 */
603c4019 2631
5b0cb1d8
JK
2632#define NID_MAPPING (-1)
2633
2634#define SUBDEV_SPEAKER_ (0 << 6)
2635#define SUBDEV_HP_ (1 << 6)
2636#define SUBDEV_LINE_ (2 << 6)
2637#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2638#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2639#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2640
603c4019
TI
2641static void alc_free_kctls(struct hda_codec *codec);
2642
67d634c0 2643#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2644/* additional beep mixers; the actual parameters are overwritten at build */
2645static struct snd_kcontrol_new alc_beep_mixer[] = {
2646 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 2647 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
2648 { } /* end */
2649};
67d634c0 2650#endif
45bdd1c1 2651
1da177e4
LT
2652static int alc_build_controls(struct hda_codec *codec)
2653{
2654 struct alc_spec *spec = codec->spec;
2f44f847 2655 struct snd_kcontrol *kctl = NULL;
5b0cb1d8
JK
2656 struct snd_kcontrol_new *knew;
2657 int i, j, err;
2658 unsigned int u;
2659 hda_nid_t nid;
1da177e4
LT
2660
2661 for (i = 0; i < spec->num_mixers; i++) {
2662 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2663 if (err < 0)
2664 return err;
2665 }
f9e336f6
TI
2666 if (spec->cap_mixer) {
2667 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2668 if (err < 0)
2669 return err;
2670 }
1da177e4 2671 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2672 err = snd_hda_create_spdif_out_ctls(codec,
2673 spec->multiout.dig_out_nid);
1da177e4
LT
2674 if (err < 0)
2675 return err;
e64f14f4
TI
2676 if (!spec->no_analog) {
2677 err = snd_hda_create_spdif_share_sw(codec,
2678 &spec->multiout);
2679 if (err < 0)
2680 return err;
2681 spec->multiout.share_spdif = 1;
2682 }
1da177e4
LT
2683 }
2684 if (spec->dig_in_nid) {
2685 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2686 if (err < 0)
2687 return err;
2688 }
2134ea4f 2689
67d634c0 2690#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
2691 /* create beep controls if needed */
2692 if (spec->beep_amp) {
2693 struct snd_kcontrol_new *knew;
2694 for (knew = alc_beep_mixer; knew->name; knew++) {
2695 struct snd_kcontrol *kctl;
2696 kctl = snd_ctl_new1(knew, codec);
2697 if (!kctl)
2698 return -ENOMEM;
2699 kctl->private_value = spec->beep_amp;
5e26dfd0 2700 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
2701 if (err < 0)
2702 return err;
2703 }
2704 }
67d634c0 2705#endif
45bdd1c1 2706
2134ea4f 2707 /* if we have no master control, let's create it */
e64f14f4
TI
2708 if (!spec->no_analog &&
2709 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2710 unsigned int vmaster_tlv[4];
2134ea4f 2711 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2712 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2713 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2714 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2715 if (err < 0)
2716 return err;
2717 }
e64f14f4
TI
2718 if (!spec->no_analog &&
2719 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2720 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2721 NULL, alc_slave_sws);
2722 if (err < 0)
2723 return err;
2724 }
2725
5b0cb1d8 2726 /* assign Capture Source enums to NID */
fbe618f2
TI
2727 if (spec->capsrc_nids || spec->adc_nids) {
2728 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2729 if (!kctl)
2730 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2731 for (i = 0; kctl && i < kctl->count; i++) {
2732 hda_nid_t *nids = spec->capsrc_nids;
2733 if (!nids)
2734 nids = spec->adc_nids;
2735 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
2736 if (err < 0)
2737 return err;
2738 }
5b0cb1d8
JK
2739 }
2740 if (spec->cap_mixer) {
2741 const char *kname = kctl ? kctl->id.name : NULL;
2742 for (knew = spec->cap_mixer; knew->name; knew++) {
2743 if (kname && strcmp(knew->name, kname) == 0)
2744 continue;
2745 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2746 for (i = 0; kctl && i < kctl->count; i++) {
2747 err = snd_hda_add_nid(codec, kctl, i,
2748 spec->adc_nids[i]);
2749 if (err < 0)
2750 return err;
2751 }
2752 }
2753 }
2754
2755 /* other nid->control mapping */
2756 for (i = 0; i < spec->num_mixers; i++) {
2757 for (knew = spec->mixers[i]; knew->name; knew++) {
2758 if (knew->iface != NID_MAPPING)
2759 continue;
2760 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2761 if (kctl == NULL)
2762 continue;
2763 u = knew->subdevice;
2764 for (j = 0; j < 4; j++, u >>= 8) {
2765 nid = u & 0x3f;
2766 if (nid == 0)
2767 continue;
2768 switch (u & 0xc0) {
2769 case SUBDEV_SPEAKER_:
2770 nid = spec->autocfg.speaker_pins[nid];
2771 break;
2772 case SUBDEV_LINE_:
2773 nid = spec->autocfg.line_out_pins[nid];
2774 break;
2775 case SUBDEV_HP_:
2776 nid = spec->autocfg.hp_pins[nid];
2777 break;
2778 default:
2779 continue;
2780 }
2781 err = snd_hda_add_nid(codec, kctl, 0, nid);
2782 if (err < 0)
2783 return err;
2784 }
2785 u = knew->private_value;
2786 for (j = 0; j < 4; j++, u >>= 8) {
2787 nid = u & 0xff;
2788 if (nid == 0)
2789 continue;
2790 err = snd_hda_add_nid(codec, kctl, 0, nid);
2791 if (err < 0)
2792 return err;
2793 }
2794 }
2795 }
bae84e70
TI
2796
2797 alc_free_kctls(codec); /* no longer needed */
2798
1da177e4
LT
2799 return 0;
2800}
2801
e9edcee0 2802
1da177e4
LT
2803/*
2804 * initialize the codec volumes, etc
2805 */
2806
e9edcee0
TI
2807/*
2808 * generic initialization of ADC, input mixers and output mixers
2809 */
2810static struct hda_verb alc880_volume_init_verbs[] = {
2811 /*
2812 * Unmute ADC0-2 and set the default input to mic-in
2813 */
71fe7b82 2814 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2815 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2816 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2817 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2818 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2819 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 2820
e9edcee0
TI
2821 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2822 * mixer widget
9c7f852e
TI
2823 * Note: PASD motherboards uses the Line In 2 as the input for front
2824 * panel mic (mic 2)
1da177e4 2825 */
e9edcee0 2826 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
2827 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2828 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2829 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2830 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2831 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2832 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2833 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 2834
e9edcee0
TI
2835 /*
2836 * Set up output mixers (0x0c - 0x0f)
1da177e4 2837 */
e9edcee0
TI
2838 /* set vol=0 to output mixers */
2839 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2840 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2841 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2842 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2843 /* set up input amps for analog loopback */
2844 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
2845 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2846 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2847 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2848 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2849 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2850 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2851 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2852 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
2853
2854 { }
2855};
2856
e9edcee0
TI
2857/*
2858 * 3-stack pin configuration:
2859 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2860 */
2861static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2862 /*
2863 * preset connection lists of input pins
2864 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2865 */
2866 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2867 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2868 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2869
2870 /*
2871 * Set pin mode and muting
2872 */
2873 /* set front pin widgets 0x14 for output */
05acb863 2874 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2875 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2876 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2877 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2878 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2879 /* Mic2 (as headphone out) for HP output */
2880 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2881 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2882 /* Line In pin widget for input */
05acb863 2883 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
2884 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2885 /* Line2 (as front mic) pin widget for input and vref at 80% */
2886 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2887 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2888 /* CD pin widget for input */
05acb863 2889 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 2890
e9edcee0
TI
2891 { }
2892};
1da177e4 2893
e9edcee0
TI
2894/*
2895 * 5-stack pin configuration:
2896 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2897 * line-in/side = 0x1a, f-mic = 0x1b
2898 */
2899static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2900 /*
2901 * preset connection lists of input pins
2902 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 2903 */
e9edcee0
TI
2904 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2905 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 2906
e9edcee0
TI
2907 /*
2908 * Set pin mode and muting
1da177e4 2909 */
e9edcee0
TI
2910 /* set pin widgets 0x14-0x17 for output */
2911 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2912 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2913 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2914 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2915 /* unmute pins for output (no gain on this amp) */
2916 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2917 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2918 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2919 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2920
2921 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2922 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2923 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2924 /* Mic2 (as headphone out) for HP output */
2925 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2926 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2927 /* Line In pin widget for input */
2928 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2929 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2930 /* Line2 (as front mic) pin widget for input and vref at 80% */
2931 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2932 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2933 /* CD pin widget for input */
2934 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
2935
2936 { }
2937};
2938
e9edcee0
TI
2939/*
2940 * W810 pin configuration:
2941 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2942 */
2943static struct hda_verb alc880_pin_w810_init_verbs[] = {
2944 /* hphone/speaker input selector: front DAC */
2945 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 2946
05acb863 2947 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2948 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2949 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2950 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2951 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2952 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2953
e9edcee0 2954 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 2955 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2956
1da177e4
LT
2957 { }
2958};
2959
e9edcee0
TI
2960/*
2961 * Z71V pin configuration:
2962 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2963 */
2964static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 2965 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2966 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2967 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2968 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 2969
16ded525 2970 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2971 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 2972 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2973 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
2974
2975 { }
2976};
2977
e9edcee0
TI
2978/*
2979 * 6-stack pin configuration:
9c7f852e
TI
2980 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2981 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
2982 */
2983static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2984 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2985
16ded525 2986 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2987 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2988 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2989 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2990 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2991 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2992 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2993 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2994
16ded525 2995 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2996 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2997 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2998 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2999 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3000 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3001 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3002 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3003 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3004
e9edcee0
TI
3005 { }
3006};
3007
ccc656ce
KY
3008/*
3009 * Uniwill pin configuration:
3010 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3011 * line = 0x1a
3012 */
3013static struct hda_verb alc880_uniwill_init_verbs[] = {
3014 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3015
3016 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3017 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3018 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3019 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3020 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3021 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3022 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3023 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3026 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3027 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3028 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3029 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3030
3031 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3032 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3033 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3034 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3035 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3036 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3037 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3038 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3039 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3040
3041 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3042 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3043
3044 { }
3045};
3046
3047/*
3048* Uniwill P53
ea1fb29a 3049* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
3050 */
3051static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3052 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3053
3054 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3055 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3056 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3057 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3058 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3059 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3060 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3061 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3062 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3063 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3064 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3065 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3066
3067 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3068 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3069 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3070 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3071 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3072 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3073
3074 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3075 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3076
3077 { }
3078};
3079
2cf9f0fc
TD
3080static struct hda_verb alc880_beep_init_verbs[] = {
3081 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3082 { }
3083};
3084
458a4fab
TI
3085/* auto-toggle front mic */
3086static void alc880_uniwill_mic_automute(struct hda_codec *codec)
3087{
3088 unsigned int present;
3089 unsigned char bits;
ccc656ce 3090
864f92be 3091 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3092 bits = present ? HDA_AMP_MUTE : 0;
3093 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3094}
3095
4f5d1706 3096static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3097{
a9fd4f3f
TI
3098 struct alc_spec *spec = codec->spec;
3099
3100 spec->autocfg.hp_pins[0] = 0x14;
3101 spec->autocfg.speaker_pins[0] = 0x15;
3102 spec->autocfg.speaker_pins[0] = 0x16;
4f5d1706
TI
3103}
3104
3105static void alc880_uniwill_init_hook(struct hda_codec *codec)
3106{
a9fd4f3f 3107 alc_automute_amp(codec);
458a4fab 3108 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
3109}
3110
3111static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3112 unsigned int res)
3113{
3114 /* Looks like the unsol event is incompatible with the standard
3115 * definition. 4bit tag is placed at 28 bit!
3116 */
458a4fab 3117 switch (res >> 28) {
458a4fab
TI
3118 case ALC880_MIC_EVENT:
3119 alc880_uniwill_mic_automute(codec);
3120 break;
a9fd4f3f
TI
3121 default:
3122 alc_automute_amp_unsol_event(codec, res);
3123 break;
458a4fab 3124 }
ccc656ce
KY
3125}
3126
4f5d1706 3127static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3128{
a9fd4f3f 3129 struct alc_spec *spec = codec->spec;
ccc656ce 3130
a9fd4f3f
TI
3131 spec->autocfg.hp_pins[0] = 0x14;
3132 spec->autocfg.speaker_pins[0] = 0x15;
ccc656ce
KY
3133}
3134
3135static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3136{
3137 unsigned int present;
ea1fb29a 3138
ccc656ce 3139 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3140 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3141 present &= HDA_AMP_VOLMASK;
3142 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3143 HDA_AMP_VOLMASK, present);
3144 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3145 HDA_AMP_VOLMASK, present);
ccc656ce 3146}
47fd830a 3147
ccc656ce
KY
3148static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3149 unsigned int res)
3150{
3151 /* Looks like the unsol event is incompatible with the standard
3152 * definition. 4bit tag is placed at 28 bit!
3153 */
f12ab1e0 3154 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3155 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
3156 else
3157 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
3158}
3159
e9edcee0
TI
3160/*
3161 * F1734 pin configuration:
3162 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3163 */
3164static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3165 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3166 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3167 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3168 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3169 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3170
e9edcee0 3171 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3172 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3173 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3174 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3175
e9edcee0
TI
3176 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3177 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3178 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3179 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3180 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3181 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3182 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3183 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3184 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3185
937b4160
TI
3186 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3187 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3188
dfc0ff62
TI
3189 { }
3190};
3191
e9edcee0
TI
3192/*
3193 * ASUS pin configuration:
3194 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3195 */
3196static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3197 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3198 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3199 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3200 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3201
3202 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3203 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3204 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3205 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3206 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3207 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3208 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3209 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3210
3211 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3212 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3213 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3214 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3215 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3216 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3217 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3218 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3219 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3220
e9edcee0
TI
3221 { }
3222};
16ded525 3223
e9edcee0 3224/* Enable GPIO mask and set output */
bc9f98a9
KY
3225#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3226#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3227#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3228
3229/* Clevo m520g init */
3230static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3231 /* headphone output */
3232 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3233 /* line-out */
3234 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3235 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3236 /* Line-in */
3237 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3238 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3239 /* CD */
3240 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3241 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3242 /* Mic1 (rear panel) */
3243 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3244 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3245 /* Mic2 (front panel) */
3246 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3247 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3248 /* headphone */
3249 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3250 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3251 /* change to EAPD mode */
3252 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3253 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3254
3255 { }
16ded525
TI
3256};
3257
df694daa 3258static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3259 /* change to EAPD mode */
3260 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3261 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3262
df694daa
KY
3263 /* Headphone output */
3264 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3265 /* Front output*/
3266 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3267 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3268
3269 /* Line In pin widget for input */
3270 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3271 /* CD pin widget for input */
3272 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3273 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3274 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3275
3276 /* change to EAPD mode */
3277 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3278 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3279
3280 { }
3281};
16ded525 3282
e9edcee0 3283/*
ae6b813a
TI
3284 * LG m1 express dual
3285 *
3286 * Pin assignment:
3287 * Rear Line-In/Out (blue): 0x14
3288 * Build-in Mic-In: 0x15
3289 * Speaker-out: 0x17
3290 * HP-Out (green): 0x1b
3291 * Mic-In/Out (red): 0x19
3292 * SPDIF-Out: 0x1e
3293 */
3294
3295/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3296static hda_nid_t alc880_lg_dac_nids[3] = {
3297 0x05, 0x02, 0x03
3298};
3299
3300/* seems analog CD is not working */
3301static struct hda_input_mux alc880_lg_capture_source = {
3302 .num_items = 3,
3303 .items = {
3304 { "Mic", 0x1 },
3305 { "Line", 0x5 },
3306 { "Internal Mic", 0x6 },
3307 },
3308};
3309
3310/* 2,4,6 channel modes */
3311static struct hda_verb alc880_lg_ch2_init[] = {
3312 /* set line-in and mic-in to input */
3313 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3314 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3315 { }
3316};
3317
3318static struct hda_verb alc880_lg_ch4_init[] = {
3319 /* set line-in to out and mic-in to input */
3320 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3321 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3322 { }
3323};
3324
3325static struct hda_verb alc880_lg_ch6_init[] = {
3326 /* set line-in and mic-in to output */
3327 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3328 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3329 { }
3330};
3331
3332static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3333 { 2, alc880_lg_ch2_init },
3334 { 4, alc880_lg_ch4_init },
3335 { 6, alc880_lg_ch6_init },
3336};
3337
3338static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3339 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3340 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3341 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3342 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3343 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3344 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3345 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3346 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3347 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3348 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3349 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3350 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3351 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3352 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3353 {
3354 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3355 .name = "Channel Mode",
3356 .info = alc_ch_mode_info,
3357 .get = alc_ch_mode_get,
3358 .put = alc_ch_mode_put,
3359 },
3360 { } /* end */
3361};
3362
3363static struct hda_verb alc880_lg_init_verbs[] = {
3364 /* set capture source to mic-in */
3365 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3366 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3367 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3368 /* mute all amp mixer inputs */
3369 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3370 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3371 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3372 /* line-in to input */
3373 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3374 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3375 /* built-in mic */
3376 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3377 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3378 /* speaker-out */
3379 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3380 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3381 /* mic-in to input */
3382 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3383 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3384 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3385 /* HP-out */
3386 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3387 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3388 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3389 /* jack sense */
a9fd4f3f 3390 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3391 { }
3392};
3393
3394/* toggle speaker-output according to the hp-jack state */
4f5d1706 3395static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3396{
a9fd4f3f 3397 struct alc_spec *spec = codec->spec;
ae6b813a 3398
a9fd4f3f
TI
3399 spec->autocfg.hp_pins[0] = 0x1b;
3400 spec->autocfg.speaker_pins[0] = 0x17;
ae6b813a
TI
3401}
3402
d681518a
TI
3403/*
3404 * LG LW20
3405 *
3406 * Pin assignment:
3407 * Speaker-out: 0x14
3408 * Mic-In: 0x18
e4f41da9
CM
3409 * Built-in Mic-In: 0x19
3410 * Line-In: 0x1b
3411 * HP-Out: 0x1a
d681518a
TI
3412 * SPDIF-Out: 0x1e
3413 */
3414
d681518a 3415static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3416 .num_items = 3,
d681518a
TI
3417 .items = {
3418 { "Mic", 0x0 },
3419 { "Internal Mic", 0x1 },
e4f41da9 3420 { "Line In", 0x2 },
d681518a
TI
3421 },
3422};
3423
0a8c5da3
CM
3424#define alc880_lg_lw_modes alc880_threestack_modes
3425
d681518a 3426static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3427 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3428 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3429 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3430 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3431 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3432 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3433 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3434 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3435 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3436 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3437 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3438 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3439 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3440 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3441 {
3442 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3443 .name = "Channel Mode",
3444 .info = alc_ch_mode_info,
3445 .get = alc_ch_mode_get,
3446 .put = alc_ch_mode_put,
3447 },
d681518a
TI
3448 { } /* end */
3449};
3450
3451static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3452 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3453 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3454 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3455
d681518a
TI
3456 /* set capture source to mic-in */
3457 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3458 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3459 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3460 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3461 /* speaker-out */
3462 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3463 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3464 /* HP-out */
d681518a
TI
3465 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3466 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3467 /* mic-in to input */
3468 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3469 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3470 /* built-in mic */
3471 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3472 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3473 /* jack sense */
a9fd4f3f 3474 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3475 { }
3476};
3477
3478/* toggle speaker-output according to the hp-jack state */
4f5d1706 3479static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3480{
a9fd4f3f 3481 struct alc_spec *spec = codec->spec;
d681518a 3482
a9fd4f3f
TI
3483 spec->autocfg.hp_pins[0] = 0x1b;
3484 spec->autocfg.speaker_pins[0] = 0x14;
d681518a
TI
3485}
3486
df99cd33
TI
3487static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3488 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3489 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3490 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3491 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3492 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3493 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3494 { } /* end */
3495};
3496
3497static struct hda_input_mux alc880_medion_rim_capture_source = {
3498 .num_items = 2,
3499 .items = {
3500 { "Mic", 0x0 },
3501 { "Internal Mic", 0x1 },
3502 },
3503};
3504
3505static struct hda_verb alc880_medion_rim_init_verbs[] = {
3506 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3507
3508 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3509 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3510
3511 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3512 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3513 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3514 /* Mic2 (as headphone out) for HP output */
3515 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3516 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3517 /* Internal Speaker */
3518 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3519 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3520
3521 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3522 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3523
3524 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3525 { }
3526};
3527
3528/* toggle speaker-output according to the hp-jack state */
3529static void alc880_medion_rim_automute(struct hda_codec *codec)
3530{
a9fd4f3f
TI
3531 struct alc_spec *spec = codec->spec;
3532 alc_automute_amp(codec);
3533 /* toggle EAPD */
3534 if (spec->jack_present)
df99cd33
TI
3535 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3536 else
3537 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3538}
3539
3540static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3541 unsigned int res)
3542{
3543 /* Looks like the unsol event is incompatible with the standard
3544 * definition. 4bit tag is placed at 28 bit!
3545 */
3546 if ((res >> 28) == ALC880_HP_EVENT)
3547 alc880_medion_rim_automute(codec);
3548}
3549
4f5d1706 3550static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
3551{
3552 struct alc_spec *spec = codec->spec;
3553
3554 spec->autocfg.hp_pins[0] = 0x14;
3555 spec->autocfg.speaker_pins[0] = 0x1b;
a9fd4f3f
TI
3556}
3557
cb53c626
TI
3558#ifdef CONFIG_SND_HDA_POWER_SAVE
3559static struct hda_amp_list alc880_loopbacks[] = {
3560 { 0x0b, HDA_INPUT, 0 },
3561 { 0x0b, HDA_INPUT, 1 },
3562 { 0x0b, HDA_INPUT, 2 },
3563 { 0x0b, HDA_INPUT, 3 },
3564 { 0x0b, HDA_INPUT, 4 },
3565 { } /* end */
3566};
3567
3568static struct hda_amp_list alc880_lg_loopbacks[] = {
3569 { 0x0b, HDA_INPUT, 1 },
3570 { 0x0b, HDA_INPUT, 6 },
3571 { 0x0b, HDA_INPUT, 7 },
3572 { } /* end */
3573};
3574#endif
3575
ae6b813a
TI
3576/*
3577 * Common callbacks
e9edcee0
TI
3578 */
3579
1da177e4
LT
3580static int alc_init(struct hda_codec *codec)
3581{
3582 struct alc_spec *spec = codec->spec;
e9edcee0
TI
3583 unsigned int i;
3584
2c3bf9ab 3585 alc_fix_pll(codec);
4a79ba34 3586 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 3587
e9edcee0
TI
3588 for (i = 0; i < spec->num_init_verbs; i++)
3589 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
3590
3591 if (spec->init_hook)
3592 spec->init_hook(codec);
3593
ad35879a
TI
3594#ifdef CONFIG_SND_HDA_POWER_SAVE
3595 if (codec->patch_ops.check_power_status)
3596 codec->patch_ops.check_power_status(codec, 0x01);
3597#endif
1da177e4
LT
3598 return 0;
3599}
3600
ae6b813a
TI
3601static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3602{
3603 struct alc_spec *spec = codec->spec;
3604
3605 if (spec->unsol_event)
3606 spec->unsol_event(codec, res);
3607}
3608
cb53c626
TI
3609#ifdef CONFIG_SND_HDA_POWER_SAVE
3610static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3611{
3612 struct alc_spec *spec = codec->spec;
3613 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3614}
3615#endif
3616
1da177e4
LT
3617/*
3618 * Analog playback callbacks
3619 */
3620static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3621 struct hda_codec *codec,
c8b6bf9b 3622 struct snd_pcm_substream *substream)
1da177e4
LT
3623{
3624 struct alc_spec *spec = codec->spec;
9a08160b
TI
3625 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3626 hinfo);
1da177e4
LT
3627}
3628
3629static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3630 struct hda_codec *codec,
3631 unsigned int stream_tag,
3632 unsigned int format,
c8b6bf9b 3633 struct snd_pcm_substream *substream)
1da177e4
LT
3634{
3635 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3636 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3637 stream_tag, format, substream);
1da177e4
LT
3638}
3639
3640static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3641 struct hda_codec *codec,
c8b6bf9b 3642 struct snd_pcm_substream *substream)
1da177e4
LT
3643{
3644 struct alc_spec *spec = codec->spec;
3645 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3646}
3647
3648/*
3649 * Digital out
3650 */
3651static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3652 struct hda_codec *codec,
c8b6bf9b 3653 struct snd_pcm_substream *substream)
1da177e4
LT
3654{
3655 struct alc_spec *spec = codec->spec;
3656 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3657}
3658
6b97eb45
TI
3659static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3660 struct hda_codec *codec,
3661 unsigned int stream_tag,
3662 unsigned int format,
3663 struct snd_pcm_substream *substream)
3664{
3665 struct alc_spec *spec = codec->spec;
3666 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3667 stream_tag, format, substream);
3668}
3669
9b5f12e5
TI
3670static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3671 struct hda_codec *codec,
3672 struct snd_pcm_substream *substream)
3673{
3674 struct alc_spec *spec = codec->spec;
3675 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3676}
3677
1da177e4
LT
3678static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3679 struct hda_codec *codec,
c8b6bf9b 3680 struct snd_pcm_substream *substream)
1da177e4
LT
3681{
3682 struct alc_spec *spec = codec->spec;
3683 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3684}
3685
3686/*
3687 * Analog capture
3688 */
6330079f 3689static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3690 struct hda_codec *codec,
3691 unsigned int stream_tag,
3692 unsigned int format,
c8b6bf9b 3693 struct snd_pcm_substream *substream)
1da177e4
LT
3694{
3695 struct alc_spec *spec = codec->spec;
3696
6330079f 3697 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3698 stream_tag, 0, format);
3699 return 0;
3700}
3701
6330079f 3702static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3703 struct hda_codec *codec,
c8b6bf9b 3704 struct snd_pcm_substream *substream)
1da177e4
LT
3705{
3706 struct alc_spec *spec = codec->spec;
3707
888afa15
TI
3708 snd_hda_codec_cleanup_stream(codec,
3709 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3710 return 0;
3711}
3712
840b64c0
TI
3713/* analog capture with dynamic dual-adc changes */
3714static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3715 struct hda_codec *codec,
3716 unsigned int stream_tag,
3717 unsigned int format,
3718 struct snd_pcm_substream *substream)
3719{
3720 struct alc_spec *spec = codec->spec;
3721 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
3722 spec->cur_adc_stream_tag = stream_tag;
3723 spec->cur_adc_format = format;
3724 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
3725 return 0;
3726}
3727
3728static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3729 struct hda_codec *codec,
3730 struct snd_pcm_substream *substream)
3731{
3732 struct alc_spec *spec = codec->spec;
3733 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
3734 spec->cur_adc = 0;
3735 return 0;
3736}
3737
3738static struct hda_pcm_stream dualmic_pcm_analog_capture = {
3739 .substreams = 1,
3740 .channels_min = 2,
3741 .channels_max = 2,
3742 .nid = 0, /* fill later */
3743 .ops = {
3744 .prepare = dualmic_capture_pcm_prepare,
3745 .cleanup = dualmic_capture_pcm_cleanup
3746 },
3747};
1da177e4
LT
3748
3749/*
3750 */
3751static struct hda_pcm_stream alc880_pcm_analog_playback = {
3752 .substreams = 1,
3753 .channels_min = 2,
3754 .channels_max = 8,
e9edcee0 3755 /* NID is set in alc_build_pcms */
1da177e4
LT
3756 .ops = {
3757 .open = alc880_playback_pcm_open,
3758 .prepare = alc880_playback_pcm_prepare,
3759 .cleanup = alc880_playback_pcm_cleanup
3760 },
3761};
3762
3763static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
3764 .substreams = 1,
3765 .channels_min = 2,
3766 .channels_max = 2,
3767 /* NID is set in alc_build_pcms */
3768};
3769
3770static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3771 .substreams = 1,
3772 .channels_min = 2,
3773 .channels_max = 2,
3774 /* NID is set in alc_build_pcms */
3775};
3776
3777static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3778 .substreams = 2, /* can be overridden */
1da177e4
LT
3779 .channels_min = 2,
3780 .channels_max = 2,
e9edcee0 3781 /* NID is set in alc_build_pcms */
1da177e4 3782 .ops = {
6330079f
TI
3783 .prepare = alc880_alt_capture_pcm_prepare,
3784 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
3785 },
3786};
3787
3788static struct hda_pcm_stream alc880_pcm_digital_playback = {
3789 .substreams = 1,
3790 .channels_min = 2,
3791 .channels_max = 2,
3792 /* NID is set in alc_build_pcms */
3793 .ops = {
3794 .open = alc880_dig_playback_pcm_open,
6b97eb45 3795 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
3796 .prepare = alc880_dig_playback_pcm_prepare,
3797 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
3798 },
3799};
3800
3801static struct hda_pcm_stream alc880_pcm_digital_capture = {
3802 .substreams = 1,
3803 .channels_min = 2,
3804 .channels_max = 2,
3805 /* NID is set in alc_build_pcms */
3806};
3807
4c5186ed 3808/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 3809static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
3810 .substreams = 0,
3811 .channels_min = 0,
3812 .channels_max = 0,
3813};
3814
1da177e4
LT
3815static int alc_build_pcms(struct hda_codec *codec)
3816{
3817 struct alc_spec *spec = codec->spec;
3818 struct hda_pcm *info = spec->pcm_rec;
3819 int i;
3820
3821 codec->num_pcms = 1;
3822 codec->pcm_info = info;
3823
e64f14f4
TI
3824 if (spec->no_analog)
3825 goto skip_analog;
3826
812a2cca
TI
3827 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3828 "%s Analog", codec->chip_name);
1da177e4 3829 info->name = spec->stream_name_analog;
274693f3 3830
4a471b7d 3831 if (spec->stream_analog_playback) {
da3cec35
TI
3832 if (snd_BUG_ON(!spec->multiout.dac_nids))
3833 return -EINVAL;
4a471b7d
TI
3834 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3835 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3836 }
3837 if (spec->stream_analog_capture) {
da3cec35
TI
3838 if (snd_BUG_ON(!spec->adc_nids))
3839 return -EINVAL;
4a471b7d
TI
3840 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3841 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3842 }
3843
3844 if (spec->channel_mode) {
3845 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3846 for (i = 0; i < spec->num_channel_mode; i++) {
3847 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3848 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3849 }
1da177e4
LT
3850 }
3851 }
3852
e64f14f4 3853 skip_analog:
e08a007d 3854 /* SPDIF for stream index #1 */
1da177e4 3855 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
3856 snprintf(spec->stream_name_digital,
3857 sizeof(spec->stream_name_digital),
3858 "%s Digital", codec->chip_name);
e08a007d 3859 codec->num_pcms = 2;
b25c9da1 3860 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 3861 info = spec->pcm_rec + 1;
1da177e4 3862 info->name = spec->stream_name_digital;
8c441982
TI
3863 if (spec->dig_out_type)
3864 info->pcm_type = spec->dig_out_type;
3865 else
3866 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
3867 if (spec->multiout.dig_out_nid &&
3868 spec->stream_digital_playback) {
1da177e4
LT
3869 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3870 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3871 }
4a471b7d
TI
3872 if (spec->dig_in_nid &&
3873 spec->stream_digital_capture) {
1da177e4
LT
3874 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3875 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3876 }
963f803f
TI
3877 /* FIXME: do we need this for all Realtek codec models? */
3878 codec->spdif_status_reset = 1;
1da177e4
LT
3879 }
3880
e64f14f4
TI
3881 if (spec->no_analog)
3882 return 0;
3883
e08a007d
TI
3884 /* If the use of more than one ADC is requested for the current
3885 * model, configure a second analog capture-only PCM.
3886 */
3887 /* Additional Analaog capture for index #2 */
6330079f
TI
3888 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3889 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 3890 codec->num_pcms = 3;
c06134d7 3891 info = spec->pcm_rec + 2;
e08a007d 3892 info->name = spec->stream_name_analog;
6330079f
TI
3893 if (spec->alt_dac_nid) {
3894 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3895 *spec->stream_analog_alt_playback;
3896 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3897 spec->alt_dac_nid;
3898 } else {
3899 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3900 alc_pcm_null_stream;
3901 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3902 }
3903 if (spec->num_adc_nids > 1) {
3904 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3905 *spec->stream_analog_alt_capture;
3906 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3907 spec->adc_nids[1];
3908 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3909 spec->num_adc_nids - 1;
3910 } else {
3911 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3912 alc_pcm_null_stream;
3913 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
3914 }
3915 }
3916
1da177e4
LT
3917 return 0;
3918}
3919
a4e09aa3
TI
3920static inline void alc_shutup(struct hda_codec *codec)
3921{
3922 snd_hda_shutup_pins(codec);
3923}
3924
603c4019
TI
3925static void alc_free_kctls(struct hda_codec *codec)
3926{
3927 struct alc_spec *spec = codec->spec;
3928
3929 if (spec->kctls.list) {
3930 struct snd_kcontrol_new *kctl = spec->kctls.list;
3931 int i;
3932 for (i = 0; i < spec->kctls.used; i++)
3933 kfree(kctl[i].name);
3934 }
3935 snd_array_free(&spec->kctls);
3936}
3937
1da177e4
LT
3938static void alc_free(struct hda_codec *codec)
3939{
e9edcee0 3940 struct alc_spec *spec = codec->spec;
e9edcee0 3941
f12ab1e0 3942 if (!spec)
e9edcee0
TI
3943 return;
3944
a4e09aa3 3945 alc_shutup(codec);
603c4019 3946 alc_free_kctls(codec);
e9edcee0 3947 kfree(spec);
680cd536 3948 snd_hda_detach_beep_device(codec);
1da177e4
LT
3949}
3950
f5de24b0 3951#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
3952static void alc_power_eapd(struct hda_codec *codec)
3953{
3954 /* We currently only handle front, HP */
3955 switch (codec->vendor_id) {
3956 case 0x10ec0260:
9e4c8496
TI
3957 set_eapd(codec, 0x0f, 0);
3958 set_eapd(codec, 0x10, 0);
c97259df
DC
3959 break;
3960 case 0x10ec0262:
3961 case 0x10ec0267:
3962 case 0x10ec0268:
3963 case 0x10ec0269:
9e4c8496 3964 case 0x10ec0270:
c97259df
DC
3965 case 0x10ec0272:
3966 case 0x10ec0660:
3967 case 0x10ec0662:
3968 case 0x10ec0663:
3969 case 0x10ec0862:
3970 case 0x10ec0889:
9e4c8496
TI
3971 set_eapd(codec, 0x14, 0);
3972 set_eapd(codec, 0x15, 0);
c97259df
DC
3973 break;
3974 }
3975}
3976
f5de24b0
HM
3977static int alc_suspend(struct hda_codec *codec, pm_message_t state)
3978{
3979 struct alc_spec *spec = codec->spec;
a4e09aa3 3980 alc_shutup(codec);
f5de24b0 3981 if (spec && spec->power_hook)
c97259df 3982 spec->power_hook(codec);
f5de24b0
HM
3983 return 0;
3984}
3985#endif
3986
e044c39a 3987#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
3988static int alc_resume(struct hda_codec *codec)
3989{
e044c39a
TI
3990 codec->patch_ops.init(codec);
3991 snd_hda_codec_resume_amp(codec);
3992 snd_hda_codec_resume_cache(codec);
ad35879a
TI
3993#ifdef CONFIG_SND_HDA_POWER_SAVE
3994 if (codec->patch_ops.check_power_status)
3995 codec->patch_ops.check_power_status(codec, 0x01);
3996#endif
e044c39a
TI
3997 return 0;
3998}
e044c39a
TI
3999#endif
4000
1da177e4
LT
4001/*
4002 */
4003static struct hda_codec_ops alc_patch_ops = {
4004 .build_controls = alc_build_controls,
4005 .build_pcms = alc_build_pcms,
4006 .init = alc_init,
4007 .free = alc_free,
ae6b813a 4008 .unsol_event = alc_unsol_event,
e044c39a
TI
4009#ifdef SND_HDA_NEEDS_RESUME
4010 .resume = alc_resume,
4011#endif
cb53c626 4012#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4013 .suspend = alc_suspend,
cb53c626
TI
4014 .check_power_status = alc_check_power_status,
4015#endif
c97259df 4016 .reboot_notify = alc_shutup,
1da177e4
LT
4017};
4018
c027ddcd
KY
4019/* replace the codec chip_name with the given string */
4020static int alc_codec_rename(struct hda_codec *codec, const char *name)
4021{
4022 kfree(codec->chip_name);
4023 codec->chip_name = kstrdup(name, GFP_KERNEL);
4024 if (!codec->chip_name) {
4025 alc_free(codec);
4026 return -ENOMEM;
4027 }
4028 return 0;
4029}
4030
2fa522be
TI
4031/*
4032 * Test configuration for debugging
4033 *
4034 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4035 * enum controls.
4036 */
4037#ifdef CONFIG_SND_DEBUG
4038static hda_nid_t alc880_test_dac_nids[4] = {
4039 0x02, 0x03, 0x04, 0x05
4040};
4041
4042static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4043 .num_items = 7,
2fa522be
TI
4044 .items = {
4045 { "In-1", 0x0 },
4046 { "In-2", 0x1 },
4047 { "In-3", 0x2 },
4048 { "In-4", 0x3 },
4049 { "CD", 0x4 },
ae6b813a
TI
4050 { "Front", 0x5 },
4051 { "Surround", 0x6 },
2fa522be
TI
4052 },
4053};
4054
d2a6d7dc 4055static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4056 { 2, NULL },
fd2c326d 4057 { 4, NULL },
2fa522be 4058 { 6, NULL },
fd2c326d 4059 { 8, NULL },
2fa522be
TI
4060};
4061
9c7f852e
TI
4062static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4063 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4064{
4065 static char *texts[] = {
4066 "N/A", "Line Out", "HP Out",
4067 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4068 };
4069 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4070 uinfo->count = 1;
4071 uinfo->value.enumerated.items = 8;
4072 if (uinfo->value.enumerated.item >= 8)
4073 uinfo->value.enumerated.item = 7;
4074 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4075 return 0;
4076}
4077
9c7f852e
TI
4078static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4079 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4080{
4081 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4082 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4083 unsigned int pin_ctl, item = 0;
4084
4085 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4086 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4087 if (pin_ctl & AC_PINCTL_OUT_EN) {
4088 if (pin_ctl & AC_PINCTL_HP_EN)
4089 item = 2;
4090 else
4091 item = 1;
4092 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4093 switch (pin_ctl & AC_PINCTL_VREFEN) {
4094 case AC_PINCTL_VREF_HIZ: item = 3; break;
4095 case AC_PINCTL_VREF_50: item = 4; break;
4096 case AC_PINCTL_VREF_GRD: item = 5; break;
4097 case AC_PINCTL_VREF_80: item = 6; break;
4098 case AC_PINCTL_VREF_100: item = 7; break;
4099 }
4100 }
4101 ucontrol->value.enumerated.item[0] = item;
4102 return 0;
4103}
4104
9c7f852e
TI
4105static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4106 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4107{
4108 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4109 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4110 static unsigned int ctls[] = {
4111 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4112 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4113 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4114 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4115 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4116 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4117 };
4118 unsigned int old_ctl, new_ctl;
4119
4120 old_ctl = snd_hda_codec_read(codec, nid, 0,
4121 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4122 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4123 if (old_ctl != new_ctl) {
82beb8fd
TI
4124 int val;
4125 snd_hda_codec_write_cache(codec, nid, 0,
4126 AC_VERB_SET_PIN_WIDGET_CONTROL,
4127 new_ctl);
47fd830a
TI
4128 val = ucontrol->value.enumerated.item[0] >= 3 ?
4129 HDA_AMP_MUTE : 0;
4130 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4131 HDA_AMP_MUTE, val);
2fa522be
TI
4132 return 1;
4133 }
4134 return 0;
4135}
4136
9c7f852e
TI
4137static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4138 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
4139{
4140 static char *texts[] = {
4141 "Front", "Surround", "CLFE", "Side"
4142 };
4143 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4144 uinfo->count = 1;
4145 uinfo->value.enumerated.items = 4;
4146 if (uinfo->value.enumerated.item >= 4)
4147 uinfo->value.enumerated.item = 3;
4148 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4149 return 0;
4150}
4151
9c7f852e
TI
4152static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4153 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4154{
4155 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4156 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4157 unsigned int sel;
4158
4159 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4160 ucontrol->value.enumerated.item[0] = sel & 3;
4161 return 0;
4162}
4163
9c7f852e
TI
4164static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4165 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4166{
4167 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4168 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4169 unsigned int sel;
4170
4171 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4172 if (ucontrol->value.enumerated.item[0] != sel) {
4173 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4174 snd_hda_codec_write_cache(codec, nid, 0,
4175 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4176 return 1;
4177 }
4178 return 0;
4179}
4180
4181#define PIN_CTL_TEST(xname,nid) { \
4182 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4183 .name = xname, \
5b0cb1d8 4184 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4185 .info = alc_test_pin_ctl_info, \
4186 .get = alc_test_pin_ctl_get, \
4187 .put = alc_test_pin_ctl_put, \
4188 .private_value = nid \
4189 }
4190
4191#define PIN_SRC_TEST(xname,nid) { \
4192 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4193 .name = xname, \
5b0cb1d8 4194 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4195 .info = alc_test_pin_src_info, \
4196 .get = alc_test_pin_src_get, \
4197 .put = alc_test_pin_src_put, \
4198 .private_value = nid \
4199 }
4200
c8b6bf9b 4201static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4202 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4203 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4204 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4205 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4206 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4207 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4208 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4209 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4210 PIN_CTL_TEST("Front Pin Mode", 0x14),
4211 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4212 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4213 PIN_CTL_TEST("Side Pin Mode", 0x17),
4214 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4215 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4216 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4217 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4218 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4219 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4220 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4221 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4222 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4223 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4224 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4225 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4226 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4227 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4228 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4229 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4230 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4231 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4232 {
4233 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4234 .name = "Channel Mode",
df694daa
KY
4235 .info = alc_ch_mode_info,
4236 .get = alc_ch_mode_get,
4237 .put = alc_ch_mode_put,
2fa522be
TI
4238 },
4239 { } /* end */
4240};
4241
4242static struct hda_verb alc880_test_init_verbs[] = {
4243 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4244 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4245 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4246 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4247 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4248 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4249 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4250 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4251 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4252 /* Vol output for 0x0c-0x0f */
05acb863
TI
4253 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4254 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4255 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4256 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4257 /* Set output pins 0x14-0x17 */
05acb863
TI
4258 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4259 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4260 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4261 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4262 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4263 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4264 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4265 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4266 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4267 /* Set input pins 0x18-0x1c */
16ded525
TI
4268 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4269 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4270 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4271 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4272 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4273 /* Mute input pins 0x18-0x1b */
05acb863
TI
4274 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4275 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4276 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4277 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4278 /* ADC set up */
05acb863 4279 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4280 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4281 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4282 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4283 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4284 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4285 /* Analog input/passthru */
4286 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4287 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4288 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4289 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4290 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4291 { }
4292};
4293#endif
4294
1da177e4
LT
4295/*
4296 */
4297
f5fcc13c
TI
4298static const char *alc880_models[ALC880_MODEL_LAST] = {
4299 [ALC880_3ST] = "3stack",
4300 [ALC880_TCL_S700] = "tcl",
4301 [ALC880_3ST_DIG] = "3stack-digout",
4302 [ALC880_CLEVO] = "clevo",
4303 [ALC880_5ST] = "5stack",
4304 [ALC880_5ST_DIG] = "5stack-digout",
4305 [ALC880_W810] = "w810",
4306 [ALC880_Z71V] = "z71v",
4307 [ALC880_6ST] = "6stack",
4308 [ALC880_6ST_DIG] = "6stack-digout",
4309 [ALC880_ASUS] = "asus",
4310 [ALC880_ASUS_W1V] = "asus-w1v",
4311 [ALC880_ASUS_DIG] = "asus-dig",
4312 [ALC880_ASUS_DIG2] = "asus-dig2",
4313 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4314 [ALC880_UNIWILL_P53] = "uniwill-p53",
4315 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4316 [ALC880_F1734] = "F1734",
4317 [ALC880_LG] = "lg",
4318 [ALC880_LG_LW] = "lg-lw",
df99cd33 4319 [ALC880_MEDION_RIM] = "medion",
2fa522be 4320#ifdef CONFIG_SND_DEBUG
f5fcc13c 4321 [ALC880_TEST] = "test",
2fa522be 4322#endif
f5fcc13c
TI
4323 [ALC880_AUTO] = "auto",
4324};
4325
4326static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4327 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4328 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4329 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4330 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4331 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4332 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4333 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4334 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4335 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4336 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4337 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4338 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4339 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4340 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4341 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4342 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4343 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4344 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4345 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4346 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4347 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4348 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4349 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4350 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4351 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4352 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4353 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4354 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4355 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4356 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4357 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4358 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4359 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4360 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4361 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4362 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4363 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4364 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4365 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4366 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 4367 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
4368 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4369 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4370 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4371 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4372 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4373 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4374 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4375 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4376 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4377 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4378 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
4379 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4380 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4381 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4382 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4383 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4384 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4385 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4386 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4387 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4388 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4389 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4390 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4391 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4392 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4393 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4394 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4395 /* default Intel */
4396 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4397 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4398 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4399 {}
4400};
4401
16ded525 4402/*
df694daa 4403 * ALC880 codec presets
16ded525 4404 */
16ded525
TI
4405static struct alc_config_preset alc880_presets[] = {
4406 [ALC880_3ST] = {
e9edcee0 4407 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4408 .init_verbs = { alc880_volume_init_verbs,
4409 alc880_pin_3stack_init_verbs },
16ded525 4410 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4411 .dac_nids = alc880_dac_nids,
16ded525
TI
4412 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4413 .channel_mode = alc880_threestack_modes,
4e195a7b 4414 .need_dac_fix = 1,
16ded525
TI
4415 .input_mux = &alc880_capture_source,
4416 },
4417 [ALC880_3ST_DIG] = {
e9edcee0 4418 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4419 .init_verbs = { alc880_volume_init_verbs,
4420 alc880_pin_3stack_init_verbs },
16ded525 4421 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4422 .dac_nids = alc880_dac_nids,
4423 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4424 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4425 .channel_mode = alc880_threestack_modes,
4e195a7b 4426 .need_dac_fix = 1,
16ded525
TI
4427 .input_mux = &alc880_capture_source,
4428 },
df694daa
KY
4429 [ALC880_TCL_S700] = {
4430 .mixers = { alc880_tcl_s700_mixer },
4431 .init_verbs = { alc880_volume_init_verbs,
4432 alc880_pin_tcl_S700_init_verbs,
4433 alc880_gpio2_init_verbs },
4434 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4435 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4436 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4437 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4438 .hp_nid = 0x03,
4439 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4440 .channel_mode = alc880_2_jack_modes,
4441 .input_mux = &alc880_capture_source,
4442 },
16ded525 4443 [ALC880_5ST] = {
f12ab1e0
TI
4444 .mixers = { alc880_three_stack_mixer,
4445 alc880_five_stack_mixer},
4446 .init_verbs = { alc880_volume_init_verbs,
4447 alc880_pin_5stack_init_verbs },
16ded525
TI
4448 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4449 .dac_nids = alc880_dac_nids,
16ded525
TI
4450 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4451 .channel_mode = alc880_fivestack_modes,
4452 .input_mux = &alc880_capture_source,
4453 },
4454 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4455 .mixers = { alc880_three_stack_mixer,
4456 alc880_five_stack_mixer },
4457 .init_verbs = { alc880_volume_init_verbs,
4458 alc880_pin_5stack_init_verbs },
16ded525
TI
4459 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4460 .dac_nids = alc880_dac_nids,
4461 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4462 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4463 .channel_mode = alc880_fivestack_modes,
4464 .input_mux = &alc880_capture_source,
4465 },
b6482d48
TI
4466 [ALC880_6ST] = {
4467 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4468 .init_verbs = { alc880_volume_init_verbs,
4469 alc880_pin_6stack_init_verbs },
b6482d48
TI
4470 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4471 .dac_nids = alc880_6st_dac_nids,
4472 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4473 .channel_mode = alc880_sixstack_modes,
4474 .input_mux = &alc880_6stack_capture_source,
4475 },
16ded525 4476 [ALC880_6ST_DIG] = {
e9edcee0 4477 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4478 .init_verbs = { alc880_volume_init_verbs,
4479 alc880_pin_6stack_init_verbs },
16ded525
TI
4480 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4481 .dac_nids = alc880_6st_dac_nids,
4482 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4483 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4484 .channel_mode = alc880_sixstack_modes,
4485 .input_mux = &alc880_6stack_capture_source,
4486 },
4487 [ALC880_W810] = {
e9edcee0 4488 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4489 .init_verbs = { alc880_volume_init_verbs,
4490 alc880_pin_w810_init_verbs,
b0af0de5 4491 alc880_gpio2_init_verbs },
16ded525
TI
4492 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4493 .dac_nids = alc880_w810_dac_nids,
4494 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4495 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4496 .channel_mode = alc880_w810_modes,
4497 .input_mux = &alc880_capture_source,
4498 },
4499 [ALC880_Z71V] = {
e9edcee0 4500 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
4501 .init_verbs = { alc880_volume_init_verbs,
4502 alc880_pin_z71v_init_verbs },
16ded525
TI
4503 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4504 .dac_nids = alc880_z71v_dac_nids,
4505 .dig_out_nid = ALC880_DIGOUT_NID,
4506 .hp_nid = 0x03,
e9edcee0
TI
4507 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4508 .channel_mode = alc880_2_jack_modes,
16ded525
TI
4509 .input_mux = &alc880_capture_source,
4510 },
4511 [ALC880_F1734] = {
e9edcee0 4512 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
4513 .init_verbs = { alc880_volume_init_verbs,
4514 alc880_pin_f1734_init_verbs },
e9edcee0
TI
4515 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4516 .dac_nids = alc880_f1734_dac_nids,
4517 .hp_nid = 0x02,
4518 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4519 .channel_mode = alc880_2_jack_modes,
937b4160
TI
4520 .input_mux = &alc880_f1734_capture_source,
4521 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4522 .setup = alc880_uniwill_p53_setup,
4523 .init_hook = alc_automute_amp,
16ded525
TI
4524 },
4525 [ALC880_ASUS] = {
e9edcee0 4526 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4527 .init_verbs = { alc880_volume_init_verbs,
4528 alc880_pin_asus_init_verbs,
e9edcee0
TI
4529 alc880_gpio1_init_verbs },
4530 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4531 .dac_nids = alc880_asus_dac_nids,
4532 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4533 .channel_mode = alc880_asus_modes,
4e195a7b 4534 .need_dac_fix = 1,
16ded525
TI
4535 .input_mux = &alc880_capture_source,
4536 },
4537 [ALC880_ASUS_DIG] = {
e9edcee0 4538 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4539 .init_verbs = { alc880_volume_init_verbs,
4540 alc880_pin_asus_init_verbs,
e9edcee0
TI
4541 alc880_gpio1_init_verbs },
4542 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4543 .dac_nids = alc880_asus_dac_nids,
16ded525 4544 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4545 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4546 .channel_mode = alc880_asus_modes,
4e195a7b 4547 .need_dac_fix = 1,
16ded525
TI
4548 .input_mux = &alc880_capture_source,
4549 },
df694daa
KY
4550 [ALC880_ASUS_DIG2] = {
4551 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4552 .init_verbs = { alc880_volume_init_verbs,
4553 alc880_pin_asus_init_verbs,
df694daa
KY
4554 alc880_gpio2_init_verbs }, /* use GPIO2 */
4555 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4556 .dac_nids = alc880_asus_dac_nids,
4557 .dig_out_nid = ALC880_DIGOUT_NID,
4558 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4559 .channel_mode = alc880_asus_modes,
4e195a7b 4560 .need_dac_fix = 1,
df694daa
KY
4561 .input_mux = &alc880_capture_source,
4562 },
16ded525 4563 [ALC880_ASUS_W1V] = {
e9edcee0 4564 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
4565 .init_verbs = { alc880_volume_init_verbs,
4566 alc880_pin_asus_init_verbs,
e9edcee0
TI
4567 alc880_gpio1_init_verbs },
4568 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4569 .dac_nids = alc880_asus_dac_nids,
16ded525 4570 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4571 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4572 .channel_mode = alc880_asus_modes,
4e195a7b 4573 .need_dac_fix = 1,
16ded525
TI
4574 .input_mux = &alc880_capture_source,
4575 },
4576 [ALC880_UNIWILL_DIG] = {
45bdd1c1 4577 .mixers = { alc880_asus_mixer },
ccc656ce
KY
4578 .init_verbs = { alc880_volume_init_verbs,
4579 alc880_pin_asus_init_verbs },
e9edcee0
TI
4580 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4581 .dac_nids = alc880_asus_dac_nids,
16ded525 4582 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4583 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4584 .channel_mode = alc880_asus_modes,
4e195a7b 4585 .need_dac_fix = 1,
16ded525
TI
4586 .input_mux = &alc880_capture_source,
4587 },
ccc656ce
KY
4588 [ALC880_UNIWILL] = {
4589 .mixers = { alc880_uniwill_mixer },
4590 .init_verbs = { alc880_volume_init_verbs,
4591 alc880_uniwill_init_verbs },
4592 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4593 .dac_nids = alc880_asus_dac_nids,
4594 .dig_out_nid = ALC880_DIGOUT_NID,
4595 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4596 .channel_mode = alc880_threestack_modes,
4597 .need_dac_fix = 1,
4598 .input_mux = &alc880_capture_source,
4599 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 4600 .setup = alc880_uniwill_setup,
a9fd4f3f 4601 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
4602 },
4603 [ALC880_UNIWILL_P53] = {
4604 .mixers = { alc880_uniwill_p53_mixer },
4605 .init_verbs = { alc880_volume_init_verbs,
4606 alc880_uniwill_p53_init_verbs },
4607 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4608 .dac_nids = alc880_asus_dac_nids,
4609 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4610 .channel_mode = alc880_threestack_modes,
4611 .input_mux = &alc880_capture_source,
4612 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4613 .setup = alc880_uniwill_p53_setup,
4614 .init_hook = alc_automute_amp,
2cf9f0fc
TD
4615 },
4616 [ALC880_FUJITSU] = {
45bdd1c1 4617 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4618 .init_verbs = { alc880_volume_init_verbs,
4619 alc880_uniwill_p53_init_verbs,
4620 alc880_beep_init_verbs },
4621 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4622 .dac_nids = alc880_dac_nids,
d53d7d9e 4623 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4624 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4625 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4626 .input_mux = &alc880_capture_source,
4627 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706
TI
4628 .setup = alc880_uniwill_p53_setup,
4629 .init_hook = alc_automute_amp,
ccc656ce 4630 },
df694daa
KY
4631 [ALC880_CLEVO] = {
4632 .mixers = { alc880_three_stack_mixer },
4633 .init_verbs = { alc880_volume_init_verbs,
4634 alc880_pin_clevo_init_verbs },
4635 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4636 .dac_nids = alc880_dac_nids,
4637 .hp_nid = 0x03,
4638 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4639 .channel_mode = alc880_threestack_modes,
4e195a7b 4640 .need_dac_fix = 1,
df694daa
KY
4641 .input_mux = &alc880_capture_source,
4642 },
ae6b813a
TI
4643 [ALC880_LG] = {
4644 .mixers = { alc880_lg_mixer },
4645 .init_verbs = { alc880_volume_init_verbs,
4646 alc880_lg_init_verbs },
4647 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4648 .dac_nids = alc880_lg_dac_nids,
4649 .dig_out_nid = ALC880_DIGOUT_NID,
4650 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4651 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4652 .need_dac_fix = 1,
ae6b813a 4653 .input_mux = &alc880_lg_capture_source,
a9fd4f3f 4654 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4655 .setup = alc880_lg_setup,
4656 .init_hook = alc_automute_amp,
cb53c626
TI
4657#ifdef CONFIG_SND_HDA_POWER_SAVE
4658 .loopbacks = alc880_lg_loopbacks,
4659#endif
ae6b813a 4660 },
d681518a
TI
4661 [ALC880_LG_LW] = {
4662 .mixers = { alc880_lg_lw_mixer },
4663 .init_verbs = { alc880_volume_init_verbs,
4664 alc880_lg_lw_init_verbs },
0a8c5da3 4665 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
4666 .dac_nids = alc880_dac_nids,
4667 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
4668 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4669 .channel_mode = alc880_lg_lw_modes,
d681518a 4670 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f 4671 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
4672 .setup = alc880_lg_lw_setup,
4673 .init_hook = alc_automute_amp,
d681518a 4674 },
df99cd33
TI
4675 [ALC880_MEDION_RIM] = {
4676 .mixers = { alc880_medion_rim_mixer },
4677 .init_verbs = { alc880_volume_init_verbs,
4678 alc880_medion_rim_init_verbs,
4679 alc_gpio2_init_verbs },
4680 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4681 .dac_nids = alc880_dac_nids,
4682 .dig_out_nid = ALC880_DIGOUT_NID,
4683 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4684 .channel_mode = alc880_2_jack_modes,
4685 .input_mux = &alc880_medion_rim_capture_source,
4686 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
4687 .setup = alc880_medion_rim_setup,
4688 .init_hook = alc880_medion_rim_automute,
df99cd33 4689 },
16ded525
TI
4690#ifdef CONFIG_SND_DEBUG
4691 [ALC880_TEST] = {
e9edcee0
TI
4692 .mixers = { alc880_test_mixer },
4693 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
4694 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4695 .dac_nids = alc880_test_dac_nids,
4696 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4697 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4698 .channel_mode = alc880_test_modes,
4699 .input_mux = &alc880_test_capture_source,
4700 },
4701#endif
4702};
4703
e9edcee0
TI
4704/*
4705 * Automatic parse of I/O pins from the BIOS configuration
4706 */
4707
e9edcee0
TI
4708enum {
4709 ALC_CTL_WIDGET_VOL,
4710 ALC_CTL_WIDGET_MUTE,
4711 ALC_CTL_BIND_MUTE,
4712};
c8b6bf9b 4713static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
4714 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4715 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 4716 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
4717};
4718
4719/* add dynamic controls */
f12ab1e0
TI
4720static int add_control(struct alc_spec *spec, int type, const char *name,
4721 unsigned long val)
e9edcee0 4722{
c8b6bf9b 4723 struct snd_kcontrol_new *knew;
e9edcee0 4724
603c4019
TI
4725 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4726 knew = snd_array_new(&spec->kctls);
4727 if (!knew)
4728 return -ENOMEM;
e9edcee0 4729 *knew = alc880_control_templates[type];
543537bd 4730 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 4731 if (!knew->name)
e9edcee0 4732 return -ENOMEM;
4d02d1b6 4733 if (get_amp_nid_(val))
5e26dfd0 4734 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 4735 knew->private_value = val;
e9edcee0
TI
4736 return 0;
4737}
4738
0afe5f89
TI
4739static int add_control_with_pfx(struct alc_spec *spec, int type,
4740 const char *pfx, const char *dir,
4741 const char *sfx, unsigned long val)
4742{
4743 char name[32];
4744 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
4745 return add_control(spec, type, name, val);
4746}
4747
4748#define add_pb_vol_ctrl(spec, type, pfx, val) \
4749 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val)
4750#define add_pb_sw_ctrl(spec, type, pfx, val) \
4751 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val)
4752
e9edcee0
TI
4753#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4754#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4755#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4756#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
4757#define alc880_idx_to_dac(nid) ((nid) + 0x02)
4758#define alc880_dac_to_idx(nid) ((nid) - 0x02)
4759#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4760#define alc880_idx_to_selector(nid) ((nid) + 0x10)
4761#define ALC880_PIN_CD_NID 0x1c
4762
4763/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
4764static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4765 const struct auto_pin_cfg *cfg)
e9edcee0
TI
4766{
4767 hda_nid_t nid;
4768 int assigned[4];
4769 int i, j;
4770
4771 memset(assigned, 0, sizeof(assigned));
b0af0de5 4772 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
4773
4774 /* check the pins hardwired to audio widget */
4775 for (i = 0; i < cfg->line_outs; i++) {
4776 nid = cfg->line_out_pins[i];
4777 if (alc880_is_fixed_pin(nid)) {
4778 int idx = alc880_fixed_pin_idx(nid);
5014f193 4779 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
4780 assigned[idx] = 1;
4781 }
4782 }
4783 /* left pins can be connect to any audio widget */
4784 for (i = 0; i < cfg->line_outs; i++) {
4785 nid = cfg->line_out_pins[i];
4786 if (alc880_is_fixed_pin(nid))
4787 continue;
4788 /* search for an empty channel */
4789 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
4790 if (!assigned[j]) {
4791 spec->multiout.dac_nids[i] =
4792 alc880_idx_to_dac(j);
e9edcee0
TI
4793 assigned[j] = 1;
4794 break;
4795 }
4796 }
4797 }
4798 spec->multiout.num_dacs = cfg->line_outs;
4799 return 0;
4800}
4801
4802/* add playback controls from the parsed DAC table */
df694daa
KY
4803static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4804 const struct auto_pin_cfg *cfg)
e9edcee0 4805{
f12ab1e0
TI
4806 static const char *chname[4] = {
4807 "Front", "Surround", NULL /*CLFE*/, "Side"
4808 };
e9edcee0
TI
4809 hda_nid_t nid;
4810 int i, err;
4811
4812 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 4813 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
4814 continue;
4815 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4816 if (i == 2) {
4817 /* Center/LFE */
0afe5f89
TI
4818 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4819 "Center",
f12ab1e0
TI
4820 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4821 HDA_OUTPUT));
4822 if (err < 0)
e9edcee0 4823 return err;
0afe5f89
TI
4824 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4825 "LFE",
f12ab1e0
TI
4826 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4827 HDA_OUTPUT));
4828 if (err < 0)
e9edcee0 4829 return err;
0afe5f89
TI
4830 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4831 "Center",
f12ab1e0
TI
4832 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4833 HDA_INPUT));
4834 if (err < 0)
e9edcee0 4835 return err;
0afe5f89
TI
4836 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4837 "LFE",
f12ab1e0
TI
4838 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4839 HDA_INPUT));
4840 if (err < 0)
e9edcee0
TI
4841 return err;
4842 } else {
cb162b6b
TI
4843 const char *pfx;
4844 if (cfg->line_outs == 1 &&
4845 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4846 pfx = "Speaker";
4847 else
4848 pfx = chname[i];
0afe5f89 4849 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
4850 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4851 HDA_OUTPUT));
4852 if (err < 0)
e9edcee0 4853 return err;
0afe5f89 4854 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
4855 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4856 HDA_INPUT));
4857 if (err < 0)
e9edcee0
TI
4858 return err;
4859 }
4860 }
e9edcee0
TI
4861 return 0;
4862}
4863
8d88bc3d
TI
4864/* add playback controls for speaker and HP outputs */
4865static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4866 const char *pfx)
e9edcee0
TI
4867{
4868 hda_nid_t nid;
4869 int err;
4870
f12ab1e0 4871 if (!pin)
e9edcee0
TI
4872 return 0;
4873
4874 if (alc880_is_fixed_pin(pin)) {
4875 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 4876 /* specify the DAC as the extra output */
f12ab1e0 4877 if (!spec->multiout.hp_nid)
e9edcee0 4878 spec->multiout.hp_nid = nid;
82bc955f
TI
4879 else
4880 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
4881 /* control HP volume/switch on the output mixer amp */
4882 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 4883 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
4884 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4885 if (err < 0)
e9edcee0 4886 return err;
0afe5f89 4887 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
4888 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4889 if (err < 0)
e9edcee0
TI
4890 return err;
4891 } else if (alc880_is_multi_pin(pin)) {
4892 /* set manual connection */
e9edcee0 4893 /* we have only a switch on HP-out PIN */
0afe5f89 4894 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
4895 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4896 if (err < 0)
e9edcee0
TI
4897 return err;
4898 }
4899 return 0;
4900}
4901
4902/* create input playback/capture controls for the given pin */
f12ab1e0
TI
4903static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4904 const char *ctlname,
df694daa 4905 int idx, hda_nid_t mix_nid)
e9edcee0 4906{
df694daa 4907 int err;
e9edcee0 4908
0afe5f89 4909 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
f12ab1e0
TI
4910 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4911 if (err < 0)
e9edcee0 4912 return err;
0afe5f89 4913 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
f12ab1e0
TI
4914 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4915 if (err < 0)
e9edcee0
TI
4916 return err;
4917 return 0;
4918}
4919
05f5f477
TI
4920static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
4921{
4922 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
4923 return (pincap & AC_PINCAP_IN) != 0;
4924}
4925
e9edcee0 4926/* create playback/capture controls for input pins */
05f5f477
TI
4927static int alc_auto_create_input_ctls(struct hda_codec *codec,
4928 const struct auto_pin_cfg *cfg,
4929 hda_nid_t mixer,
4930 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 4931{
05f5f477 4932 struct alc_spec *spec = codec->spec;
61b9b9b1 4933 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa 4934 int i, err, idx;
e9edcee0
TI
4935
4936 for (i = 0; i < AUTO_PIN_LAST; i++) {
05f5f477
TI
4937 hda_nid_t pin;
4938
4939 pin = cfg->input_pins[i];
4940 if (!alc_is_input_pin(codec, pin))
4941 continue;
4942
4943 if (mixer) {
4944 idx = get_connection_index(codec, mixer, pin);
4945 if (idx >= 0) {
4946 err = new_analog_input(spec, pin,
4947 auto_pin_cfg_labels[i],
4948 idx, mixer);
4949 if (err < 0)
4950 return err;
4951 }
4952 }
4953
4954 if (!cap1)
4955 continue;
4956 idx = get_connection_index(codec, cap1, pin);
4957 if (idx < 0 && cap2)
4958 idx = get_connection_index(codec, cap2, pin);
4959 if (idx >= 0) {
f12ab1e0
TI
4960 imux->items[imux->num_items].label =
4961 auto_pin_cfg_labels[i];
05f5f477 4962 imux->items[imux->num_items].index = idx;
e9edcee0
TI
4963 imux->num_items++;
4964 }
4965 }
4966 return 0;
4967}
4968
05f5f477
TI
4969static int alc880_auto_create_input_ctls(struct hda_codec *codec,
4970 const struct auto_pin_cfg *cfg)
4971{
4972 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
4973}
4974
f6c7e546
TI
4975static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4976 unsigned int pin_type)
4977{
4978 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4979 pin_type);
4980 /* unmute pin */
d260cdf6
TI
4981 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4982 AMP_OUT_UNMUTE);
f6c7e546
TI
4983}
4984
df694daa
KY
4985static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4986 hda_nid_t nid, int pin_type,
e9edcee0
TI
4987 int dac_idx)
4988{
f6c7e546 4989 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
4990 /* need the manual connection? */
4991 if (alc880_is_multi_pin(nid)) {
4992 struct alc_spec *spec = codec->spec;
4993 int idx = alc880_multi_pin_idx(nid);
4994 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4995 AC_VERB_SET_CONNECT_SEL,
4996 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4997 }
4998}
4999
baba8ee9
TI
5000static int get_pin_type(int line_out_type)
5001{
5002 if (line_out_type == AUTO_PIN_HP_OUT)
5003 return PIN_HP;
5004 else
5005 return PIN_OUT;
5006}
5007
e9edcee0
TI
5008static void alc880_auto_init_multi_out(struct hda_codec *codec)
5009{
5010 struct alc_spec *spec = codec->spec;
5011 int i;
ea1fb29a 5012
e9edcee0
TI
5013 for (i = 0; i < spec->autocfg.line_outs; i++) {
5014 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5015 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5016 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5017 }
5018}
5019
8d88bc3d 5020static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5021{
5022 struct alc_spec *spec = codec->spec;
5023 hda_nid_t pin;
5024
82bc955f 5025 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5026 if (pin) /* connect to front */
5027 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5028 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5029 if (pin) /* connect to front */
5030 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5031}
5032
5033static void alc880_auto_init_analog_input(struct hda_codec *codec)
5034{
5035 struct alc_spec *spec = codec->spec;
5036 int i;
5037
5038 for (i = 0; i < AUTO_PIN_LAST; i++) {
5039 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 5040 if (alc_is_input_pin(codec, nid)) {
23f0c048 5041 alc_set_input_pin(codec, nid, i);
e82c025b
TI
5042 if (nid != ALC880_PIN_CD_NID &&
5043 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5044 snd_hda_codec_write(codec, nid, 0,
5045 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5046 AMP_OUT_MUTE);
5047 }
5048 }
5049}
5050
7f311a46
TI
5051static void alc880_auto_init_input_src(struct hda_codec *codec)
5052{
5053 struct alc_spec *spec = codec->spec;
5054 int c;
5055
5056 for (c = 0; c < spec->num_adc_nids; c++) {
5057 unsigned int mux_idx;
5058 const struct hda_input_mux *imux;
5059 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5060 imux = &spec->input_mux[mux_idx];
5061 if (!imux->num_items && mux_idx > 0)
5062 imux = &spec->input_mux[0];
5063 if (imux)
5064 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5065 AC_VERB_SET_CONNECT_SEL,
5066 imux->items[0].index);
5067 }
5068}
5069
e9edcee0 5070/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5071/* return 1 if successful, 0 if the proper config is not found,
5072 * or a negative error code
5073 */
e9edcee0
TI
5074static int alc880_parse_auto_config(struct hda_codec *codec)
5075{
5076 struct alc_spec *spec = codec->spec;
757899ac 5077 int err;
df694daa 5078 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5079
f12ab1e0
TI
5080 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5081 alc880_ignore);
5082 if (err < 0)
e9edcee0 5083 return err;
f12ab1e0 5084 if (!spec->autocfg.line_outs)
e9edcee0 5085 return 0; /* can't find valid BIOS pin config */
df694daa 5086
f12ab1e0
TI
5087 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5088 if (err < 0)
5089 return err;
5090 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5091 if (err < 0)
5092 return err;
5093 err = alc880_auto_create_extra_out(spec,
5094 spec->autocfg.speaker_pins[0],
5095 "Speaker");
5096 if (err < 0)
5097 return err;
5098 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5099 "Headphone");
5100 if (err < 0)
5101 return err;
05f5f477 5102 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5103 if (err < 0)
e9edcee0
TI
5104 return err;
5105
5106 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5107
757899ac 5108 alc_auto_parse_digital(codec);
e9edcee0 5109
603c4019 5110 if (spec->kctls.list)
d88897ea 5111 add_mixer(spec, spec->kctls.list);
e9edcee0 5112
d88897ea 5113 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5114
a1e8d2da 5115 spec->num_mux_defs = 1;
61b9b9b1 5116 spec->input_mux = &spec->private_imux[0];
e9edcee0 5117
6227cdce 5118 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5119
e9edcee0
TI
5120 return 1;
5121}
5122
ae6b813a
TI
5123/* additional initialization for auto-configuration model */
5124static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5125{
f6c7e546 5126 struct alc_spec *spec = codec->spec;
e9edcee0 5127 alc880_auto_init_multi_out(codec);
8d88bc3d 5128 alc880_auto_init_extra_out(codec);
e9edcee0 5129 alc880_auto_init_analog_input(codec);
7f311a46 5130 alc880_auto_init_input_src(codec);
757899ac 5131 alc_auto_init_digital(codec);
f6c7e546 5132 if (spec->unsol_event)
7fb0d78f 5133 alc_inithook(codec);
e9edcee0
TI
5134}
5135
b59bdf3b
TI
5136/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5137 * one of two digital mic pins, e.g. on ALC272
5138 */
5139static void fixup_automic_adc(struct hda_codec *codec)
5140{
5141 struct alc_spec *spec = codec->spec;
5142 int i;
5143
5144 for (i = 0; i < spec->num_adc_nids; i++) {
5145 hda_nid_t cap = spec->capsrc_nids ?
5146 spec->capsrc_nids[i] : spec->adc_nids[i];
5147 int iidx, eidx;
5148
5149 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5150 if (iidx < 0)
5151 continue;
5152 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5153 if (eidx < 0)
5154 continue;
5155 spec->int_mic.mux_idx = iidx;
5156 spec->ext_mic.mux_idx = eidx;
5157 if (spec->capsrc_nids)
5158 spec->capsrc_nids += i;
5159 spec->adc_nids += i;
5160 spec->num_adc_nids = 1;
5161 return;
5162 }
5163 snd_printd(KERN_INFO "hda_codec: %s: "
5164 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5165 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5166 spec->auto_mic = 0; /* disable auto-mic to be sure */
5167}
5168
840b64c0
TI
5169/* set the default connection to that pin */
5170static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5171{
5172 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5173 int i;
5174
eaa9b3a7
TI
5175 for (i = 0; i < spec->num_adc_nids; i++) {
5176 hda_nid_t cap = spec->capsrc_nids ?
5177 spec->capsrc_nids[i] : spec->adc_nids[i];
5178 int idx;
5179
5180 idx = get_connection_index(codec, cap, pin);
5181 if (idx < 0)
5182 continue;
eaa9b3a7
TI
5183 /* select or unmute this route */
5184 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5185 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5186 HDA_AMP_MUTE, 0);
5187 } else {
5188 snd_hda_codec_write_cache(codec, cap, 0,
5189 AC_VERB_SET_CONNECT_SEL, idx);
5190 }
840b64c0
TI
5191 return i; /* return the found index */
5192 }
5193 return -1; /* not found */
5194}
5195
5196/* choose the ADC/MUX containing the input pin and initialize the setup */
5197static void fixup_single_adc(struct hda_codec *codec)
5198{
5199 struct alc_spec *spec = codec->spec;
5200 hda_nid_t pin = 0;
5201 int i;
5202
5203 /* search for the input pin; there must be only one */
5204 for (i = 0; i < AUTO_PIN_LAST; i++) {
5205 if (spec->autocfg.input_pins[i]) {
5206 pin = spec->autocfg.input_pins[i];
5207 break;
5208 }
5209 }
5210 if (!pin)
eaa9b3a7 5211 return;
840b64c0
TI
5212 i = init_capsrc_for_pin(codec, pin);
5213 if (i >= 0) {
5214 /* use only this ADC */
5215 if (spec->capsrc_nids)
5216 spec->capsrc_nids += i;
5217 spec->adc_nids += i;
5218 spec->num_adc_nids = 1;
eaa9b3a7
TI
5219 }
5220}
5221
840b64c0
TI
5222/* initialize dual adcs */
5223static void fixup_dual_adc_switch(struct hda_codec *codec)
5224{
5225 struct alc_spec *spec = codec->spec;
5226 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5227 init_capsrc_for_pin(codec, spec->int_mic.pin);
5228}
5229
b59bdf3b 5230static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5231{
b59bdf3b 5232 struct alc_spec *spec = codec->spec;
a23b688f
TI
5233 static struct snd_kcontrol_new *caps[2][3] = {
5234 { alc_capture_mixer_nosrc1,
5235 alc_capture_mixer_nosrc2,
5236 alc_capture_mixer_nosrc3 },
5237 { alc_capture_mixer1,
5238 alc_capture_mixer2,
5239 alc_capture_mixer3 },
f9e336f6 5240 };
a23b688f 5241 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5242 int mux = 0;
840b64c0
TI
5243 int num_adcs = spec->num_adc_nids;
5244 if (spec->dual_adc_switch)
5245 fixup_dual_adc_switch(codec);
5246 else if (spec->auto_mic)
b59bdf3b 5247 fixup_automic_adc(codec);
eaa9b3a7
TI
5248 else if (spec->input_mux) {
5249 if (spec->input_mux->num_items > 1)
5250 mux = 1;
5251 else if (spec->input_mux->num_items == 1)
5252 fixup_single_adc(codec);
5253 }
840b64c0
TI
5254 if (spec->dual_adc_switch)
5255 num_adcs = 1;
5256 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5257 }
f9e336f6
TI
5258}
5259
6694635d
TI
5260/* fill adc_nids (and capsrc_nids) containing all active input pins */
5261static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5262 int num_nids)
5263{
5264 struct alc_spec *spec = codec->spec;
5265 int n;
5266 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5267
5268 for (n = 0; n < num_nids; n++) {
5269 hda_nid_t adc, cap;
5270 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5271 int nconns, i, j;
5272
5273 adc = nids[n];
5274 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5275 continue;
5276 cap = adc;
5277 nconns = snd_hda_get_connections(codec, cap, conn,
5278 ARRAY_SIZE(conn));
5279 if (nconns == 1) {
5280 cap = conn[0];
5281 nconns = snd_hda_get_connections(codec, cap, conn,
5282 ARRAY_SIZE(conn));
5283 }
5284 if (nconns <= 0)
5285 continue;
5286 if (!fallback_adc) {
5287 fallback_adc = adc;
5288 fallback_cap = cap;
5289 }
5290 for (i = 0; i < AUTO_PIN_LAST; i++) {
5291 hda_nid_t nid = spec->autocfg.input_pins[i];
5292 if (!nid)
5293 continue;
5294 for (j = 0; j < nconns; j++) {
5295 if (conn[j] == nid)
5296 break;
5297 }
5298 if (j >= nconns)
5299 break;
5300 }
5301 if (i >= AUTO_PIN_LAST) {
5302 int num_adcs = spec->num_adc_nids;
5303 spec->private_adc_nids[num_adcs] = adc;
5304 spec->private_capsrc_nids[num_adcs] = cap;
5305 spec->num_adc_nids++;
5306 spec->adc_nids = spec->private_adc_nids;
5307 if (adc != cap)
5308 spec->capsrc_nids = spec->private_capsrc_nids;
5309 }
5310 }
5311 if (!spec->num_adc_nids) {
5312 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5313 " using fallback 0x%x\n",
5314 codec->chip_name, fallback_adc);
6694635d
TI
5315 spec->private_adc_nids[0] = fallback_adc;
5316 spec->adc_nids = spec->private_adc_nids;
5317 if (fallback_adc != fallback_cap) {
5318 spec->private_capsrc_nids[0] = fallback_cap;
5319 spec->capsrc_nids = spec->private_adc_nids;
5320 }
5321 }
5322}
5323
67d634c0 5324#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5325#define set_beep_amp(spec, nid, idx, dir) \
5326 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25
TI
5327
5328static struct snd_pci_quirk beep_white_list[] = {
5329 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5330 {}
5331};
5332
5333static inline int has_cdefine_beep(struct hda_codec *codec)
5334{
5335 struct alc_spec *spec = codec->spec;
5336 const struct snd_pci_quirk *q;
5337 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5338 if (q)
5339 return q->value;
5340 return spec->cdefine.enable_pcbeep;
5341}
67d634c0
TI
5342#else
5343#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5344#define has_cdefine_beep(codec) 0
67d634c0 5345#endif
45bdd1c1
TI
5346
5347/*
5348 * OK, here we have finally the patch for ALC880
5349 */
5350
1da177e4
LT
5351static int patch_alc880(struct hda_codec *codec)
5352{
5353 struct alc_spec *spec;
5354 int board_config;
df694daa 5355 int err;
1da177e4 5356
e560d8d8 5357 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5358 if (spec == NULL)
5359 return -ENOMEM;
5360
5361 codec->spec = spec;
5362
f5fcc13c
TI
5363 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5364 alc880_models,
5365 alc880_cfg_tbl);
5366 if (board_config < 0) {
9a11f1aa
TI
5367 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5368 codec->chip_name);
e9edcee0 5369 board_config = ALC880_AUTO;
1da177e4 5370 }
1da177e4 5371
e9edcee0
TI
5372 if (board_config == ALC880_AUTO) {
5373 /* automatic parse from the BIOS config */
5374 err = alc880_parse_auto_config(codec);
5375 if (err < 0) {
5376 alc_free(codec);
5377 return err;
f12ab1e0 5378 } else if (!err) {
9c7f852e
TI
5379 printk(KERN_INFO
5380 "hda_codec: Cannot set up configuration "
5381 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5382 board_config = ALC880_3ST;
5383 }
1da177e4
LT
5384 }
5385
680cd536
KK
5386 err = snd_hda_attach_beep_device(codec, 0x1);
5387 if (err < 0) {
5388 alc_free(codec);
5389 return err;
5390 }
5391
df694daa 5392 if (board_config != ALC880_AUTO)
e9c364c0 5393 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5394
1da177e4
LT
5395 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5396 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5397 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5398
1da177e4
LT
5399 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5400 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5401
f12ab1e0 5402 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5403 /* check whether NID 0x07 is valid */
54d17403 5404 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5405 /* get type */
a22d543a 5406 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5407 if (wcap != AC_WID_AUD_IN) {
5408 spec->adc_nids = alc880_adc_nids_alt;
5409 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5410 } else {
5411 spec->adc_nids = alc880_adc_nids;
5412 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5413 }
5414 }
b59bdf3b 5415 set_capture_mixer(codec);
45bdd1c1 5416 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5417
2134ea4f
TI
5418 spec->vmaster_nid = 0x0c;
5419
1da177e4 5420 codec->patch_ops = alc_patch_ops;
e9edcee0 5421 if (board_config == ALC880_AUTO)
ae6b813a 5422 spec->init_hook = alc880_auto_init;
cb53c626
TI
5423#ifdef CONFIG_SND_HDA_POWER_SAVE
5424 if (!spec->loopback.amplist)
5425 spec->loopback.amplist = alc880_loopbacks;
5426#endif
1da177e4
LT
5427
5428 return 0;
5429}
5430
e9edcee0 5431
1da177e4
LT
5432/*
5433 * ALC260 support
5434 */
5435
e9edcee0
TI
5436static hda_nid_t alc260_dac_nids[1] = {
5437 /* front */
5438 0x02,
5439};
5440
5441static hda_nid_t alc260_adc_nids[1] = {
5442 /* ADC0 */
5443 0x04,
5444};
5445
df694daa 5446static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5447 /* ADC1 */
5448 0x05,
5449};
5450
d57fdac0
JW
5451/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5452 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5453 */
5454static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5455 /* ADC0, ADC1 */
5456 0x04, 0x05
5457};
5458
e9edcee0
TI
5459#define ALC260_DIGOUT_NID 0x03
5460#define ALC260_DIGIN_NID 0x06
5461
5462static struct hda_input_mux alc260_capture_source = {
5463 .num_items = 4,
5464 .items = {
5465 { "Mic", 0x0 },
5466 { "Front Mic", 0x1 },
5467 { "Line", 0x2 },
5468 { "CD", 0x4 },
5469 },
5470};
5471
17e7aec6 5472/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5473 * headphone jack and the internal CD lines since these are the only pins at
5474 * which audio can appear. For flexibility, also allow the option of
5475 * recording the mixer output on the second ADC (ADC0 doesn't have a
5476 * connection to the mixer output).
a9430dd8 5477 */
a1e8d2da
JW
5478static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5479 {
5480 .num_items = 3,
5481 .items = {
5482 { "Mic/Line", 0x0 },
5483 { "CD", 0x4 },
5484 { "Headphone", 0x2 },
5485 },
a9430dd8 5486 },
a1e8d2da
JW
5487 {
5488 .num_items = 4,
5489 .items = {
5490 { "Mic/Line", 0x0 },
5491 { "CD", 0x4 },
5492 { "Headphone", 0x2 },
5493 { "Mixer", 0x5 },
5494 },
5495 },
5496
a9430dd8
JW
5497};
5498
a1e8d2da
JW
5499/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5500 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 5501 */
a1e8d2da
JW
5502static struct hda_input_mux alc260_acer_capture_sources[2] = {
5503 {
5504 .num_items = 4,
5505 .items = {
5506 { "Mic", 0x0 },
5507 { "Line", 0x2 },
5508 { "CD", 0x4 },
5509 { "Headphone", 0x5 },
5510 },
5511 },
5512 {
5513 .num_items = 5,
5514 .items = {
5515 { "Mic", 0x0 },
5516 { "Line", 0x2 },
5517 { "CD", 0x4 },
5518 { "Headphone", 0x6 },
5519 { "Mixer", 0x5 },
5520 },
0bfc90e9
JW
5521 },
5522};
cc959489
MS
5523
5524/* Maxdata Favorit 100XS */
5525static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5526 {
5527 .num_items = 2,
5528 .items = {
5529 { "Line/Mic", 0x0 },
5530 { "CD", 0x4 },
5531 },
5532 },
5533 {
5534 .num_items = 3,
5535 .items = {
5536 { "Line/Mic", 0x0 },
5537 { "CD", 0x4 },
5538 { "Mixer", 0x5 },
5539 },
5540 },
5541};
5542
1da177e4
LT
5543/*
5544 * This is just place-holder, so there's something for alc_build_pcms to look
5545 * at when it calculates the maximum number of channels. ALC260 has no mixer
5546 * element which allows changing the channel mode, so the verb list is
5547 * never used.
5548 */
d2a6d7dc 5549static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
5550 { 2, NULL },
5551};
5552
df694daa
KY
5553
5554/* Mixer combinations
5555 *
5556 * basic: base_output + input + pc_beep + capture
5557 * HP: base_output + input + capture_alt
5558 * HP_3013: hp_3013 + input + capture
5559 * fujitsu: fujitsu + capture
0bfc90e9 5560 * acer: acer + capture
df694daa
KY
5561 */
5562
5563static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 5564 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5565 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 5566 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 5567 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 5568 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 5569 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 5570 { } /* end */
f12ab1e0 5571};
1da177e4 5572
df694daa 5573static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
5574 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5575 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5576 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5577 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5578 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5579 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5580 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5581 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
5582 { } /* end */
5583};
5584
bec15c3a
TI
5585/* update HP, line and mono out pins according to the master switch */
5586static void alc260_hp_master_update(struct hda_codec *codec,
5587 hda_nid_t hp, hda_nid_t line,
5588 hda_nid_t mono)
5589{
5590 struct alc_spec *spec = codec->spec;
5591 unsigned int val = spec->master_sw ? PIN_HP : 0;
5592 /* change HP and line-out pins */
30cde0aa 5593 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 5594 val);
30cde0aa 5595 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5596 val);
5597 /* mono (speaker) depending on the HP jack sense */
5598 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 5599 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
5600 val);
5601}
5602
5603static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5604 struct snd_ctl_elem_value *ucontrol)
5605{
5606 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5607 struct alc_spec *spec = codec->spec;
5608 *ucontrol->value.integer.value = spec->master_sw;
5609 return 0;
5610}
5611
5612static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5613 struct snd_ctl_elem_value *ucontrol)
5614{
5615 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5616 struct alc_spec *spec = codec->spec;
5617 int val = !!*ucontrol->value.integer.value;
5618 hda_nid_t hp, line, mono;
5619
5620 if (val == spec->master_sw)
5621 return 0;
5622 spec->master_sw = val;
5623 hp = (kcontrol->private_value >> 16) & 0xff;
5624 line = (kcontrol->private_value >> 8) & 0xff;
5625 mono = kcontrol->private_value & 0xff;
5626 alc260_hp_master_update(codec, hp, line, mono);
5627 return 1;
5628}
5629
5630static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5631 {
5632 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5633 .name = "Master Playback Switch",
5b0cb1d8 5634 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5635 .info = snd_ctl_boolean_mono_info,
5636 .get = alc260_hp_master_sw_get,
5637 .put = alc260_hp_master_sw_put,
5638 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5639 },
5640 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5641 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5642 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5643 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5644 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5645 HDA_OUTPUT),
5646 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5647 { } /* end */
5648};
5649
5650static struct hda_verb alc260_hp_unsol_verbs[] = {
5651 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5652 {},
5653};
5654
5655static void alc260_hp_automute(struct hda_codec *codec)
5656{
5657 struct alc_spec *spec = codec->spec;
bec15c3a 5658
864f92be 5659 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
bec15c3a
TI
5660 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5661}
5662
5663static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5664{
5665 if ((res >> 26) == ALC880_HP_EVENT)
5666 alc260_hp_automute(codec);
5667}
5668
df694daa 5669static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
5670 {
5671 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5672 .name = "Master Playback Switch",
5b0cb1d8 5673 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
5674 .info = snd_ctl_boolean_mono_info,
5675 .get = alc260_hp_master_sw_get,
5676 .put = alc260_hp_master_sw_put,
30cde0aa 5677 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 5678 },
df694daa
KY
5679 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5680 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5681 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5682 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5683 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5684 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
5685 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5686 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
5687 { } /* end */
5688};
5689
3f878308
KY
5690static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5691 .ops = &snd_hda_bind_vol,
5692 .values = {
5693 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5694 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5695 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5696 0
5697 },
5698};
5699
5700static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5701 .ops = &snd_hda_bind_sw,
5702 .values = {
5703 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5704 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5705 0
5706 },
5707};
5708
5709static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5710 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5711 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5712 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5713 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5714 { } /* end */
5715};
5716
bec15c3a
TI
5717static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5718 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5719 {},
5720};
5721
5722static void alc260_hp_3013_automute(struct hda_codec *codec)
5723{
5724 struct alc_spec *spec = codec->spec;
bec15c3a 5725
864f92be 5726 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
30cde0aa 5727 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
5728}
5729
5730static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5731 unsigned int res)
5732{
5733 if ((res >> 26) == ALC880_HP_EVENT)
5734 alc260_hp_3013_automute(codec);
5735}
5736
3f878308
KY
5737static void alc260_hp_3012_automute(struct hda_codec *codec)
5738{
864f92be 5739 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
3f878308 5740
3f878308
KY
5741 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5742 bits);
5743 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5744 bits);
5745 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5746 bits);
5747}
5748
5749static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5750 unsigned int res)
5751{
5752 if ((res >> 26) == ALC880_HP_EVENT)
5753 alc260_hp_3012_automute(codec);
5754}
5755
5756/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
5757 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5758 */
c8b6bf9b 5759static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 5760 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 5761 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 5762 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
5763 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5764 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5765 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5766 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 5767 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
5768 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5769 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
5770 { } /* end */
5771};
5772
a1e8d2da
JW
5773/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5774 * versions of the ALC260 don't act on requests to enable mic bias from NID
5775 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5776 * datasheet doesn't mention this restriction. At this stage it's not clear
5777 * whether this behaviour is intentional or is a hardware bug in chip
5778 * revisions available in early 2006. Therefore for now allow the
5779 * "Headphone Jack Mode" control to span all choices, but if it turns out
5780 * that the lack of mic bias for this NID is intentional we could change the
5781 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5782 *
5783 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5784 * don't appear to make the mic bias available from the "line" jack, even
5785 * though the NID used for this jack (0x14) can supply it. The theory is
5786 * that perhaps Acer have included blocking capacitors between the ALC260
5787 * and the output jack. If this turns out to be the case for all such
5788 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5789 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
5790 *
5791 * The C20x Tablet series have a mono internal speaker which is controlled
5792 * via the chip's Mono sum widget and pin complex, so include the necessary
5793 * controls for such models. On models without a "mono speaker" the control
5794 * won't do anything.
a1e8d2da 5795 */
0bfc90e9
JW
5796static struct snd_kcontrol_new alc260_acer_mixer[] = {
5797 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5798 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 5799 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 5800 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 5801 HDA_OUTPUT),
31bffaa9 5802 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 5803 HDA_INPUT),
0bfc90e9
JW
5804 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5805 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5806 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5807 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5808 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5809 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5810 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5811 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
5812 { } /* end */
5813};
5814
cc959489
MS
5815/* Maxdata Favorit 100XS: one output and one input (0x12) jack
5816 */
5817static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5818 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5819 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5820 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5821 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5822 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5823 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5824 { } /* end */
5825};
5826
bc9f98a9
KY
5827/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5828 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5829 */
5830static struct snd_kcontrol_new alc260_will_mixer[] = {
5831 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5832 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5833 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5834 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5835 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5836 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5837 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5838 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5839 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5840 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
5841 { } /* end */
5842};
5843
5844/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5845 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5846 */
5847static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5848 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5849 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5850 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5851 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5852 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5853 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5854 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5855 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5856 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5857 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5858 { } /* end */
5859};
5860
df694daa
KY
5861/*
5862 * initialization verbs
5863 */
1da177e4
LT
5864static struct hda_verb alc260_init_verbs[] = {
5865 /* Line In pin widget for input */
05acb863 5866 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5867 /* CD pin widget for input */
05acb863 5868 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5869 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 5870 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5871 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 5872 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5873 /* LINE-2 is used for line-out in rear */
05acb863 5874 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5875 /* select line-out */
fd56f2db 5876 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5877 /* LINE-OUT pin */
05acb863 5878 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5879 /* enable HP */
05acb863 5880 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 5881 /* enable Mono */
05acb863
TI
5882 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5883 /* mute capture amp left and right */
16ded525 5884 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
5885 /* set connection select to line in (default select for this ADC) */
5886 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
5887 /* mute capture amp left and right */
5888 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5889 /* set connection select to line in (default select for this ADC) */
5890 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
5891 /* set vol=0 Line-Out mixer amp left and right */
5892 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5893 /* unmute pin widget amp left and right (no gain on this amp) */
5894 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5895 /* set vol=0 HP mixer amp left and right */
5896 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5897 /* unmute pin widget amp left and right (no gain on this amp) */
5898 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5899 /* set vol=0 Mono mixer amp left and right */
5900 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5901 /* unmute pin widget amp left and right (no gain on this amp) */
5902 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5903 /* unmute LINE-2 out pin */
5904 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
5905 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5906 * Line In 2 = 0x03
5907 */
cb53c626
TI
5908 /* mute analog inputs */
5909 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5910 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5911 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5912 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5913 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5914 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
5915 /* mute Front out path */
5916 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5917 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5918 /* mute Headphone out path */
5919 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5920 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5921 /* mute Mono out path */
5922 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5923 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
5924 { }
5925};
5926
474167d6 5927#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
5928static struct hda_verb alc260_hp_init_verbs[] = {
5929 /* Headphone and output */
5930 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5931 /* mono output */
5932 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5933 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5934 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5935 /* Mic2 (front panel) pin widget for input and vref at 80% */
5936 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5937 /* Line In pin widget for input */
5938 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5939 /* Line-2 pin widget for output */
5940 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5941 /* CD pin widget for input */
5942 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5943 /* unmute amp left and right */
5944 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5945 /* set connection select to line in (default select for this ADC) */
5946 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5947 /* unmute Line-Out mixer amp left and right (volume = 0) */
5948 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5949 /* mute pin widget amp left and right (no gain on this amp) */
5950 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5951 /* unmute HP mixer amp left and right (volume = 0) */
5952 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5953 /* mute pin widget amp left and right (no gain on this amp) */
5954 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5955 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5956 * Line In 2 = 0x03
5957 */
cb53c626
TI
5958 /* mute analog inputs */
5959 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5960 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5961 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5962 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5963 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5964 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5965 /* Unmute Front out path */
5966 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5967 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5968 /* Unmute Headphone out path */
5969 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5970 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5971 /* Unmute Mono out path */
5972 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5973 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5974 { }
5975};
474167d6 5976#endif
df694daa
KY
5977
5978static struct hda_verb alc260_hp_3013_init_verbs[] = {
5979 /* Line out and output */
5980 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5981 /* mono output */
5982 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5983 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5984 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5985 /* Mic2 (front panel) pin widget for input and vref at 80% */
5986 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5987 /* Line In pin widget for input */
5988 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5989 /* Headphone pin widget for output */
5990 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5991 /* CD pin widget for input */
5992 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5993 /* unmute amp left and right */
5994 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5995 /* set connection select to line in (default select for this ADC) */
5996 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5997 /* unmute Line-Out mixer amp left and right (volume = 0) */
5998 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5999 /* mute pin widget amp left and right (no gain on this amp) */
6000 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6001 /* unmute HP mixer amp left and right (volume = 0) */
6002 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6003 /* mute pin widget amp left and right (no gain on this amp) */
6004 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6005 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6006 * Line In 2 = 0x03
6007 */
cb53c626
TI
6008 /* mute analog inputs */
6009 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6010 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6011 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6012 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6013 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6014 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6015 /* Unmute Front out path */
6016 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6017 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6018 /* Unmute Headphone out path */
6019 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6020 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6021 /* Unmute Mono out path */
6022 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6023 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6024 { }
6025};
6026
a9430dd8 6027/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6028 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6029 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
6030 */
6031static struct hda_verb alc260_fujitsu_init_verbs[] = {
6032 /* Disable all GPIOs */
6033 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6034 /* Internal speaker is connected to headphone pin */
6035 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6036 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6037 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6038 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6039 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6040 /* Ensure all other unused pins are disabled and muted. */
6041 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6042 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6043 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6044 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6045 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6046 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6047 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6048 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6049
6050 /* Disable digital (SPDIF) pins */
6051 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6052 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6053
ea1fb29a 6054 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6055 * when acting as an output.
6056 */
6057 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6058
f7ace40d 6059 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6060 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6061 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6062 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6063 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6064 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6065 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6066 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6067 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6068 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6069
f7ace40d
JW
6070 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6071 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6072 /* Unmute Line1 pin widget output buffer since it starts as an output.
6073 * If the pin mode is changed by the user the pin mode control will
6074 * take care of enabling the pin's input/output buffers as needed.
6075 * Therefore there's no need to enable the input buffer at this
6076 * stage.
cdcd9268 6077 */
f7ace40d 6078 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6079 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6080 * mixer ctrl)
6081 */
f7ace40d
JW
6082 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6083
6084 /* Mute capture amp left and right */
6085 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6086 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6087 * in (on mic1 pin)
6088 */
6089 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6090
6091 /* Do the same for the second ADC: mute capture input amp and
6092 * set ADC connection to line in (on mic1 pin)
6093 */
6094 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6095 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6096
6097 /* Mute all inputs to mixer widget (even unconnected ones) */
6098 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6099 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6100 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6101 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6102 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6103 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6104 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6105 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6106
6107 { }
a9430dd8
JW
6108};
6109
0bfc90e9
JW
6110/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6111 * similar laptops (adapted from Fujitsu init verbs).
6112 */
6113static struct hda_verb alc260_acer_init_verbs[] = {
6114 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6115 * the headphone jack. Turn this on and rely on the standard mute
6116 * methods whenever the user wants to turn these outputs off.
6117 */
6118 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6119 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6120 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6121 /* Internal speaker/Headphone jack is connected to Line-out pin */
6122 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6123 /* Internal microphone/Mic jack is connected to Mic1 pin */
6124 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6125 /* Line In jack is connected to Line1 pin */
6126 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6127 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6128 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6129 /* Ensure all other unused pins are disabled and muted. */
6130 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6131 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6132 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6133 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6134 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6135 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6136 /* Disable digital (SPDIF) pins */
6137 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6138 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6139
ea1fb29a 6140 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6141 * bus when acting as outputs.
6142 */
6143 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6144 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6145
6146 /* Start with output sum widgets muted and their output gains at min */
6147 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6148 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6149 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6150 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6151 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6152 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6153 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6154 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6155 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6156
f12ab1e0
TI
6157 /* Unmute Line-out pin widget amp left and right
6158 * (no equiv mixer ctrl)
6159 */
0bfc90e9 6160 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6161 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6162 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6163 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6164 * inputs. If the pin mode is changed by the user the pin mode control
6165 * will take care of enabling the pin's input/output buffers as needed.
6166 * Therefore there's no need to enable the input buffer at this
6167 * stage.
6168 */
6169 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6170 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6171
6172 /* Mute capture amp left and right */
6173 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6174 /* Set ADC connection select to match default mixer setting - mic
6175 * (on mic1 pin)
6176 */
6177 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6178
6179 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6180 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6181 */
6182 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6183 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6184
6185 /* Mute all inputs to mixer widget (even unconnected ones) */
6186 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6187 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6188 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6189 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6190 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6191 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6192 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6193 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6194
6195 { }
6196};
6197
cc959489
MS
6198/* Initialisation sequence for Maxdata Favorit 100XS
6199 * (adapted from Acer init verbs).
6200 */
6201static struct hda_verb alc260_favorit100_init_verbs[] = {
6202 /* GPIO 0 enables the output jack.
6203 * Turn this on and rely on the standard mute
6204 * methods whenever the user wants to turn these outputs off.
6205 */
6206 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6207 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6208 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6209 /* Line/Mic input jack is connected to Mic1 pin */
6210 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6211 /* Ensure all other unused pins are disabled and muted. */
6212 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6213 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6214 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6215 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6216 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6217 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6218 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6219 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6220 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6221 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6222 /* Disable digital (SPDIF) pins */
6223 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6224 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6225
6226 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6227 * bus when acting as outputs.
6228 */
6229 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6230 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6231
6232 /* Start with output sum widgets muted and their output gains at min */
6233 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6234 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6235 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6236 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6237 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6238 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6239 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6240 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6241 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6242
6243 /* Unmute Line-out pin widget amp left and right
6244 * (no equiv mixer ctrl)
6245 */
6246 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6247 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6248 * inputs. If the pin mode is changed by the user the pin mode control
6249 * will take care of enabling the pin's input/output buffers as needed.
6250 * Therefore there's no need to enable the input buffer at this
6251 * stage.
6252 */
6253 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6254
6255 /* Mute capture amp left and right */
6256 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6257 /* Set ADC connection select to match default mixer setting - mic
6258 * (on mic1 pin)
6259 */
6260 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6261
6262 /* Do similar with the second ADC: mute capture input amp and
6263 * set ADC connection to mic to match ALSA's default state.
6264 */
6265 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6266 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6267
6268 /* Mute all inputs to mixer widget (even unconnected ones) */
6269 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6270 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6271 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6272 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6273 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6274 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6275 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6276 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6277
6278 { }
6279};
6280
bc9f98a9
KY
6281static struct hda_verb alc260_will_verbs[] = {
6282 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6283 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6284 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6285 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6286 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6287 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6288 {}
6289};
6290
6291static struct hda_verb alc260_replacer_672v_verbs[] = {
6292 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6293 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6294 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6295
6296 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6297 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6298 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6299
6300 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6301 {}
6302};
6303
6304/* toggle speaker-output according to the hp-jack state */
6305static void alc260_replacer_672v_automute(struct hda_codec *codec)
6306{
6307 unsigned int present;
6308
6309 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6310 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6311 if (present) {
82beb8fd
TI
6312 snd_hda_codec_write_cache(codec, 0x01, 0,
6313 AC_VERB_SET_GPIO_DATA, 1);
6314 snd_hda_codec_write_cache(codec, 0x0f, 0,
6315 AC_VERB_SET_PIN_WIDGET_CONTROL,
6316 PIN_HP);
bc9f98a9 6317 } else {
82beb8fd
TI
6318 snd_hda_codec_write_cache(codec, 0x01, 0,
6319 AC_VERB_SET_GPIO_DATA, 0);
6320 snd_hda_codec_write_cache(codec, 0x0f, 0,
6321 AC_VERB_SET_PIN_WIDGET_CONTROL,
6322 PIN_OUT);
bc9f98a9
KY
6323 }
6324}
6325
6326static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6327 unsigned int res)
6328{
6329 if ((res >> 26) == ALC880_HP_EVENT)
6330 alc260_replacer_672v_automute(codec);
6331}
6332
3f878308
KY
6333static struct hda_verb alc260_hp_dc7600_verbs[] = {
6334 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6335 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6336 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6337 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6338 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6339 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6340 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6341 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6342 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6343 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6344 {}
6345};
6346
7cf51e48
JW
6347/* Test configuration for debugging, modelled after the ALC880 test
6348 * configuration.
6349 */
6350#ifdef CONFIG_SND_DEBUG
6351static hda_nid_t alc260_test_dac_nids[1] = {
6352 0x02,
6353};
6354static hda_nid_t alc260_test_adc_nids[2] = {
6355 0x04, 0x05,
6356};
a1e8d2da 6357/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6358 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6359 * is NID 0x04.
17e7aec6 6360 */
a1e8d2da
JW
6361static struct hda_input_mux alc260_test_capture_sources[2] = {
6362 {
6363 .num_items = 7,
6364 .items = {
6365 { "MIC1 pin", 0x0 },
6366 { "MIC2 pin", 0x1 },
6367 { "LINE1 pin", 0x2 },
6368 { "LINE2 pin", 0x3 },
6369 { "CD pin", 0x4 },
6370 { "LINE-OUT pin", 0x5 },
6371 { "HP-OUT pin", 0x6 },
6372 },
6373 },
6374 {
6375 .num_items = 8,
6376 .items = {
6377 { "MIC1 pin", 0x0 },
6378 { "MIC2 pin", 0x1 },
6379 { "LINE1 pin", 0x2 },
6380 { "LINE2 pin", 0x3 },
6381 { "CD pin", 0x4 },
6382 { "Mixer", 0x5 },
6383 { "LINE-OUT pin", 0x6 },
6384 { "HP-OUT pin", 0x7 },
6385 },
7cf51e48
JW
6386 },
6387};
6388static struct snd_kcontrol_new alc260_test_mixer[] = {
6389 /* Output driver widgets */
6390 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6391 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6392 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6393 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6394 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6395 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6396
a1e8d2da
JW
6397 /* Modes for retasking pin widgets
6398 * Note: the ALC260 doesn't seem to act on requests to enable mic
6399 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6400 * mention this restriction. At this stage it's not clear whether
6401 * this behaviour is intentional or is a hardware bug in chip
6402 * revisions available at least up until early 2006. Therefore for
6403 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6404 * choices, but if it turns out that the lack of mic bias for these
6405 * NIDs is intentional we could change their modes from
6406 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6407 */
7cf51e48
JW
6408 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6409 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6410 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6411 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6412 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6413 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6414
6415 /* Loopback mixer controls */
6416 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6417 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6418 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6419 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6420 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6421 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6422 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6423 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6424 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6425 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6426 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6427 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6428 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6429 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6430
6431 /* Controls for GPIO pins, assuming they are configured as outputs */
6432 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6433 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6434 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6435 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6436
92621f13
JW
6437 /* Switches to allow the digital IO pins to be enabled. The datasheet
6438 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6439 * make this output available should provide clarification.
92621f13
JW
6440 */
6441 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6442 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6443
f8225f6d
JW
6444 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6445 * this output to turn on an external amplifier.
6446 */
6447 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6448 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6449
7cf51e48
JW
6450 { } /* end */
6451};
6452static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6453 /* Enable all GPIOs as outputs with an initial value of 0 */
6454 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6455 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6456 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6457
7cf51e48
JW
6458 /* Enable retasking pins as output, initially without power amp */
6459 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6460 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6461 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6462 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6463 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6464 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6465
92621f13
JW
6466 /* Disable digital (SPDIF) pins initially, but users can enable
6467 * them via a mixer switch. In the case of SPDIF-out, this initverb
6468 * payload also sets the generation to 0, output to be in "consumer"
6469 * PCM format, copyright asserted, no pre-emphasis and no validity
6470 * control.
6471 */
7cf51e48
JW
6472 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6473 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6474
ea1fb29a 6475 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6476 * OUT1 sum bus when acting as an output.
6477 */
6478 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6479 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6480 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6481 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6482
6483 /* Start with output sum widgets muted and their output gains at min */
6484 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6485 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6486 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6487 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6488 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6489 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6490 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6491 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6492 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6493
cdcd9268
JW
6494 /* Unmute retasking pin widget output buffers since the default
6495 * state appears to be output. As the pin mode is changed by the
6496 * user the pin mode control will take care of enabling the pin's
6497 * input/output buffers as needed.
6498 */
7cf51e48
JW
6499 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6500 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6501 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6502 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6503 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6504 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6505 /* Also unmute the mono-out pin widget */
6506 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6507
7cf51e48
JW
6508 /* Mute capture amp left and right */
6509 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6510 /* Set ADC connection select to match default mixer setting (mic1
6511 * pin)
7cf51e48
JW
6512 */
6513 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6514
6515 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6516 * set ADC connection to mic1 pin
7cf51e48
JW
6517 */
6518 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6519 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6520
6521 /* Mute all inputs to mixer widget (even unconnected ones) */
6522 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6523 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6524 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6525 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6526 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6527 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6528 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6529 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6530
6531 { }
6532};
6533#endif
6534
6330079f
TI
6535#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6536#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 6537
a3bcba38
TI
6538#define alc260_pcm_digital_playback alc880_pcm_digital_playback
6539#define alc260_pcm_digital_capture alc880_pcm_digital_capture
6540
df694daa
KY
6541/*
6542 * for BIOS auto-configuration
6543 */
16ded525 6544
df694daa 6545static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 6546 const char *pfx, int *vol_bits)
df694daa
KY
6547{
6548 hda_nid_t nid_vol;
6549 unsigned long vol_val, sw_val;
df694daa
KY
6550 int err;
6551
6552 if (nid >= 0x0f && nid < 0x11) {
6553 nid_vol = nid - 0x7;
6554 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6555 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6556 } else if (nid == 0x11) {
6557 nid_vol = nid - 0x7;
6558 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6559 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6560 } else if (nid >= 0x12 && nid <= 0x15) {
6561 nid_vol = 0x08;
6562 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6563 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6564 } else
6565 return 0; /* N/A */
ea1fb29a 6566
863b4518
TI
6567 if (!(*vol_bits & (1 << nid_vol))) {
6568 /* first control for the volume widget */
0afe5f89 6569 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
6570 if (err < 0)
6571 return err;
6572 *vol_bits |= (1 << nid_vol);
6573 }
0afe5f89 6574 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 6575 if (err < 0)
df694daa
KY
6576 return err;
6577 return 1;
6578}
6579
6580/* add playback controls from the parsed DAC table */
6581static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6582 const struct auto_pin_cfg *cfg)
6583{
6584 hda_nid_t nid;
6585 int err;
863b4518 6586 int vols = 0;
df694daa
KY
6587
6588 spec->multiout.num_dacs = 1;
6589 spec->multiout.dac_nids = spec->private_dac_nids;
6590 spec->multiout.dac_nids[0] = 0x02;
6591
6592 nid = cfg->line_out_pins[0];
6593 if (nid) {
23112d6d
TI
6594 const char *pfx;
6595 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6596 pfx = "Master";
6597 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6598 pfx = "Speaker";
6599 else
6600 pfx = "Front";
6601 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
6602 if (err < 0)
6603 return err;
6604 }
6605
82bc955f 6606 nid = cfg->speaker_pins[0];
df694daa 6607 if (nid) {
863b4518 6608 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
6609 if (err < 0)
6610 return err;
6611 }
6612
eb06ed8f 6613 nid = cfg->hp_pins[0];
df694daa 6614 if (nid) {
863b4518
TI
6615 err = alc260_add_playback_controls(spec, nid, "Headphone",
6616 &vols);
df694daa
KY
6617 if (err < 0)
6618 return err;
6619 }
f12ab1e0 6620 return 0;
df694daa
KY
6621}
6622
6623/* create playback/capture controls for input pins */
05f5f477 6624static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
6625 const struct auto_pin_cfg *cfg)
6626{
05f5f477 6627 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
6628}
6629
6630static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6631 hda_nid_t nid, int pin_type,
6632 int sel_idx)
6633{
f6c7e546 6634 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6635 /* need the manual connection? */
6636 if (nid >= 0x12) {
6637 int idx = nid - 0x12;
6638 snd_hda_codec_write(codec, idx + 0x0b, 0,
6639 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
6640 }
6641}
6642
6643static void alc260_auto_init_multi_out(struct hda_codec *codec)
6644{
6645 struct alc_spec *spec = codec->spec;
6646 hda_nid_t nid;
6647
f12ab1e0 6648 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
6649 if (nid) {
6650 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6651 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6652 }
ea1fb29a 6653
82bc955f 6654 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
6655 if (nid)
6656 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6657
eb06ed8f 6658 nid = spec->autocfg.hp_pins[0];
df694daa 6659 if (nid)
baba8ee9 6660 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 6661}
df694daa
KY
6662
6663#define ALC260_PIN_CD_NID 0x16
6664static void alc260_auto_init_analog_input(struct hda_codec *codec)
6665{
6666 struct alc_spec *spec = codec->spec;
6667 int i;
6668
6669 for (i = 0; i < AUTO_PIN_LAST; i++) {
6670 hda_nid_t nid = spec->autocfg.input_pins[i];
6671 if (nid >= 0x12) {
23f0c048 6672 alc_set_input_pin(codec, nid, i);
e82c025b
TI
6673 if (nid != ALC260_PIN_CD_NID &&
6674 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
6675 snd_hda_codec_write(codec, nid, 0,
6676 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6677 AMP_OUT_MUTE);
6678 }
6679 }
6680}
6681
7f311a46
TI
6682#define alc260_auto_init_input_src alc880_auto_init_input_src
6683
df694daa
KY
6684/*
6685 * generic initialization of ADC, input mixers and output mixers
6686 */
6687static struct hda_verb alc260_volume_init_verbs[] = {
6688 /*
6689 * Unmute ADC0-1 and set the default input to mic-in
6690 */
6691 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6692 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6693 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6694 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 6695
df694daa
KY
6696 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6697 * mixer widget
f12ab1e0
TI
6698 * Note: PASD motherboards uses the Line In 2 as the input for
6699 * front panel mic (mic 2)
df694daa
KY
6700 */
6701 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6702 /* mute analog inputs */
6703 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6704 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6705 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6706 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6707 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6708
6709 /*
6710 * Set up output mixers (0x08 - 0x0a)
6711 */
6712 /* set vol=0 to output mixers */
6713 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6714 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6715 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6716 /* set up input amps for analog loopback */
6717 /* Amp Indices: DAC = 0, mixer = 1 */
6718 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6719 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6720 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6721 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6722 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6723 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 6724
df694daa
KY
6725 { }
6726};
6727
6728static int alc260_parse_auto_config(struct hda_codec *codec)
6729{
6730 struct alc_spec *spec = codec->spec;
df694daa
KY
6731 int err;
6732 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6733
f12ab1e0
TI
6734 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6735 alc260_ignore);
6736 if (err < 0)
df694daa 6737 return err;
f12ab1e0
TI
6738 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6739 if (err < 0)
4a471b7d 6740 return err;
603c4019 6741 if (!spec->kctls.list)
df694daa 6742 return 0; /* can't find valid BIOS pin config */
05f5f477 6743 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 6744 if (err < 0)
df694daa
KY
6745 return err;
6746
6747 spec->multiout.max_channels = 2;
6748
0852d7a6 6749 if (spec->autocfg.dig_outs)
df694daa 6750 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 6751 if (spec->kctls.list)
d88897ea 6752 add_mixer(spec, spec->kctls.list);
df694daa 6753
d88897ea 6754 add_verb(spec, alc260_volume_init_verbs);
df694daa 6755
a1e8d2da 6756 spec->num_mux_defs = 1;
61b9b9b1 6757 spec->input_mux = &spec->private_imux[0];
df694daa 6758
6227cdce 6759 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 6760
df694daa
KY
6761 return 1;
6762}
6763
ae6b813a
TI
6764/* additional initialization for auto-configuration model */
6765static void alc260_auto_init(struct hda_codec *codec)
df694daa 6766{
f6c7e546 6767 struct alc_spec *spec = codec->spec;
df694daa
KY
6768 alc260_auto_init_multi_out(codec);
6769 alc260_auto_init_analog_input(codec);
7f311a46 6770 alc260_auto_init_input_src(codec);
757899ac 6771 alc_auto_init_digital(codec);
f6c7e546 6772 if (spec->unsol_event)
7fb0d78f 6773 alc_inithook(codec);
df694daa
KY
6774}
6775
cb53c626
TI
6776#ifdef CONFIG_SND_HDA_POWER_SAVE
6777static struct hda_amp_list alc260_loopbacks[] = {
6778 { 0x07, HDA_INPUT, 0 },
6779 { 0x07, HDA_INPUT, 1 },
6780 { 0x07, HDA_INPUT, 2 },
6781 { 0x07, HDA_INPUT, 3 },
6782 { 0x07, HDA_INPUT, 4 },
6783 { } /* end */
6784};
6785#endif
6786
df694daa
KY
6787/*
6788 * ALC260 configurations
6789 */
f5fcc13c
TI
6790static const char *alc260_models[ALC260_MODEL_LAST] = {
6791 [ALC260_BASIC] = "basic",
6792 [ALC260_HP] = "hp",
6793 [ALC260_HP_3013] = "hp-3013",
2922c9af 6794 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
6795 [ALC260_FUJITSU_S702X] = "fujitsu",
6796 [ALC260_ACER] = "acer",
bc9f98a9
KY
6797 [ALC260_WILL] = "will",
6798 [ALC260_REPLACER_672V] = "replacer",
cc959489 6799 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 6800#ifdef CONFIG_SND_DEBUG
f5fcc13c 6801 [ALC260_TEST] = "test",
7cf51e48 6802#endif
f5fcc13c
TI
6803 [ALC260_AUTO] = "auto",
6804};
6805
6806static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 6807 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 6808 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 6809 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 6810 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 6811 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 6812 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 6813 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 6814 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 6815 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
6816 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6817 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6818 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6819 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6820 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6821 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6822 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6823 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6824 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 6825 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 6826 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
6827 {}
6828};
6829
6830static struct alc_config_preset alc260_presets[] = {
6831 [ALC260_BASIC] = {
6832 .mixers = { alc260_base_output_mixer,
45bdd1c1 6833 alc260_input_mixer },
df694daa
KY
6834 .init_verbs = { alc260_init_verbs },
6835 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6836 .dac_nids = alc260_dac_nids,
f9e336f6 6837 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 6838 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
6839 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6840 .channel_mode = alc260_modes,
6841 .input_mux = &alc260_capture_source,
6842 },
6843 [ALC260_HP] = {
bec15c3a 6844 .mixers = { alc260_hp_output_mixer,
f9e336f6 6845 alc260_input_mixer },
bec15c3a
TI
6846 .init_verbs = { alc260_init_verbs,
6847 alc260_hp_unsol_verbs },
df694daa
KY
6848 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6849 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6850 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6851 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6852 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6853 .channel_mode = alc260_modes,
6854 .input_mux = &alc260_capture_source,
bec15c3a
TI
6855 .unsol_event = alc260_hp_unsol_event,
6856 .init_hook = alc260_hp_automute,
df694daa 6857 },
3f878308
KY
6858 [ALC260_HP_DC7600] = {
6859 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 6860 alc260_input_mixer },
3f878308
KY
6861 .init_verbs = { alc260_init_verbs,
6862 alc260_hp_dc7600_verbs },
6863 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6864 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6865 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6866 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
6867 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6868 .channel_mode = alc260_modes,
6869 .input_mux = &alc260_capture_source,
6870 .unsol_event = alc260_hp_3012_unsol_event,
6871 .init_hook = alc260_hp_3012_automute,
6872 },
df694daa
KY
6873 [ALC260_HP_3013] = {
6874 .mixers = { alc260_hp_3013_mixer,
f9e336f6 6875 alc260_input_mixer },
bec15c3a
TI
6876 .init_verbs = { alc260_hp_3013_init_verbs,
6877 alc260_hp_3013_unsol_verbs },
df694daa
KY
6878 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6879 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6880 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6881 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6882 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6883 .channel_mode = alc260_modes,
6884 .input_mux = &alc260_capture_source,
bec15c3a
TI
6885 .unsol_event = alc260_hp_3013_unsol_event,
6886 .init_hook = alc260_hp_3013_automute,
df694daa
KY
6887 },
6888 [ALC260_FUJITSU_S702X] = {
f9e336f6 6889 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
6890 .init_verbs = { alc260_fujitsu_init_verbs },
6891 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6892 .dac_nids = alc260_dac_nids,
d57fdac0
JW
6893 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6894 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
6895 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6896 .channel_mode = alc260_modes,
a1e8d2da
JW
6897 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6898 .input_mux = alc260_fujitsu_capture_sources,
df694daa 6899 },
0bfc90e9 6900 [ALC260_ACER] = {
f9e336f6 6901 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
6902 .init_verbs = { alc260_acer_init_verbs },
6903 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6904 .dac_nids = alc260_dac_nids,
6905 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6906 .adc_nids = alc260_dual_adc_nids,
6907 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6908 .channel_mode = alc260_modes,
a1e8d2da
JW
6909 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6910 .input_mux = alc260_acer_capture_sources,
0bfc90e9 6911 },
cc959489
MS
6912 [ALC260_FAVORIT100] = {
6913 .mixers = { alc260_favorit100_mixer },
6914 .init_verbs = { alc260_favorit100_init_verbs },
6915 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6916 .dac_nids = alc260_dac_nids,
6917 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6918 .adc_nids = alc260_dual_adc_nids,
6919 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6920 .channel_mode = alc260_modes,
6921 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6922 .input_mux = alc260_favorit100_capture_sources,
6923 },
bc9f98a9 6924 [ALC260_WILL] = {
f9e336f6 6925 .mixers = { alc260_will_mixer },
bc9f98a9
KY
6926 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6927 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6928 .dac_nids = alc260_dac_nids,
6929 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6930 .adc_nids = alc260_adc_nids,
6931 .dig_out_nid = ALC260_DIGOUT_NID,
6932 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6933 .channel_mode = alc260_modes,
6934 .input_mux = &alc260_capture_source,
6935 },
6936 [ALC260_REPLACER_672V] = {
f9e336f6 6937 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
6938 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6939 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6940 .dac_nids = alc260_dac_nids,
6941 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6942 .adc_nids = alc260_adc_nids,
6943 .dig_out_nid = ALC260_DIGOUT_NID,
6944 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6945 .channel_mode = alc260_modes,
6946 .input_mux = &alc260_capture_source,
6947 .unsol_event = alc260_replacer_672v_unsol_event,
6948 .init_hook = alc260_replacer_672v_automute,
6949 },
7cf51e48
JW
6950#ifdef CONFIG_SND_DEBUG
6951 [ALC260_TEST] = {
f9e336f6 6952 .mixers = { alc260_test_mixer },
7cf51e48
JW
6953 .init_verbs = { alc260_test_init_verbs },
6954 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6955 .dac_nids = alc260_test_dac_nids,
6956 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6957 .adc_nids = alc260_test_adc_nids,
6958 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6959 .channel_mode = alc260_modes,
a1e8d2da
JW
6960 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6961 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
6962 },
6963#endif
df694daa
KY
6964};
6965
6966static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
6967{
6968 struct alc_spec *spec;
df694daa 6969 int err, board_config;
1da177e4 6970
e560d8d8 6971 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
6972 if (spec == NULL)
6973 return -ENOMEM;
6974
6975 codec->spec = spec;
6976
f5fcc13c
TI
6977 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6978 alc260_models,
6979 alc260_cfg_tbl);
6980 if (board_config < 0) {
9a11f1aa 6981 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 6982 codec->chip_name);
df694daa 6983 board_config = ALC260_AUTO;
16ded525 6984 }
1da177e4 6985
df694daa
KY
6986 if (board_config == ALC260_AUTO) {
6987 /* automatic parse from the BIOS config */
6988 err = alc260_parse_auto_config(codec);
6989 if (err < 0) {
6990 alc_free(codec);
6991 return err;
f12ab1e0 6992 } else if (!err) {
9c7f852e
TI
6993 printk(KERN_INFO
6994 "hda_codec: Cannot set up configuration "
6995 "from BIOS. Using base mode...\n");
df694daa
KY
6996 board_config = ALC260_BASIC;
6997 }
a9430dd8 6998 }
e9edcee0 6999
680cd536
KK
7000 err = snd_hda_attach_beep_device(codec, 0x1);
7001 if (err < 0) {
7002 alc_free(codec);
7003 return err;
7004 }
7005
df694daa 7006 if (board_config != ALC260_AUTO)
e9c364c0 7007 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7008
1da177e4
LT
7009 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7010 spec->stream_analog_capture = &alc260_pcm_analog_capture;
7011
a3bcba38
TI
7012 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7013 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7014
4ef0ef19
TI
7015 if (!spec->adc_nids && spec->input_mux) {
7016 /* check whether NID 0x04 is valid */
7017 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7018 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7019 /* get type */
7020 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7021 spec->adc_nids = alc260_adc_nids_alt;
7022 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7023 } else {
7024 spec->adc_nids = alc260_adc_nids;
7025 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7026 }
7027 }
b59bdf3b 7028 set_capture_mixer(codec);
45bdd1c1 7029 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7030
2134ea4f
TI
7031 spec->vmaster_nid = 0x08;
7032
1da177e4 7033 codec->patch_ops = alc_patch_ops;
df694daa 7034 if (board_config == ALC260_AUTO)
ae6b813a 7035 spec->init_hook = alc260_auto_init;
cb53c626
TI
7036#ifdef CONFIG_SND_HDA_POWER_SAVE
7037 if (!spec->loopback.amplist)
7038 spec->loopback.amplist = alc260_loopbacks;
7039#endif
1da177e4
LT
7040
7041 return 0;
7042}
7043
e9edcee0 7044
1da177e4 7045/*
4953550a 7046 * ALC882/883/885/888/889 support
1da177e4
LT
7047 *
7048 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7049 * configuration. Each pin widget can choose any input DACs and a mixer.
7050 * Each ADC is connected from a mixer of all inputs. This makes possible
7051 * 6-channel independent captures.
7052 *
7053 * In addition, an independent DAC for the multi-playback (not used in this
7054 * driver yet).
7055 */
df694daa
KY
7056#define ALC882_DIGOUT_NID 0x06
7057#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7058#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7059#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7060#define ALC1200_DIGOUT_NID 0x10
7061
1da177e4 7062
d2a6d7dc 7063static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7064 { 8, NULL }
7065};
7066
4953550a 7067/* DACs */
1da177e4
LT
7068static hda_nid_t alc882_dac_nids[4] = {
7069 /* front, rear, clfe, rear_surr */
7070 0x02, 0x03, 0x04, 0x05
7071};
4953550a 7072#define alc883_dac_nids alc882_dac_nids
1da177e4 7073
4953550a 7074/* ADCs */
df694daa
KY
7075#define alc882_adc_nids alc880_adc_nids
7076#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
7077#define alc883_adc_nids alc882_adc_nids_alt
7078static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7079static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7080#define alc889_adc_nids alc880_adc_nids
1da177e4 7081
e1406348
TI
7082static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7083static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
7084#define alc883_capsrc_nids alc882_capsrc_nids_alt
7085static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7086#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7087
1da177e4
LT
7088/* input MUX */
7089/* FIXME: should be a matrix-type input source selection */
7090
7091static struct hda_input_mux alc882_capture_source = {
7092 .num_items = 4,
7093 .items = {
7094 { "Mic", 0x0 },
7095 { "Front Mic", 0x1 },
7096 { "Line", 0x2 },
7097 { "CD", 0x4 },
7098 },
7099};
41d5545d 7100
4953550a
TI
7101#define alc883_capture_source alc882_capture_source
7102
87a8c370
JK
7103static struct hda_input_mux alc889_capture_source = {
7104 .num_items = 3,
7105 .items = {
7106 { "Front Mic", 0x0 },
7107 { "Mic", 0x3 },
7108 { "Line", 0x2 },
7109 },
7110};
7111
41d5545d
KS
7112static struct hda_input_mux mb5_capture_source = {
7113 .num_items = 3,
7114 .items = {
7115 { "Mic", 0x1 },
b8f171e7 7116 { "Line", 0x7 },
41d5545d
KS
7117 { "CD", 0x4 },
7118 },
7119};
7120
e458b1fa
LY
7121static struct hda_input_mux macmini3_capture_source = {
7122 .num_items = 2,
7123 .items = {
7124 { "Line", 0x2 },
7125 { "CD", 0x4 },
7126 },
7127};
7128
4953550a
TI
7129static struct hda_input_mux alc883_3stack_6ch_intel = {
7130 .num_items = 4,
7131 .items = {
7132 { "Mic", 0x1 },
7133 { "Front Mic", 0x0 },
7134 { "Line", 0x2 },
7135 { "CD", 0x4 },
7136 },
7137};
7138
7139static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7140 .num_items = 2,
7141 .items = {
7142 { "Mic", 0x1 },
7143 { "Line", 0x2 },
7144 },
7145};
7146
7147static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7148 .num_items = 4,
7149 .items = {
7150 { "Mic", 0x0 },
150b432f 7151 { "Int Mic", 0x1 },
4953550a
TI
7152 { "Line", 0x2 },
7153 { "CD", 0x4 },
7154 },
7155};
7156
7157static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7158 .num_items = 2,
7159 .items = {
7160 { "Mic", 0x0 },
7161 { "Int Mic", 0x1 },
7162 },
7163};
7164
7165static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7166 .num_items = 3,
7167 .items = {
7168 { "Mic", 0x0 },
7169 { "Front Mic", 0x1 },
7170 { "Line", 0x4 },
7171 },
7172};
7173
7174static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7175 .num_items = 2,
7176 .items = {
7177 { "Mic", 0x0 },
7178 { "Line", 0x2 },
7179 },
7180};
7181
7182static struct hda_input_mux alc889A_mb31_capture_source = {
7183 .num_items = 2,
7184 .items = {
7185 { "Mic", 0x0 },
7186 /* Front Mic (0x01) unused */
7187 { "Line", 0x2 },
7188 /* Line 2 (0x03) unused */
af901ca1 7189 /* CD (0x04) unused? */
4953550a
TI
7190 },
7191};
7192
b7cccc52
JM
7193static struct hda_input_mux alc889A_imac91_capture_source = {
7194 .num_items = 2,
7195 .items = {
7196 { "Mic", 0x01 },
7197 { "Line", 0x2 }, /* Not sure! */
7198 },
7199};
7200
4953550a
TI
7201/*
7202 * 2ch mode
7203 */
7204static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7205 { 2, NULL }
7206};
7207
272a527c
KY
7208/*
7209 * 2ch mode
7210 */
7211static struct hda_verb alc882_3ST_ch2_init[] = {
7212 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7213 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7214 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7215 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7216 { } /* end */
7217};
7218
4953550a
TI
7219/*
7220 * 4ch mode
7221 */
7222static struct hda_verb alc882_3ST_ch4_init[] = {
7223 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7224 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7225 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7226 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7227 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7228 { } /* end */
7229};
7230
272a527c
KY
7231/*
7232 * 6ch mode
7233 */
7234static struct hda_verb alc882_3ST_ch6_init[] = {
7235 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7236 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7237 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7238 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7239 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7240 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7241 { } /* end */
7242};
7243
4953550a 7244static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7245 { 2, alc882_3ST_ch2_init },
4953550a 7246 { 4, alc882_3ST_ch4_init },
272a527c
KY
7247 { 6, alc882_3ST_ch6_init },
7248};
7249
4953550a
TI
7250#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7251
a65cc60f 7252/*
7253 * 2ch mode
7254 */
7255static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7256 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7257 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7258 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7259 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7260 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7261 { } /* end */
7262};
7263
7264/*
7265 * 4ch mode
7266 */
7267static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7268 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7269 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7270 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7271 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7272 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7273 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7274 { } /* end */
7275};
7276
7277/*
7278 * 6ch mode
7279 */
7280static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7281 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7282 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7283 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7284 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7285 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7286 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7287 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7288 { } /* end */
7289};
7290
7291static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7292 { 2, alc883_3ST_ch2_clevo_init },
7293 { 4, alc883_3ST_ch4_clevo_init },
7294 { 6, alc883_3ST_ch6_clevo_init },
7295};
7296
7297
df694daa
KY
7298/*
7299 * 6ch mode
7300 */
7301static struct hda_verb alc882_sixstack_ch6_init[] = {
7302 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7303 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7304 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7305 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7306 { } /* end */
7307};
7308
7309/*
7310 * 8ch mode
7311 */
7312static struct hda_verb alc882_sixstack_ch8_init[] = {
7313 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7314 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7315 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7316 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7317 { } /* end */
7318};
7319
7320static struct hda_channel_mode alc882_sixstack_modes[2] = {
7321 { 6, alc882_sixstack_ch6_init },
7322 { 8, alc882_sixstack_ch8_init },
7323};
7324
76e6f5a9
RH
7325
7326/* Macbook Air 2,1 */
7327
7328static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7329 { 2, NULL },
7330};
7331
87350ad0 7332/*
def319f9 7333 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7334 */
7335
7336/*
7337 * 2ch mode
7338 */
7339static struct hda_verb alc885_mbp_ch2_init[] = {
7340 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7341 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7342 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7343 { } /* end */
7344};
7345
7346/*
a3f730af 7347 * 4ch mode
87350ad0 7348 */
a3f730af 7349static struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7350 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7351 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7352 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7353 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7354 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7355 { } /* end */
7356};
7357
a3f730af 7358static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7359 { 2, alc885_mbp_ch2_init },
a3f730af 7360 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7361};
7362
92b9de83
KS
7363/*
7364 * 2ch
7365 * Speakers/Woofer/HP = Front
7366 * LineIn = Input
7367 */
7368static struct hda_verb alc885_mb5_ch2_init[] = {
7369 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7370 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7371 { } /* end */
7372};
7373
7374/*
7375 * 6ch mode
7376 * Speakers/HP = Front
7377 * Woofer = LFE
7378 * LineIn = Surround
7379 */
7380static struct hda_verb alc885_mb5_ch6_init[] = {
7381 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7382 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7383 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7384 { } /* end */
7385};
7386
7387static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7388 { 2, alc885_mb5_ch2_init },
7389 { 6, alc885_mb5_ch6_init },
7390};
87350ad0 7391
d01aecdf 7392#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7393
7394/*
7395 * 2ch mode
7396 */
7397static struct hda_verb alc883_4ST_ch2_init[] = {
7398 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7399 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7400 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7401 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7402 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7403 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7404 { } /* end */
7405};
7406
7407/*
7408 * 4ch mode
7409 */
7410static struct hda_verb alc883_4ST_ch4_init[] = {
7411 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7412 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7413 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7414 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7415 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7416 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7417 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7418 { } /* end */
7419};
7420
7421/*
7422 * 6ch mode
7423 */
7424static struct hda_verb alc883_4ST_ch6_init[] = {
7425 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7426 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7427 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7428 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7429 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7430 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7431 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7432 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7433 { } /* end */
7434};
7435
7436/*
7437 * 8ch mode
7438 */
7439static struct hda_verb alc883_4ST_ch8_init[] = {
7440 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7441 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7442 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7443 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7444 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7445 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7446 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7447 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7448 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7449 { } /* end */
7450};
7451
7452static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7453 { 2, alc883_4ST_ch2_init },
7454 { 4, alc883_4ST_ch4_init },
7455 { 6, alc883_4ST_ch6_init },
7456 { 8, alc883_4ST_ch8_init },
7457};
7458
7459
7460/*
7461 * 2ch mode
7462 */
7463static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7464 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7465 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7466 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7467 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7468 { } /* end */
7469};
7470
7471/*
7472 * 4ch mode
7473 */
7474static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7475 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7476 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7477 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7478 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7479 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7480 { } /* end */
7481};
7482
7483/*
7484 * 6ch mode
7485 */
7486static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7487 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7488 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7489 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7490 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7491 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7492 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7493 { } /* end */
7494};
7495
7496static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7497 { 2, alc883_3ST_ch2_intel_init },
7498 { 4, alc883_3ST_ch4_intel_init },
7499 { 6, alc883_3ST_ch6_intel_init },
7500};
7501
dd7714c9
WF
7502/*
7503 * 2ch mode
7504 */
7505static struct hda_verb alc889_ch2_intel_init[] = {
7506 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7507 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7508 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7509 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7510 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7511 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7512 { } /* end */
7513};
7514
87a8c370
JK
7515/*
7516 * 6ch mode
7517 */
7518static struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7519 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7520 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7521 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7522 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7523 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7524 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7525 { } /* end */
7526};
7527
7528/*
7529 * 8ch mode
7530 */
7531static struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7532 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7533 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7534 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7535 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7536 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7537 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7538 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7539 { } /* end */
7540};
7541
dd7714c9
WF
7542static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7543 { 2, alc889_ch2_intel_init },
87a8c370
JK
7544 { 6, alc889_ch6_intel_init },
7545 { 8, alc889_ch8_intel_init },
7546};
7547
4953550a
TI
7548/*
7549 * 6ch mode
7550 */
7551static struct hda_verb alc883_sixstack_ch6_init[] = {
7552 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7553 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7554 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7555 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7556 { } /* end */
7557};
7558
7559/*
7560 * 8ch mode
7561 */
7562static struct hda_verb alc883_sixstack_ch8_init[] = {
7563 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7564 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7565 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7566 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7567 { } /* end */
7568};
7569
7570static struct hda_channel_mode alc883_sixstack_modes[2] = {
7571 { 6, alc883_sixstack_ch6_init },
7572 { 8, alc883_sixstack_ch8_init },
7573};
7574
7575
1da177e4
LT
7576/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7577 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7578 */
c8b6bf9b 7579static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 7580 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 7581 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 7582 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 7583 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
7584 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7585 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
7586 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7587 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 7588 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 7589 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
7590 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7591 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7592 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7593 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7594 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7595 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7596 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
7597 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7598 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7599 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4 7600 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
7601 { } /* end */
7602};
7603
76e6f5a9
RH
7604/* Macbook Air 2,1 same control for HP and internal Speaker */
7605
7606static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7607 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7608 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7609 { }
7610};
7611
7612
87350ad0 7613static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
7614 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7615 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7616 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7617 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7618 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
7619 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7620 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
7621 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7622 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 7623 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
7624 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7625 { } /* end */
7626};
41d5545d
KS
7627
7628static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
7629 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7630 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7631 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7632 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7633 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7634 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
7635 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7636 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
7637 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7638 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
7639 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7640 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7641 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7642 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7643 { } /* end */
7644};
92b9de83 7645
e458b1fa
LY
7646static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7647 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7648 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7649 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7650 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7651 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7652 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7653 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7654 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7655 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7656 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7657 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7658 { } /* end */
7659};
7660
4b7e1803 7661static struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
7662 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7663 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
7664 { } /* end */
7665};
7666
7667
bdd148a3
KY
7668static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7669 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7670 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7671 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7672 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7673 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7674 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7675 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7676 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7677 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
7678 { } /* end */
7679};
7680
272a527c
KY
7681static struct snd_kcontrol_new alc882_targa_mixer[] = {
7682 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7683 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7684 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7685 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7686 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7687 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7688 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7689 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7690 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7691 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7692 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7693 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 7694 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
7695 { } /* end */
7696};
7697
7698/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7699 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7700 */
7701static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7702 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7703 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7704 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7705 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7706 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7707 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7708 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7709 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7710 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7711 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7712 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7713 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 7714 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
7715 { } /* end */
7716};
7717
914759b7
TI
7718static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7719 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7720 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7721 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7722 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7723 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7724 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7725 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7726 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7727 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7728 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
7729 { } /* end */
7730};
7731
df694daa
KY
7732static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7733 {
7734 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7735 .name = "Channel Mode",
7736 .info = alc_ch_mode_info,
7737 .get = alc_ch_mode_get,
7738 .put = alc_ch_mode_put,
7739 },
7740 { } /* end */
7741};
7742
4953550a 7743static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 7744 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
7745 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7746 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7747 /* Rear mixer */
05acb863
TI
7748 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7749 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7750 /* CLFE mixer */
05acb863
TI
7751 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7752 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7753 /* Side mixer */
05acb863
TI
7754 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7755 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 7756
e9edcee0 7757 /* Front Pin: output 0 (0x0c) */
05acb863 7758 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7759 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7760 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 7761 /* Rear Pin: output 1 (0x0d) */
05acb863 7762 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7763 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7764 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 7765 /* CLFE Pin: output 2 (0x0e) */
05acb863 7766 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7767 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7768 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 7769 /* Side Pin: output 3 (0x0f) */
05acb863 7770 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 7771 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 7772 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 7773 /* Mic (rear) pin: input vref at 80% */
16ded525 7774 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7775 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7776 /* Front Mic pin: input vref at 80% */
16ded525 7777 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
7778 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7779 /* Line In pin: input */
05acb863 7780 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
7781 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7782 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7783 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7784 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7785 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 7786 /* CD pin widget for input */
05acb863 7787 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
7788
7789 /* FIXME: use matrix-type input source selection */
7790 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 7791 /* Input mixer2 */
05acb863 7792 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 7793 /* Input mixer3 */
05acb863 7794 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
7795 /* ADC2: mute amp left and right */
7796 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7797 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
7798 /* ADC3: mute amp left and right */
7799 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 7800 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
7801
7802 { }
7803};
7804
4953550a
TI
7805static struct hda_verb alc882_adc1_init_verbs[] = {
7806 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7807 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7808 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7809 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7810 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7811 /* ADC1: mute amp left and right */
7812 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7813 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7814 { }
7815};
7816
4b146cb0
TI
7817static struct hda_verb alc882_eapd_verbs[] = {
7818 /* change to EAPD mode */
7819 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 7820 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 7821 { }
4b146cb0
TI
7822};
7823
87a8c370
JK
7824static struct hda_verb alc889_eapd_verbs[] = {
7825 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7826 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7827 { }
7828};
7829
6732bd0d
WF
7830static struct hda_verb alc_hp15_unsol_verbs[] = {
7831 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7832 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7833 {}
7834};
87a8c370
JK
7835
7836static struct hda_verb alc885_init_verbs[] = {
7837 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
7838 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7839 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7840 /* Rear mixer */
88102f3f
KY
7841 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7842 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7843 /* CLFE mixer */
88102f3f
KY
7844 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7845 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 7846 /* Side mixer */
88102f3f
KY
7847 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7848 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
7849
7850 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 7851 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
7852 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7853 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7854 /* Front Pin: output 0 (0x0c) */
7855 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7856 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7857 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7858 /* Rear Pin: output 1 (0x0d) */
7859 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7860 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7861 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
7862 /* CLFE Pin: output 2 (0x0e) */
7863 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7864 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7865 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7866 /* Side Pin: output 3 (0x0f) */
7867 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7868 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7869 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7870 /* Mic (rear) pin: input vref at 80% */
7871 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7872 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7873 /* Front Mic pin: input vref at 80% */
7874 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7875 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7876 /* Line In pin: input */
7877 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7878 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7879
7880 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7881 /* Input mixer1 */
88102f3f 7882 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
7883 /* Input mixer2 */
7884 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 7885 /* Input mixer3 */
88102f3f 7886 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
7887 /* ADC2: mute amp left and right */
7888 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7889 /* ADC3: mute amp left and right */
7890 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7891
7892 { }
7893};
7894
7895static struct hda_verb alc885_init_input_verbs[] = {
7896 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7897 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7898 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7899 { }
7900};
7901
7902
7903/* Unmute Selector 24h and set the default input to front mic */
7904static struct hda_verb alc889_init_input_verbs[] = {
7905 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7906 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7907 { }
7908};
7909
7910
4953550a
TI
7911#define alc883_init_verbs alc882_base_init_verbs
7912
9102cd1c
TD
7913/* Mac Pro test */
7914static struct snd_kcontrol_new alc882_macpro_mixer[] = {
7915 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7916 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7917 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
7918 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7919 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 7920 /* FIXME: this looks suspicious...
d355c82a
JK
7921 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
7922 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 7923 */
9102cd1c
TD
7924 { } /* end */
7925};
7926
7927static struct hda_verb alc882_macpro_init_verbs[] = {
7928 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7929 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7930 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7931 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7932 /* Front Pin: output 0 (0x0c) */
7933 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7934 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7935 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7936 /* Front Mic pin: input vref at 80% */
7937 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7938 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7939 /* Speaker: output */
7940 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7941 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7942 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
7943 /* Headphone output (output 0 - 0x0c) */
7944 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7945 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7946 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7947
7948 /* FIXME: use matrix-type input source selection */
7949 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7950 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7951 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7952 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7953 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7954 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7955 /* Input mixer2 */
7956 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7957 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7958 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7959 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7960 /* Input mixer3 */
7961 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7962 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7963 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7964 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7965 /* ADC1: mute amp left and right */
7966 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7967 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7968 /* ADC2: mute amp left and right */
7969 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7970 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7971 /* ADC3: mute amp left and right */
7972 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7973 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7974
7975 { }
7976};
f12ab1e0 7977
41d5545d
KS
7978/* Macbook 5,1 */
7979static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
7980 /* DACs */
7981 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7982 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7983 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7984 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 7985 /* Front mixer */
41d5545d
KS
7986 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7987 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7988 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
7989 /* Surround mixer */
7990 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7991 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7992 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7993 /* LFE mixer */
7994 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7995 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7996 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7997 /* HP mixer */
7998 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7999 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8000 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8001 /* Front Pin (0x0c) */
41d5545d
KS
8002 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8003 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8004 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8005 /* LFE Pin (0x0e) */
8006 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8007 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8008 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8009 /* HP Pin (0x0f) */
41d5545d
KS
8010 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8011 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8012 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8013 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8014 /* Front Mic pin: input vref at 80% */
8015 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8016 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8017 /* Line In pin */
8018 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8019 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8020
b8f171e7
AM
8021 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8022 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8023 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8024 { }
8025};
8026
e458b1fa
LY
8027/* Macmini 3,1 */
8028static struct hda_verb alc885_macmini3_init_verbs[] = {
8029 /* DACs */
8030 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8031 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8032 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8033 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8034 /* Front mixer */
8035 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8036 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8037 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8038 /* Surround mixer */
8039 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8040 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8041 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8042 /* LFE mixer */
8043 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8044 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8045 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8046 /* HP mixer */
8047 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8048 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8049 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8050 /* Front Pin (0x0c) */
8051 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8052 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8053 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8054 /* LFE Pin (0x0e) */
8055 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8056 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8057 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8058 /* HP Pin (0x0f) */
8059 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8060 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8061 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8062 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8063 /* Line In pin */
8064 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8065 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8066
8067 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8068 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8069 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8070 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8071 { }
8072};
8073
76e6f5a9
RH
8074
8075static struct hda_verb alc885_mba21_init_verbs[] = {
8076 /*Internal and HP Speaker Mixer*/
8077 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8078 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8079 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8080 /*Internal Speaker Pin (0x0c)*/
8081 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8082 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8083 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8084 /* HP Pin: output 0 (0x0e) */
8085 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8086 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8087 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8088 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8089 /* Line in (is hp when jack connected)*/
8090 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8091 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8092
8093 { }
8094 };
8095
8096
87350ad0
TI
8097/* Macbook Pro rev3 */
8098static struct hda_verb alc885_mbp3_init_verbs[] = {
8099 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8100 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8101 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8102 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8103 /* Rear mixer */
8104 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8105 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8106 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8107 /* HP mixer */
8108 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8109 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8110 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8111 /* Front Pin: output 0 (0x0c) */
8112 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8113 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8114 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8115 /* HP Pin: output 0 (0x0e) */
87350ad0 8116 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8117 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8118 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8119 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8120 /* Mic (rear) pin: input vref at 80% */
8121 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8122 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8123 /* Front Mic pin: input vref at 80% */
8124 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8125 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8126 /* Line In pin: use output 1 when in LineOut mode */
8127 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8128 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8129 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8130
8131 /* FIXME: use matrix-type input source selection */
8132 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8133 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8134 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8135 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8136 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8137 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8138 /* Input mixer2 */
8139 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8140 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8141 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8142 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8143 /* Input mixer3 */
8144 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8145 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8146 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8147 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8148 /* ADC1: mute amp left and right */
8149 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8150 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8151 /* ADC2: mute amp left and right */
8152 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8153 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8154 /* ADC3: mute amp left and right */
8155 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8156 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8157
8158 { }
8159};
8160
4b7e1803
JM
8161/* iMac 9,1 */
8162static struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8163 /* Internal Speaker Pin (0x0c) */
8164 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8165 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8166 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8167 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8168 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8169 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8170 /* HP Pin: Rear */
4b7e1803
JM
8171 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8172 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8173 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8174 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8175 /* Line in Rear */
8176 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8177 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8178 /* Front Mic pin: input vref at 80% */
8179 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8180 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8181 /* Rear mixer */
8182 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8183 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8184 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8185 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8186 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8187 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8188 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8189 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8190 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8191 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8192 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8193 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8194 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8195 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8196 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8197 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8198 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8199 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8200 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8201 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8202 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8203 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8204 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8205 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8206 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8207 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8208 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8209 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8210 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8211 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8212 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8213 { }
8214};
8215
c54728d8
NF
8216/* iMac 24 mixer. */
8217static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8218 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8219 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8220 { } /* end */
8221};
8222
8223/* iMac 24 init verbs. */
8224static struct hda_verb alc885_imac24_init_verbs[] = {
8225 /* Internal speakers: output 0 (0x0c) */
8226 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8227 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8228 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8229 /* Internal speakers: output 0 (0x0c) */
8230 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8231 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8232 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8233 /* Headphone: output 0 (0x0c) */
8234 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8235 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8236 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8237 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8238 /* Front Mic: input vref at 80% */
8239 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8240 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8241 { }
8242};
8243
8244/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8245static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8246{
a9fd4f3f 8247 struct alc_spec *spec = codec->spec;
c54728d8 8248
a9fd4f3f
TI
8249 spec->autocfg.hp_pins[0] = 0x14;
8250 spec->autocfg.speaker_pins[0] = 0x18;
8251 spec->autocfg.speaker_pins[1] = 0x1a;
c54728d8
NF
8252}
8253
9d54f08b
TI
8254#define alc885_mb5_setup alc885_imac24_setup
8255#define alc885_macmini3_setup alc885_imac24_setup
8256
76e6f5a9
RH
8257/* Macbook Air 2,1 */
8258static void alc885_mba21_setup(struct hda_codec *codec)
8259{
8260 struct alc_spec *spec = codec->spec;
8261
8262 spec->autocfg.hp_pins[0] = 0x14;
8263 spec->autocfg.speaker_pins[0] = 0x18;
8264}
8265
8266
8267
4f5d1706 8268static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8269{
a9fd4f3f 8270 struct alc_spec *spec = codec->spec;
87350ad0 8271
a9fd4f3f
TI
8272 spec->autocfg.hp_pins[0] = 0x15;
8273 spec->autocfg.speaker_pins[0] = 0x14;
87350ad0
TI
8274}
8275
9d54f08b 8276static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8277{
9d54f08b 8278 struct alc_spec *spec = codec->spec;
4b7e1803 8279
9d54f08b 8280 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8281 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8282 spec->autocfg.speaker_pins[1] = 0x1a;
4b7e1803 8283}
87350ad0 8284
272a527c
KY
8285static struct hda_verb alc882_targa_verbs[] = {
8286 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8287 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8288
8289 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8290 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8291
272a527c
KY
8292 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8293 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8294 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8295
8296 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8297 { } /* end */
8298};
8299
8300/* toggle speaker-output according to the hp-jack state */
8301static void alc882_targa_automute(struct hda_codec *codec)
8302{
a9fd4f3f
TI
8303 struct alc_spec *spec = codec->spec;
8304 alc_automute_amp(codec);
82beb8fd 8305 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8306 spec->jack_present ? 1 : 3);
8307}
8308
4f5d1706 8309static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8310{
8311 struct alc_spec *spec = codec->spec;
8312
8313 spec->autocfg.hp_pins[0] = 0x14;
8314 spec->autocfg.speaker_pins[0] = 0x1b;
272a527c
KY
8315}
8316
8317static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8318{
a9fd4f3f 8319 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8320 alc882_targa_automute(codec);
272a527c
KY
8321}
8322
8323static struct hda_verb alc882_asus_a7j_verbs[] = {
8324 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8325 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8326
8327 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8328 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8329 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8330
272a527c
KY
8331 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8332 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8333 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8334
8335 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8336 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8337 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8338 { } /* end */
8339};
8340
914759b7
TI
8341static struct hda_verb alc882_asus_a7m_verbs[] = {
8342 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8343 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8344
8345 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8346 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8347 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8348
914759b7
TI
8349 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8350 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8351 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8352
8353 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8354 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8355 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8356 { } /* end */
8357};
8358
9102cd1c
TD
8359static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8360{
8361 unsigned int gpiostate, gpiomask, gpiodir;
8362
8363 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8364 AC_VERB_GET_GPIO_DATA, 0);
8365
8366 if (!muted)
8367 gpiostate |= (1 << pin);
8368 else
8369 gpiostate &= ~(1 << pin);
8370
8371 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8372 AC_VERB_GET_GPIO_MASK, 0);
8373 gpiomask |= (1 << pin);
8374
8375 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8376 AC_VERB_GET_GPIO_DIRECTION, 0);
8377 gpiodir |= (1 << pin);
8378
8379
8380 snd_hda_codec_write(codec, codec->afg, 0,
8381 AC_VERB_SET_GPIO_MASK, gpiomask);
8382 snd_hda_codec_write(codec, codec->afg, 0,
8383 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8384
8385 msleep(1);
8386
8387 snd_hda_codec_write(codec, codec->afg, 0,
8388 AC_VERB_SET_GPIO_DATA, gpiostate);
8389}
8390
7debbe51
TI
8391/* set up GPIO at initialization */
8392static void alc885_macpro_init_hook(struct hda_codec *codec)
8393{
8394 alc882_gpio_mute(codec, 0, 0);
8395 alc882_gpio_mute(codec, 1, 0);
8396}
8397
8398/* set up GPIO and update auto-muting at initialization */
8399static void alc885_imac24_init_hook(struct hda_codec *codec)
8400{
8401 alc885_macpro_init_hook(codec);
4f5d1706 8402 alc_automute_amp(codec);
7debbe51
TI
8403}
8404
df694daa
KY
8405/*
8406 * generic initialization of ADC, input mixers and output mixers
8407 */
4953550a 8408static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8409 /*
8410 * Unmute ADC0-2 and set the default input to mic-in
8411 */
4953550a
TI
8412 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8413 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8414 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8415 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 8416
4953550a
TI
8417 /*
8418 * Set up output mixers (0x0c - 0x0f)
8419 */
8420 /* set vol=0 to output mixers */
8421 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8422 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8423 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8424 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8425 /* set up input amps for analog loopback */
8426 /* Amp Indices: DAC = 0, mixer = 1 */
8427 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8428 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8429 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8430 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8431 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8432 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8433 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8434 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8435 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8436 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 8437
4953550a
TI
8438 /* FIXME: use matrix-type input source selection */
8439 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8440 /* Input mixer2 */
88102f3f 8441 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8442 /* Input mixer3 */
88102f3f 8443 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 8444 { }
9c7f852e
TI
8445};
8446
eb4c41d3
TS
8447/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8448static struct hda_verb alc889A_mb31_ch2_init[] = {
8449 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8450 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8451 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8452 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8453 { } /* end */
8454};
8455
8456/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8457static struct hda_verb alc889A_mb31_ch4_init[] = {
8458 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8459 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8460 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8461 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8462 { } /* end */
8463};
8464
8465/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8466static struct hda_verb alc889A_mb31_ch5_init[] = {
8467 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8468 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8469 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8470 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8471 { } /* end */
8472};
8473
8474/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8475static struct hda_verb alc889A_mb31_ch6_init[] = {
8476 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8477 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8478 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8479 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8480 { } /* end */
8481};
8482
8483static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8484 { 2, alc889A_mb31_ch2_init },
8485 { 4, alc889A_mb31_ch4_init },
8486 { 5, alc889A_mb31_ch5_init },
8487 { 6, alc889A_mb31_ch6_init },
8488};
8489
b373bdeb
AN
8490static struct hda_verb alc883_medion_eapd_verbs[] = {
8491 /* eanable EAPD on medion laptop */
8492 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8493 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8494 { }
8495};
8496
4953550a 8497#define alc883_base_mixer alc882_base_mixer
834be88d 8498
a8848bd6
AS
8499static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8500 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8501 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8502 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8503 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8504 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8505 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8506 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8507 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8508 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8509 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8510 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8511 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8512 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8513 { } /* end */
8514};
8515
0c4cc443 8516static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8517 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8518 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8519 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8520 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8521 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8522 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8523 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8524 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8525 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8526 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8527 { } /* end */
8528};
8529
fb97dc67
J
8530static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8531 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8532 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8533 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8534 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8535 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8536 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8537 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8538 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8539 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8540 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8541 { } /* end */
8542};
8543
9c7f852e
TI
8544static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8545 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8546 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8547 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8548 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8549 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8550 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8551 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8552 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8553 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8554 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8555 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8556 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8557 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8558 { } /* end */
8559};
df694daa 8560
9c7f852e
TI
8561static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8562 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8563 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8564 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8565 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8566 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8567 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8568 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8569 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8570 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8571 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8572 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8573 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8574 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8575 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8576 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8577 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8578 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8579 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8580 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8581 { } /* end */
8582};
8583
17bba1b7
J
8584static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8585 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8586 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8587 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8588 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8589 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8590 HDA_OUTPUT),
8591 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8592 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8593 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8594 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8595 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8596 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8597 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8598 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8599 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8600 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8601 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8602 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8603 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8604 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
8605 { } /* end */
8606};
8607
87a8c370
JK
8608static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8609 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8610 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8611 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8612 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8613 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8614 HDA_OUTPUT),
8615 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8616 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8617 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8618 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8619 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8620 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8621 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8622 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8623 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8624 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
8625 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8626 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8627 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8628 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8629 { } /* end */
8630};
8631
d1d985f0 8632static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 8633 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 8634 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 8635 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 8636 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
8637 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8638 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
8639 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8640 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
8641 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8642 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8643 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8644 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8645 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8646 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8647 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
8648 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8649 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 8650 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8 8651 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
8652 { } /* end */
8653};
8654
c259249f 8655static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 8656 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8657 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8658 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8659 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8660 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8661 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8662 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8663 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8664 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8665 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8666 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8667 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8668 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8669 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8670 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8671 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8672 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 8673 { } /* end */
f12ab1e0 8674};
ccc656ce 8675
c259249f 8676static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 8677 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 8678 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 8679 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 8680 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
8681 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8682 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8683 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 8684 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 8685 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
8686 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8687 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8688 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 8689 { } /* end */
f12ab1e0 8690};
ccc656ce 8691
b99dba34
TI
8692static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8693 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8694 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8695 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8696 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8697 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8698 { } /* end */
8699};
8700
bc9f98a9
KY
8701static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8702 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8703 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
8704 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8705 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
8706 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8708 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8709 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 8710 { } /* end */
f12ab1e0 8711};
bc9f98a9 8712
272a527c
KY
8713static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8714 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8715 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8716 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8717 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8718 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8719 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8720 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
150b432f
DH
8721 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8722 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
8723 { } /* end */
8724};
8725
8726static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8727 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8728 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8729 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8730 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8731 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8732 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8733 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8734 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8735 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
272a527c 8736 { } /* end */
ea1fb29a 8737};
272a527c 8738
7ad7b218
MC
8739static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
8740 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8741 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8742 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8743 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
8744 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
8745 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
8746 { } /* end */
8747};
8748
8749static struct hda_verb alc883_medion_wim2160_verbs[] = {
8750 /* Unmute front mixer */
8751 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8752 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8753
8754 /* Set speaker pin to front mixer */
8755 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8756
8757 /* Init headphone pin */
8758 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8759 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8760 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8761 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8762
8763 { } /* end */
8764};
8765
8766/* toggle speaker-output according to the hp-jack state */
8767static void alc883_medion_wim2160_setup(struct hda_codec *codec)
8768{
8769 struct alc_spec *spec = codec->spec;
8770
8771 spec->autocfg.hp_pins[0] = 0x1a;
8772 spec->autocfg.speaker_pins[0] = 0x15;
8773}
8774
2880a867 8775static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
8776 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8777 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 8778 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
8779 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8780 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
8781 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8782 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8783 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 8784 { } /* end */
d1a991a6 8785};
2880a867 8786
d2fd4b09
TV
8787static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8788 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 8789 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
8790 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8791 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
8792 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8793 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8794 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8795 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8796 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8797 { } /* end */
8798};
8799
e2757d5e
KY
8800static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8801 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8802 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8803 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8804 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8805 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8806 0x0d, 1, 0x0, HDA_OUTPUT),
8807 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8808 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8809 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8810 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8811 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
8812 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8813 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8814 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8815 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8816 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8817 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8818 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8819 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8820 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8821 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
8822 { } /* end */
8823};
8824
eb4c41d3
TS
8825static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8826 /* Output mixers */
8827 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8828 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8829 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8830 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8831 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8832 HDA_OUTPUT),
8833 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8834 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8835 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8836 /* Output switches */
8837 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8838 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8839 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8840 /* Boost mixers */
8841 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8842 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8843 /* Input mixers */
8844 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8845 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8846 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8847 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8848 { } /* end */
8849};
8850
3e1647c5
GG
8851static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8852 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8853 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8854 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8855 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8856 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8857 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8858 { } /* end */
8859};
8860
e2757d5e
KY
8861static struct hda_bind_ctls alc883_bind_cap_vol = {
8862 .ops = &snd_hda_bind_vol,
8863 .values = {
8864 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8865 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8866 0
8867 },
8868};
8869
8870static struct hda_bind_ctls alc883_bind_cap_switch = {
8871 .ops = &snd_hda_bind_sw,
8872 .values = {
8873 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8874 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8875 0
8876 },
8877};
8878
8879static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8880 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8881 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8882 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8883 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8884 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8885 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4953550a
TI
8886 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8887 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8888 { } /* end */
8889};
df694daa 8890
4953550a
TI
8891static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8892 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8893 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8894 {
8895 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8896 /* .name = "Capture Source", */
8897 .name = "Input Source",
8898 .count = 1,
8899 .info = alc_mux_enum_info,
8900 .get = alc_mux_enum_get,
8901 .put = alc_mux_enum_put,
8902 },
8903 { } /* end */
8904};
9c7f852e 8905
4953550a
TI
8906static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8907 {
8908 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8909 .name = "Channel Mode",
8910 .info = alc_ch_mode_info,
8911 .get = alc_ch_mode_get,
8912 .put = alc_ch_mode_put,
8913 },
8914 { } /* end */
9c7f852e
TI
8915};
8916
a8848bd6 8917/* toggle speaker-output according to the hp-jack state */
4f5d1706 8918static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 8919{
a9fd4f3f 8920 struct alc_spec *spec = codec->spec;
a8848bd6 8921
a9fd4f3f
TI
8922 spec->autocfg.hp_pins[0] = 0x15;
8923 spec->autocfg.speaker_pins[0] = 0x14;
8924 spec->autocfg.speaker_pins[1] = 0x17;
a8848bd6
AS
8925}
8926
8927/* auto-toggle front mic */
8928/*
8929static void alc883_mitac_mic_automute(struct hda_codec *codec)
8930{
864f92be 8931 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
a8848bd6 8932
a8848bd6
AS
8933 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8934}
8935*/
8936
a8848bd6
AS
8937static struct hda_verb alc883_mitac_verbs[] = {
8938 /* HP */
8939 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8940 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8941 /* Subwoofer */
8942 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8943 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8944
8945 /* enable unsolicited event */
8946 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8947 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8948
8949 { } /* end */
8950};
8951
a65cc60f 8952static struct hda_verb alc883_clevo_m540r_verbs[] = {
8953 /* HP */
8954 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8955 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8956 /* Int speaker */
8957 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
8958
8959 /* enable unsolicited event */
8960 /*
8961 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8962 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8963 */
8964
8965 { } /* end */
8966};
8967
0c4cc443 8968static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
8969 /* HP */
8970 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8971 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8972 /* Int speaker */
8973 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8974 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8975
8976 /* enable unsolicited event */
8977 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 8978 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
8979
8980 { } /* end */
8981};
8982
fb97dc67
J
8983static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8984 /* HP */
8985 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8986 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8987 /* Subwoofer */
8988 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8989 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8990
8991 /* enable unsolicited event */
8992 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8993
8994 { } /* end */
8995};
8996
c259249f 8997static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
8998 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8999 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9000
9001 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9002 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9003
64a8be74
DH
9004/* Connect Line-Out side jack (SPDIF) to Side */
9005 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9006 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9007 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9008/* Connect Mic jack to CLFE */
9009 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9010 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9011 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9012/* Connect Line-in jack to Surround */
9013 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9014 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9015 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9016/* Connect HP out jack to Front */
9017 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9018 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9019 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9020
9021 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9022
9023 { } /* end */
9024};
9025
bc9f98a9
KY
9026static struct hda_verb alc883_lenovo_101e_verbs[] = {
9027 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9028 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9029 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9030 { } /* end */
9031};
9032
272a527c
KY
9033static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9034 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9035 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9036 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9037 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9038 { } /* end */
9039};
9040
9041static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9042 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9043 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9044 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9045 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9046 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9047 { } /* end */
9048};
9049
189609ae
KY
9050static struct hda_verb alc883_haier_w66_verbs[] = {
9051 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9052 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9053
9054 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9055
9056 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9057 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9058 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9059 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9060 { } /* end */
9061};
9062
e2757d5e
KY
9063static struct hda_verb alc888_lenovo_sky_verbs[] = {
9064 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9065 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9066 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9067 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9068 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9069 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9070 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9071 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9072 { } /* end */
9073};
9074
8718b700
HRK
9075static struct hda_verb alc888_6st_dell_verbs[] = {
9076 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9077 { }
9078};
9079
3e1647c5
GG
9080static struct hda_verb alc883_vaiott_verbs[] = {
9081 /* HP */
9082 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9083 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9084
9085 /* enable unsolicited event */
9086 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9087
9088 { } /* end */
9089};
9090
4f5d1706 9091static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9092{
a9fd4f3f 9093 struct alc_spec *spec = codec->spec;
8718b700 9094
a9fd4f3f
TI
9095 spec->autocfg.hp_pins[0] = 0x1b;
9096 spec->autocfg.speaker_pins[0] = 0x14;
9097 spec->autocfg.speaker_pins[1] = 0x16;
9098 spec->autocfg.speaker_pins[2] = 0x18;
8718b700
HRK
9099}
9100
4723c022 9101static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9102 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9103 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9104 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9105 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9106 { } /* end */
5795b9e6
CM
9107};
9108
3ea0d7cf
HRK
9109/*
9110 * 2ch mode
9111 */
4723c022 9112static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9113 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9114 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9115 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9116 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9117 { } /* end */
8341de60
CM
9118};
9119
3ea0d7cf
HRK
9120/*
9121 * 4ch mode
9122 */
9123static struct hda_verb alc888_3st_hp_4ch_init[] = {
9124 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9125 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9126 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9127 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9128 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9129 { } /* end */
9130};
9131
9132/*
9133 * 6ch mode
9134 */
4723c022 9135static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9136 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9137 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9138 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9139 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9140 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9141 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9142 { } /* end */
8341de60
CM
9143};
9144
3ea0d7cf 9145static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9146 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9147 { 4, alc888_3st_hp_4ch_init },
4723c022 9148 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9149};
9150
272a527c
KY
9151/* toggle front-jack and RCA according to the hp-jack state */
9152static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9153{
864f92be 9154 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
ea1fb29a 9155
47fd830a
TI
9156 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9157 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9158 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9159 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
9160}
9161
9162/* toggle RCA according to the front-jack state */
9163static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9164{
864f92be 9165 unsigned int present = snd_hda_jack_detect(codec, 0x14);
ea1fb29a 9166
47fd830a
TI
9167 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9168 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 9169}
47fd830a 9170
272a527c
KY
9171static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9172 unsigned int res)
9173{
9174 if ((res >> 26) == ALC880_HP_EVENT)
9175 alc888_lenovo_ms7195_front_automute(codec);
9176 if ((res >> 26) == ALC880_FRONT_EVENT)
9177 alc888_lenovo_ms7195_rca_automute(codec);
9178}
9179
9180static struct hda_verb alc883_medion_md2_verbs[] = {
9181 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9182 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9183
9184 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9185
9186 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9187 { } /* end */
9188};
9189
9190/* toggle speaker-output according to the hp-jack state */
4f5d1706 9191static void alc883_medion_md2_setup(struct hda_codec *codec)
272a527c 9192{
a9fd4f3f 9193 struct alc_spec *spec = codec->spec;
272a527c 9194
a9fd4f3f
TI
9195 spec->autocfg.hp_pins[0] = 0x14;
9196 spec->autocfg.speaker_pins[0] = 0x15;
272a527c
KY
9197}
9198
ccc656ce 9199/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9200#define alc883_targa_init_hook alc882_targa_init_hook
9201#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9202
0c4cc443
HRK
9203static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
9204{
9205 unsigned int present;
9206
d56757ab 9207 present = snd_hda_jack_detect(codec, 0x18);
0c4cc443
HRK
9208 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
9209 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9210}
9211
4f5d1706 9212static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9213{
a9fd4f3f
TI
9214 struct alc_spec *spec = codec->spec;
9215
9216 spec->autocfg.hp_pins[0] = 0x15;
9217 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
9218}
9219
9220static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9221{
a9fd4f3f 9222 alc_automute_amp(codec);
0c4cc443
HRK
9223 alc883_clevo_m720_mic_automute(codec);
9224}
9225
9226static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9227 unsigned int res)
9228{
0c4cc443 9229 switch (res >> 26) {
0c4cc443
HRK
9230 case ALC880_MIC_EVENT:
9231 alc883_clevo_m720_mic_automute(codec);
9232 break;
a9fd4f3f
TI
9233 default:
9234 alc_automute_amp_unsol_event(codec, res);
9235 break;
0c4cc443 9236 }
368c7a95
J
9237}
9238
fb97dc67 9239/* toggle speaker-output according to the hp-jack state */
4f5d1706 9240static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9241{
a9fd4f3f 9242 struct alc_spec *spec = codec->spec;
fb97dc67 9243
a9fd4f3f
TI
9244 spec->autocfg.hp_pins[0] = 0x14;
9245 spec->autocfg.speaker_pins[0] = 0x15;
fb97dc67
J
9246}
9247
4f5d1706 9248static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9249{
a9fd4f3f 9250 struct alc_spec *spec = codec->spec;
189609ae 9251
a9fd4f3f
TI
9252 spec->autocfg.hp_pins[0] = 0x1b;
9253 spec->autocfg.speaker_pins[0] = 0x14;
189609ae
KY
9254}
9255
bc9f98a9
KY
9256static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9257{
864f92be 9258 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
bc9f98a9 9259
47fd830a
TI
9260 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9261 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9262}
9263
9264static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9265{
864f92be 9266 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
bc9f98a9 9267
47fd830a
TI
9268 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9269 HDA_AMP_MUTE, bits);
9270 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9271 HDA_AMP_MUTE, bits);
bc9f98a9
KY
9272}
9273
9274static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9275 unsigned int res)
9276{
9277 if ((res >> 26) == ALC880_HP_EVENT)
9278 alc883_lenovo_101e_all_automute(codec);
9279 if ((res >> 26) == ALC880_FRONT_EVENT)
9280 alc883_lenovo_101e_ispeaker_automute(codec);
9281}
9282
676a9b53 9283/* toggle speaker-output according to the hp-jack state */
4f5d1706 9284static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9285{
a9fd4f3f 9286 struct alc_spec *spec = codec->spec;
676a9b53 9287
a9fd4f3f
TI
9288 spec->autocfg.hp_pins[0] = 0x14;
9289 spec->autocfg.speaker_pins[0] = 0x15;
9290 spec->autocfg.speaker_pins[1] = 0x16;
676a9b53
TI
9291}
9292
d1a991a6
KY
9293static struct hda_verb alc883_acer_eapd_verbs[] = {
9294 /* HP Pin: output 0 (0x0c) */
9295 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9296 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9297 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9298 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9299 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9300 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9301 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9302 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9303 /* eanable EAPD on medion laptop */
9304 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9305 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9306 /* enable unsolicited event */
9307 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9308 { }
9309};
9310
fc86f954
DK
9311static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
9312 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9313 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9314 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9315 { } /* end */
9316};
9317
4f5d1706 9318static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9319{
a9fd4f3f 9320 struct alc_spec *spec = codec->spec;
5795b9e6 9321
a9fd4f3f
TI
9322 spec->autocfg.hp_pins[0] = 0x1b;
9323 spec->autocfg.speaker_pins[0] = 0x14;
9324 spec->autocfg.speaker_pins[1] = 0x15;
9325 spec->autocfg.speaker_pins[2] = 0x16;
9326 spec->autocfg.speaker_pins[3] = 0x17;
5795b9e6
CM
9327}
9328
4f5d1706 9329static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9330{
a9fd4f3f 9331 struct alc_spec *spec = codec->spec;
e2757d5e 9332
a9fd4f3f
TI
9333 spec->autocfg.hp_pins[0] = 0x1b;
9334 spec->autocfg.speaker_pins[0] = 0x14;
9335 spec->autocfg.speaker_pins[1] = 0x15;
9336 spec->autocfg.speaker_pins[2] = 0x16;
9337 spec->autocfg.speaker_pins[3] = 0x17;
9338 spec->autocfg.speaker_pins[4] = 0x1a;
e2757d5e
KY
9339}
9340
4f5d1706 9341static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9342{
9343 struct alc_spec *spec = codec->spec;
9344
9345 spec->autocfg.hp_pins[0] = 0x15;
9346 spec->autocfg.speaker_pins[0] = 0x14;
9347 spec->autocfg.speaker_pins[1] = 0x17;
3e1647c5
GG
9348}
9349
e2757d5e
KY
9350static struct hda_verb alc888_asus_m90v_verbs[] = {
9351 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9352 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9353 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9354 /* enable unsolicited event */
9355 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9356 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9357 { } /* end */
9358};
9359
4f5d1706 9360static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9361{
a9fd4f3f 9362 struct alc_spec *spec = codec->spec;
e2757d5e 9363
a9fd4f3f
TI
9364 spec->autocfg.hp_pins[0] = 0x1b;
9365 spec->autocfg.speaker_pins[0] = 0x14;
9366 spec->autocfg.speaker_pins[1] = 0x15;
9367 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9368 spec->ext_mic.pin = 0x18;
9369 spec->int_mic.pin = 0x19;
9370 spec->ext_mic.mux_idx = 0;
9371 spec->int_mic.mux_idx = 1;
9372 spec->auto_mic = 1;
e2757d5e
KY
9373}
9374
9375static struct hda_verb alc888_asus_eee1601_verbs[] = {
9376 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9377 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9378 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9379 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9380 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9381 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9382 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9383 /* enable unsolicited event */
9384 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9385 { } /* end */
9386};
9387
e2757d5e
KY
9388static void alc883_eee1601_inithook(struct hda_codec *codec)
9389{
a9fd4f3f
TI
9390 struct alc_spec *spec = codec->spec;
9391
9392 spec->autocfg.hp_pins[0] = 0x14;
9393 spec->autocfg.speaker_pins[0] = 0x1b;
9394 alc_automute_pin(codec);
e2757d5e
KY
9395}
9396
eb4c41d3
TS
9397static struct hda_verb alc889A_mb31_verbs[] = {
9398 /* Init rear pin (used as headphone output) */
9399 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9400 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9401 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9402 /* Init line pin (used as output in 4ch and 6ch mode) */
9403 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9404 /* Init line 2 pin (used as headphone out by default) */
9405 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9406 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9407 { } /* end */
9408};
9409
9410/* Mute speakers according to the headphone jack state */
9411static void alc889A_mb31_automute(struct hda_codec *codec)
9412{
9413 unsigned int present;
9414
9415 /* Mute only in 2ch or 4ch mode */
9416 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9417 == 0x00) {
864f92be 9418 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9419 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9420 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9421 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9422 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9423 }
9424}
9425
9426static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9427{
9428 if ((res >> 26) == ALC880_HP_EVENT)
9429 alc889A_mb31_automute(codec);
9430}
9431
4953550a 9432
cb53c626 9433#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9434#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9435#endif
9436
def319f9 9437/* pcm configuration: identical with ALC880 */
4953550a
TI
9438#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9439#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9440#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9441#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9442
9443static hda_nid_t alc883_slave_dig_outs[] = {
9444 ALC1200_DIGOUT_NID, 0,
9445};
9446
9447static hda_nid_t alc1200_slave_dig_outs[] = {
9448 ALC883_DIGOUT_NID, 0,
9449};
9c7f852e
TI
9450
9451/*
9452 * configuration and preset
9453 */
4953550a
TI
9454static const char *alc882_models[ALC882_MODEL_LAST] = {
9455 [ALC882_3ST_DIG] = "3stack-dig",
9456 [ALC882_6ST_DIG] = "6stack-dig",
9457 [ALC882_ARIMA] = "arima",
9458 [ALC882_W2JC] = "w2jc",
9459 [ALC882_TARGA] = "targa",
9460 [ALC882_ASUS_A7J] = "asus-a7j",
9461 [ALC882_ASUS_A7M] = "asus-a7m",
9462 [ALC885_MACPRO] = "macpro",
9463 [ALC885_MB5] = "mb5",
e458b1fa 9464 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9465 [ALC885_MBA21] = "mba21",
4953550a
TI
9466 [ALC885_MBP3] = "mbp3",
9467 [ALC885_IMAC24] = "imac24",
4b7e1803 9468 [ALC885_IMAC91] = "imac91",
4953550a 9469 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9470 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9471 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9472 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9473 [ALC883_TARGA_DIG] = "targa-dig",
9474 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9475 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9476 [ALC883_ACER] = "acer",
2880a867 9477 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9478 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9479 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9480 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9481 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9482 [ALC883_MEDION] = "medion",
272a527c 9483 [ALC883_MEDION_MD2] = "medion-md2",
7ad7b218 9484 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9485 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9486 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9487 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9488 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9489 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9490 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9491 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9492 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9493 [ALC883_MITAC] = "mitac",
a65cc60f 9494 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9495 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9496 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9497 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9498 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9499 [ALC889A_INTEL] = "intel-alc889a",
9500 [ALC889_INTEL] = "intel-x58",
3ab90935 9501 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9502 [ALC889A_MB31] = "mb31",
3e1647c5 9503 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9504 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9505};
9506
4953550a
TI
9507static struct snd_pci_quirk alc882_cfg_tbl[] = {
9508 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9509
ac3e3741 9510 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9511 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9512 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9513 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9514 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9515 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9516 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9517 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9518 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9519 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9520 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9521 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9522 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9523 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9524 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9525 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9526 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9527 ALC888_ACER_ASPIRE_6530G),
cc374c47 9528 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9529 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9530 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9531 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9532 /* default Acer -- disabled as it causes more problems.
9533 * model=auto should work fine now
9534 */
9535 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9536
5795b9e6 9537 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9538
febe3375 9539 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
9540 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9541 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9542 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9543 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9544 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9545
9546 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9547 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9548 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9549 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9550 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9551 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9552 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9553 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9554 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9555 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9556 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9557
9558 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9559 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9560 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9561 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9562 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9563 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9564 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9565 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
9566 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9567
6f3bf657 9568 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9569 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9570 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9571 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9572 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9573 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9574 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9575 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9576 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9577 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9578 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9579 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9580 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9581 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9582 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9583 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9584 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9585 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9586 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9587 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9588 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9589 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9590 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9591 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9592 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9593 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9594 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9595 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9596 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9597 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9598 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9599
ac3e3741 9600 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9601 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9602 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9603 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9604 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9605 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9606 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9607 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9608 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9609 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9610 ALC883_FUJITSU_PI2515),
bfb53037 9611 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9612 ALC888_FUJITSU_XA3530),
272a527c 9613 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9614 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9615 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9616 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9617 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
272a527c 9618 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
959973b9 9619 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9620 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9621 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9622
17bba1b7
J
9623 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9624 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9625 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9626 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9627 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9628 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9629 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9630
4953550a 9631 {}
f3cd3f5d
WF
9632};
9633
4953550a
TI
9634/* codec SSID table for Intel Mac */
9635static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9636 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9637 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9638 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9639 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9640 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9641 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9642 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 9643 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 9644 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 9645 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 9646 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
9647 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9648 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9649 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9650 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9651 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 9652 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
9653 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9654 * so apparently no perfect solution yet
4953550a
TI
9655 */
9656 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 9657 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 9658 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 9659 {} /* terminator */
b25c9da1
WF
9660};
9661
4953550a
TI
9662static struct alc_config_preset alc882_presets[] = {
9663 [ALC882_3ST_DIG] = {
9664 .mixers = { alc882_base_mixer },
8ab9e0af
TI
9665 .init_verbs = { alc882_base_init_verbs,
9666 alc882_adc1_init_verbs },
4953550a
TI
9667 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9668 .dac_nids = alc882_dac_nids,
9669 .dig_out_nid = ALC882_DIGOUT_NID,
9670 .dig_in_nid = ALC882_DIGIN_NID,
9671 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9672 .channel_mode = alc882_ch_modes,
9673 .need_dac_fix = 1,
9674 .input_mux = &alc882_capture_source,
9675 },
9676 [ALC882_6ST_DIG] = {
9677 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9678 .init_verbs = { alc882_base_init_verbs,
9679 alc882_adc1_init_verbs },
4953550a
TI
9680 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9681 .dac_nids = alc882_dac_nids,
9682 .dig_out_nid = ALC882_DIGOUT_NID,
9683 .dig_in_nid = ALC882_DIGIN_NID,
9684 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9685 .channel_mode = alc882_sixstack_modes,
9686 .input_mux = &alc882_capture_source,
9687 },
9688 [ALC882_ARIMA] = {
9689 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9690 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9691 alc882_eapd_verbs },
4953550a
TI
9692 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9693 .dac_nids = alc882_dac_nids,
9694 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9695 .channel_mode = alc882_sixstack_modes,
9696 .input_mux = &alc882_capture_source,
9697 },
9698 [ALC882_W2JC] = {
9699 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9700 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9701 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
9702 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9703 .dac_nids = alc882_dac_nids,
9704 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9705 .channel_mode = alc880_threestack_modes,
9706 .need_dac_fix = 1,
9707 .input_mux = &alc882_capture_source,
9708 .dig_out_nid = ALC882_DIGOUT_NID,
9709 },
76e6f5a9
RH
9710 [ALC885_MBA21] = {
9711 .mixers = { alc885_mba21_mixer },
9712 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9713 .num_dacs = 2,
9714 .dac_nids = alc882_dac_nids,
9715 .channel_mode = alc885_mba21_ch_modes,
9716 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9717 .input_mux = &alc882_capture_source,
9718 .unsol_event = alc_automute_amp_unsol_event,
9719 .setup = alc885_mba21_setup,
9720 .init_hook = alc_automute_amp,
9721 },
4953550a
TI
9722 [ALC885_MBP3] = {
9723 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9724 .init_verbs = { alc885_mbp3_init_verbs,
9725 alc880_gpio1_init_verbs },
be0ae923 9726 .num_dacs = 2,
4953550a 9727 .dac_nids = alc882_dac_nids,
be0ae923
TI
9728 .hp_nid = 0x04,
9729 .channel_mode = alc885_mbp_4ch_modes,
9730 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
9731 .input_mux = &alc882_capture_source,
9732 .dig_out_nid = ALC882_DIGOUT_NID,
9733 .dig_in_nid = ALC882_DIGIN_NID,
9734 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
9735 .setup = alc885_mbp3_setup,
9736 .init_hook = alc_automute_amp,
4953550a
TI
9737 },
9738 [ALC885_MB5] = {
9739 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
9740 .init_verbs = { alc885_mb5_init_verbs,
9741 alc880_gpio1_init_verbs },
9742 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9743 .dac_nids = alc882_dac_nids,
9744 .channel_mode = alc885_mb5_6ch_modes,
9745 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
9746 .input_mux = &mb5_capture_source,
9747 .dig_out_nid = ALC882_DIGOUT_NID,
9748 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9749 .unsol_event = alc_automute_amp_unsol_event,
9750 .setup = alc885_mb5_setup,
9751 .init_hook = alc_automute_amp,
4953550a 9752 },
e458b1fa
LY
9753 [ALC885_MACMINI3] = {
9754 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9755 .init_verbs = { alc885_macmini3_init_verbs,
9756 alc880_gpio1_init_verbs },
9757 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9758 .dac_nids = alc882_dac_nids,
9759 .channel_mode = alc885_macmini3_6ch_modes,
9760 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9761 .input_mux = &macmini3_capture_source,
9762 .dig_out_nid = ALC882_DIGOUT_NID,
9763 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9764 .unsol_event = alc_automute_amp_unsol_event,
9765 .setup = alc885_macmini3_setup,
9766 .init_hook = alc_automute_amp,
e458b1fa 9767 },
4953550a
TI
9768 [ALC885_MACPRO] = {
9769 .mixers = { alc882_macpro_mixer },
9770 .init_verbs = { alc882_macpro_init_verbs },
9771 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9772 .dac_nids = alc882_dac_nids,
9773 .dig_out_nid = ALC882_DIGOUT_NID,
9774 .dig_in_nid = ALC882_DIGIN_NID,
9775 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9776 .channel_mode = alc882_ch_modes,
9777 .input_mux = &alc882_capture_source,
9778 .init_hook = alc885_macpro_init_hook,
9779 },
9780 [ALC885_IMAC24] = {
9781 .mixers = { alc885_imac24_mixer },
9782 .init_verbs = { alc885_imac24_init_verbs },
9783 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9784 .dac_nids = alc882_dac_nids,
9785 .dig_out_nid = ALC882_DIGOUT_NID,
9786 .dig_in_nid = ALC882_DIGIN_NID,
9787 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9788 .channel_mode = alc882_ch_modes,
9789 .input_mux = &alc882_capture_source,
9790 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706 9791 .setup = alc885_imac24_setup,
4953550a
TI
9792 .init_hook = alc885_imac24_init_hook,
9793 },
4b7e1803 9794 [ALC885_IMAC91] = {
b7cccc52 9795 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
9796 .init_verbs = { alc885_imac91_init_verbs,
9797 alc880_gpio1_init_verbs },
9798 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9799 .dac_nids = alc882_dac_nids,
b7cccc52
JM
9800 .channel_mode = alc885_mba21_ch_modes,
9801 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9802 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
9803 .dig_out_nid = ALC882_DIGOUT_NID,
9804 .dig_in_nid = ALC882_DIGIN_NID,
9d54f08b
TI
9805 .unsol_event = alc_automute_amp_unsol_event,
9806 .setup = alc885_imac91_setup,
9807 .init_hook = alc_automute_amp,
4b7e1803 9808 },
4953550a
TI
9809 [ALC882_TARGA] = {
9810 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 9811 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 9812 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
9813 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9814 .dac_nids = alc882_dac_nids,
9815 .dig_out_nid = ALC882_DIGOUT_NID,
9816 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9817 .adc_nids = alc882_adc_nids,
9818 .capsrc_nids = alc882_capsrc_nids,
9819 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9820 .channel_mode = alc882_3ST_6ch_modes,
9821 .need_dac_fix = 1,
9822 .input_mux = &alc882_capture_source,
9823 .unsol_event = alc882_targa_unsol_event,
4f5d1706
TI
9824 .setup = alc882_targa_setup,
9825 .init_hook = alc882_targa_automute,
4953550a
TI
9826 },
9827 [ALC882_ASUS_A7J] = {
9828 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9829 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9830 alc882_asus_a7j_verbs},
4953550a
TI
9831 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9832 .dac_nids = alc882_dac_nids,
9833 .dig_out_nid = ALC882_DIGOUT_NID,
9834 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9835 .adc_nids = alc882_adc_nids,
9836 .capsrc_nids = alc882_capsrc_nids,
9837 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9838 .channel_mode = alc882_3ST_6ch_modes,
9839 .need_dac_fix = 1,
9840 .input_mux = &alc882_capture_source,
9841 },
9842 [ALC882_ASUS_A7M] = {
9843 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
9844 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9845 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
9846 alc882_asus_a7m_verbs },
9847 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9848 .dac_nids = alc882_dac_nids,
9849 .dig_out_nid = ALC882_DIGOUT_NID,
9850 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9851 .channel_mode = alc880_threestack_modes,
9852 .need_dac_fix = 1,
9853 .input_mux = &alc882_capture_source,
9854 },
9c7f852e
TI
9855 [ALC883_3ST_2ch_DIG] = {
9856 .mixers = { alc883_3ST_2ch_mixer },
9857 .init_verbs = { alc883_init_verbs },
9858 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9859 .dac_nids = alc883_dac_nids,
9860 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9861 .dig_in_nid = ALC883_DIGIN_NID,
9862 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9863 .channel_mode = alc883_3ST_2ch_modes,
9864 .input_mux = &alc883_capture_source,
9865 },
9866 [ALC883_3ST_6ch_DIG] = {
9867 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9868 .init_verbs = { alc883_init_verbs },
9869 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9870 .dac_nids = alc883_dac_nids,
9871 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9872 .dig_in_nid = ALC883_DIGIN_NID,
9873 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9874 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9875 .need_dac_fix = 1,
9c7f852e 9876 .input_mux = &alc883_capture_source,
f12ab1e0 9877 },
9c7f852e
TI
9878 [ALC883_3ST_6ch] = {
9879 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9880 .init_verbs = { alc883_init_verbs },
9881 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9882 .dac_nids = alc883_dac_nids,
9c7f852e
TI
9883 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9884 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 9885 .need_dac_fix = 1,
9c7f852e 9886 .input_mux = &alc883_capture_source,
f12ab1e0 9887 },
17bba1b7
J
9888 [ALC883_3ST_6ch_INTEL] = {
9889 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
9890 .init_verbs = { alc883_init_verbs },
9891 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9892 .dac_nids = alc883_dac_nids,
9893 .dig_out_nid = ALC883_DIGOUT_NID,
9894 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 9895 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
9896 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
9897 .channel_mode = alc883_3ST_6ch_intel_modes,
9898 .need_dac_fix = 1,
9899 .input_mux = &alc883_3stack_6ch_intel,
9900 },
87a8c370
JK
9901 [ALC889A_INTEL] = {
9902 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
9903 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
9904 alc_hp15_unsol_verbs },
87a8c370
JK
9905 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9906 .dac_nids = alc883_dac_nids,
9907 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9908 .adc_nids = alc889_adc_nids,
9909 .dig_out_nid = ALC883_DIGOUT_NID,
9910 .dig_in_nid = ALC883_DIGIN_NID,
9911 .slave_dig_outs = alc883_slave_dig_outs,
9912 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9913 .channel_mode = alc889_8ch_intel_modes,
9914 .capsrc_nids = alc889_capsrc_nids,
9915 .input_mux = &alc889_capture_source,
4f5d1706
TI
9916 .setup = alc889_automute_setup,
9917 .init_hook = alc_automute_amp,
6732bd0d 9918 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
9919 .need_dac_fix = 1,
9920 },
9921 [ALC889_INTEL] = {
9922 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9923 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 9924 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
9925 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9926 .dac_nids = alc883_dac_nids,
9927 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9928 .adc_nids = alc889_adc_nids,
9929 .dig_out_nid = ALC883_DIGOUT_NID,
9930 .dig_in_nid = ALC883_DIGIN_NID,
9931 .slave_dig_outs = alc883_slave_dig_outs,
9932 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9933 .channel_mode = alc889_8ch_intel_modes,
9934 .capsrc_nids = alc889_capsrc_nids,
9935 .input_mux = &alc889_capture_source,
4f5d1706 9936 .setup = alc889_automute_setup,
6732bd0d
WF
9937 .init_hook = alc889_intel_init_hook,
9938 .unsol_event = alc_automute_amp_unsol_event,
87a8c370
JK
9939 .need_dac_fix = 1,
9940 },
9c7f852e
TI
9941 [ALC883_6ST_DIG] = {
9942 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9943 .init_verbs = { alc883_init_verbs },
9944 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9945 .dac_nids = alc883_dac_nids,
9946 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
9947 .dig_in_nid = ALC883_DIGIN_NID,
9948 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9949 .channel_mode = alc883_sixstack_modes,
9950 .input_mux = &alc883_capture_source,
9951 },
ccc656ce 9952 [ALC883_TARGA_DIG] = {
c259249f 9953 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
9954 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9955 alc883_targa_verbs},
ccc656ce
KY
9956 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9957 .dac_nids = alc883_dac_nids,
9958 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9959 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9960 .channel_mode = alc883_3ST_6ch_modes,
9961 .need_dac_fix = 1,
9962 .input_mux = &alc883_capture_source,
c259249f 9963 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9964 .setup = alc882_targa_setup,
9965 .init_hook = alc882_targa_automute,
ccc656ce
KY
9966 },
9967 [ALC883_TARGA_2ch_DIG] = {
c259249f 9968 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
9969 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9970 alc883_targa_verbs},
ccc656ce
KY
9971 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9972 .dac_nids = alc883_dac_nids,
f9e336f6
TI
9973 .adc_nids = alc883_adc_nids_alt,
9974 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 9975 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 9976 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
9977 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9978 .channel_mode = alc883_3ST_2ch_modes,
9979 .input_mux = &alc883_capture_source,
c259249f 9980 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
9981 .setup = alc882_targa_setup,
9982 .init_hook = alc882_targa_automute,
ccc656ce 9983 },
64a8be74 9984 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
9985 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
9986 alc883_chmode_mixer },
64a8be74 9987 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 9988 alc883_targa_verbs },
64a8be74
DH
9989 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9990 .dac_nids = alc883_dac_nids,
9991 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9992 .adc_nids = alc883_adc_nids_rev,
9993 .capsrc_nids = alc883_capsrc_nids_rev,
9994 .dig_out_nid = ALC883_DIGOUT_NID,
9995 .dig_in_nid = ALC883_DIGIN_NID,
9996 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
9997 .channel_mode = alc883_4ST_8ch_modes,
9998 .need_dac_fix = 1,
9999 .input_mux = &alc883_capture_source,
c259249f 10000 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10001 .setup = alc882_targa_setup,
10002 .init_hook = alc882_targa_automute,
64a8be74 10003 },
bab282b9 10004 [ALC883_ACER] = {
676a9b53 10005 .mixers = { alc883_base_mixer },
bab282b9
VA
10006 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10007 * and the headphone jack. Turn this on and rely on the
10008 * standard mute methods whenever the user wants to turn
10009 * these outputs off.
10010 */
10011 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10012 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10013 .dac_nids = alc883_dac_nids,
bab282b9
VA
10014 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10015 .channel_mode = alc883_3ST_2ch_modes,
10016 .input_mux = &alc883_capture_source,
10017 },
2880a867 10018 [ALC883_ACER_ASPIRE] = {
676a9b53 10019 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10020 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10021 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10022 .dac_nids = alc883_dac_nids,
10023 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10024 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10025 .channel_mode = alc883_3ST_2ch_modes,
10026 .input_mux = &alc883_capture_source,
a9fd4f3f 10027 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10028 .setup = alc883_acer_aspire_setup,
10029 .init_hook = alc_automute_amp,
d1a991a6 10030 },
5b2d1eca 10031 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 10032 .mixers = { alc888_base_mixer,
5b2d1eca
VP
10033 alc883_chmode_mixer },
10034 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10035 alc888_acer_aspire_4930g_verbs },
10036 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10037 .dac_nids = alc883_dac_nids,
10038 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10039 .adc_nids = alc883_adc_nids_rev,
10040 .capsrc_nids = alc883_capsrc_nids_rev,
10041 .dig_out_nid = ALC883_DIGOUT_NID,
10042 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10043 .channel_mode = alc883_3ST_6ch_modes,
10044 .need_dac_fix = 1,
973b8cb0 10045 .const_channel_count = 6,
5b2d1eca 10046 .num_mux_defs =
ef8ef5fb
VP
10047 ARRAY_SIZE(alc888_2_capture_sources),
10048 .input_mux = alc888_2_capture_sources,
d2fd4b09 10049 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10050 .setup = alc888_acer_aspire_4930g_setup,
10051 .init_hook = alc_automute_amp,
d2fd4b09
TV
10052 },
10053 [ALC888_ACER_ASPIRE_6530G] = {
10054 .mixers = { alc888_acer_aspire_6530_mixer },
10055 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10056 alc888_acer_aspire_6530g_verbs },
10057 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10058 .dac_nids = alc883_dac_nids,
10059 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10060 .adc_nids = alc883_adc_nids_rev,
10061 .capsrc_nids = alc883_capsrc_nids_rev,
10062 .dig_out_nid = ALC883_DIGOUT_NID,
10063 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10064 .channel_mode = alc883_3ST_2ch_modes,
10065 .num_mux_defs =
10066 ARRAY_SIZE(alc888_2_capture_sources),
10067 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 10068 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10069 .setup = alc888_acer_aspire_6530g_setup,
10070 .init_hook = alc_automute_amp,
5b2d1eca 10071 },
3b315d70 10072 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10073 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10074 alc883_chmode_mixer },
10075 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10076 alc889_acer_aspire_8930g_verbs,
10077 alc889_eapd_verbs},
3b315d70
HM
10078 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10079 .dac_nids = alc883_dac_nids,
018df418
HM
10080 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10081 .adc_nids = alc889_adc_nids,
10082 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10083 .dig_out_nid = ALC883_DIGOUT_NID,
10084 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10085 .channel_mode = alc883_3ST_6ch_modes,
10086 .need_dac_fix = 1,
10087 .const_channel_count = 6,
10088 .num_mux_defs =
018df418
HM
10089 ARRAY_SIZE(alc889_capture_sources),
10090 .input_mux = alc889_capture_sources,
3b315d70 10091 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10092 .setup = alc889_acer_aspire_8930g_setup,
10093 .init_hook = alc_automute_amp,
f5de24b0 10094#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10095 .power_hook = alc_power_eapd,
f5de24b0 10096#endif
3b315d70 10097 },
fc86f954
DK
10098 [ALC888_ACER_ASPIRE_7730G] = {
10099 .mixers = { alc883_3ST_6ch_mixer,
10100 alc883_chmode_mixer },
10101 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10102 alc888_acer_aspire_7730G_verbs },
10103 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10104 .dac_nids = alc883_dac_nids,
10105 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10106 .adc_nids = alc883_adc_nids_rev,
10107 .capsrc_nids = alc883_capsrc_nids_rev,
10108 .dig_out_nid = ALC883_DIGOUT_NID,
10109 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10110 .channel_mode = alc883_3ST_6ch_modes,
10111 .need_dac_fix = 1,
10112 .const_channel_count = 6,
10113 .input_mux = &alc883_capture_source,
10114 .unsol_event = alc_automute_amp_unsol_event,
10115 .setup = alc888_acer_aspire_6530g_setup,
10116 .init_hook = alc_automute_amp,
10117 },
c07584c8
TD
10118 [ALC883_MEDION] = {
10119 .mixers = { alc883_fivestack_mixer,
10120 alc883_chmode_mixer },
10121 .init_verbs = { alc883_init_verbs,
b373bdeb 10122 alc883_medion_eapd_verbs },
c07584c8
TD
10123 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10124 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10125 .adc_nids = alc883_adc_nids_alt,
10126 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10127 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10128 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10129 .channel_mode = alc883_sixstack_modes,
10130 .input_mux = &alc883_capture_source,
b373bdeb 10131 },
272a527c
KY
10132 [ALC883_MEDION_MD2] = {
10133 .mixers = { alc883_medion_md2_mixer},
10134 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
10135 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10136 .dac_nids = alc883_dac_nids,
10137 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10138 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10139 .channel_mode = alc883_3ST_2ch_modes,
10140 .input_mux = &alc883_capture_source,
a9fd4f3f 10141 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10142 .setup = alc883_medion_md2_setup,
10143 .init_hook = alc_automute_amp,
ea1fb29a 10144 },
7ad7b218
MC
10145 [ALC883_MEDION_WIM2160] = {
10146 .mixers = { alc883_medion_wim2160_mixer },
10147 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10148 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10149 .dac_nids = alc883_dac_nids,
10150 .dig_out_nid = ALC883_DIGOUT_NID,
10151 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10152 .adc_nids = alc883_adc_nids,
10153 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10154 .channel_mode = alc883_3ST_2ch_modes,
10155 .input_mux = &alc883_capture_source,
10156 .unsol_event = alc_automute_amp_unsol_event,
10157 .setup = alc883_medion_wim2160_setup,
10158 .init_hook = alc_automute_amp,
10159 },
b373bdeb 10160 [ALC883_LAPTOP_EAPD] = {
676a9b53 10161 .mixers = { alc883_base_mixer },
b373bdeb
AN
10162 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10163 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10164 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10165 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10166 .channel_mode = alc883_3ST_2ch_modes,
10167 .input_mux = &alc883_capture_source,
10168 },
a65cc60f 10169 [ALC883_CLEVO_M540R] = {
10170 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10171 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10172 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10173 .dac_nids = alc883_dac_nids,
10174 .dig_out_nid = ALC883_DIGOUT_NID,
10175 .dig_in_nid = ALC883_DIGIN_NID,
10176 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10177 .channel_mode = alc883_3ST_6ch_clevo_modes,
10178 .need_dac_fix = 1,
10179 .input_mux = &alc883_capture_source,
10180 /* This machine has the hardware HP auto-muting, thus
10181 * we need no software mute via unsol event
10182 */
10183 },
0c4cc443
HRK
10184 [ALC883_CLEVO_M720] = {
10185 .mixers = { alc883_clevo_m720_mixer },
10186 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10187 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10188 .dac_nids = alc883_dac_nids,
10189 .dig_out_nid = ALC883_DIGOUT_NID,
10190 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10191 .channel_mode = alc883_3ST_2ch_modes,
10192 .input_mux = &alc883_capture_source,
0c4cc443 10193 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10194 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10195 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10196 },
bc9f98a9
KY
10197 [ALC883_LENOVO_101E_2ch] = {
10198 .mixers = { alc883_lenovo_101e_2ch_mixer},
10199 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10200 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10201 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10202 .adc_nids = alc883_adc_nids_alt,
10203 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10204 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10205 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10206 .channel_mode = alc883_3ST_2ch_modes,
10207 .input_mux = &alc883_lenovo_101e_capture_source,
10208 .unsol_event = alc883_lenovo_101e_unsol_event,
10209 .init_hook = alc883_lenovo_101e_all_automute,
10210 },
272a527c
KY
10211 [ALC883_LENOVO_NB0763] = {
10212 .mixers = { alc883_lenovo_nb0763_mixer },
10213 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10214 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10215 .dac_nids = alc883_dac_nids,
272a527c
KY
10216 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10217 .channel_mode = alc883_3ST_2ch_modes,
10218 .need_dac_fix = 1,
10219 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f 10220 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10221 .setup = alc883_medion_md2_setup,
10222 .init_hook = alc_automute_amp,
272a527c
KY
10223 },
10224 [ALC888_LENOVO_MS7195_DIG] = {
10225 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10226 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10227 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10228 .dac_nids = alc883_dac_nids,
10229 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10230 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10231 .channel_mode = alc883_3ST_6ch_modes,
10232 .need_dac_fix = 1,
10233 .input_mux = &alc883_capture_source,
10234 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10235 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
10236 },
10237 [ALC883_HAIER_W66] = {
c259249f 10238 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10239 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10240 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10241 .dac_nids = alc883_dac_nids,
10242 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10243 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10244 .channel_mode = alc883_3ST_2ch_modes,
10245 .input_mux = &alc883_capture_source,
a9fd4f3f 10246 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10247 .setup = alc883_haier_w66_setup,
10248 .init_hook = alc_automute_amp,
eea6419e 10249 },
4723c022 10250 [ALC888_3ST_HP] = {
eea6419e 10251 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10252 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10253 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10254 .dac_nids = alc883_dac_nids,
4723c022
CM
10255 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10256 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10257 .need_dac_fix = 1,
10258 .input_mux = &alc883_capture_source,
a9fd4f3f 10259 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10260 .setup = alc888_3st_hp_setup,
10261 .init_hook = alc_automute_amp,
8341de60 10262 },
5795b9e6 10263 [ALC888_6ST_DELL] = {
f24dbdc6 10264 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10265 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10266 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10267 .dac_nids = alc883_dac_nids,
10268 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10269 .dig_in_nid = ALC883_DIGIN_NID,
10270 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10271 .channel_mode = alc883_sixstack_modes,
10272 .input_mux = &alc883_capture_source,
a9fd4f3f 10273 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10274 .setup = alc888_6st_dell_setup,
10275 .init_hook = alc_automute_amp,
5795b9e6 10276 },
a8848bd6
AS
10277 [ALC883_MITAC] = {
10278 .mixers = { alc883_mitac_mixer },
10279 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10280 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10281 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10282 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10283 .channel_mode = alc883_3ST_2ch_modes,
10284 .input_mux = &alc883_capture_source,
a9fd4f3f 10285 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10286 .setup = alc883_mitac_setup,
10287 .init_hook = alc_automute_amp,
a8848bd6 10288 },
fb97dc67
J
10289 [ALC883_FUJITSU_PI2515] = {
10290 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10291 .init_verbs = { alc883_init_verbs,
10292 alc883_2ch_fujitsu_pi2515_verbs},
10293 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10294 .dac_nids = alc883_dac_nids,
10295 .dig_out_nid = ALC883_DIGOUT_NID,
10296 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10297 .channel_mode = alc883_3ST_2ch_modes,
10298 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f 10299 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10300 .setup = alc883_2ch_fujitsu_pi2515_setup,
10301 .init_hook = alc_automute_amp,
fb97dc67 10302 },
ef8ef5fb
VP
10303 [ALC888_FUJITSU_XA3530] = {
10304 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10305 .init_verbs = { alc883_init_verbs,
10306 alc888_fujitsu_xa3530_verbs },
10307 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10308 .dac_nids = alc883_dac_nids,
10309 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10310 .adc_nids = alc883_adc_nids_rev,
10311 .capsrc_nids = alc883_capsrc_nids_rev,
10312 .dig_out_nid = ALC883_DIGOUT_NID,
10313 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10314 .channel_mode = alc888_4ST_8ch_intel_modes,
10315 .num_mux_defs =
10316 ARRAY_SIZE(alc888_2_capture_sources),
10317 .input_mux = alc888_2_capture_sources,
a9fd4f3f 10318 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10319 .setup = alc888_fujitsu_xa3530_setup,
10320 .init_hook = alc_automute_amp,
ef8ef5fb 10321 },
e2757d5e
KY
10322 [ALC888_LENOVO_SKY] = {
10323 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10324 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10325 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10326 .dac_nids = alc883_dac_nids,
10327 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10328 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10329 .channel_mode = alc883_sixstack_modes,
10330 .need_dac_fix = 1,
10331 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f 10332 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10333 .setup = alc888_lenovo_sky_setup,
10334 .init_hook = alc_automute_amp,
e2757d5e
KY
10335 },
10336 [ALC888_ASUS_M90V] = {
10337 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10338 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10339 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10340 .dac_nids = alc883_dac_nids,
10341 .dig_out_nid = ALC883_DIGOUT_NID,
10342 .dig_in_nid = ALC883_DIGIN_NID,
10343 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10344 .channel_mode = alc883_3ST_6ch_modes,
10345 .need_dac_fix = 1,
10346 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10347 .unsol_event = alc_sku_unsol_event,
10348 .setup = alc883_mode2_setup,
10349 .init_hook = alc_inithook,
e2757d5e
KY
10350 },
10351 [ALC888_ASUS_EEE1601] = {
10352 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10353 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10354 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10355 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10356 .dac_nids = alc883_dac_nids,
10357 .dig_out_nid = ALC883_DIGOUT_NID,
10358 .dig_in_nid = ALC883_DIGIN_NID,
10359 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10360 .channel_mode = alc883_3ST_2ch_modes,
10361 .need_dac_fix = 1,
10362 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10363 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10364 .init_hook = alc883_eee1601_inithook,
10365 },
3ab90935
WF
10366 [ALC1200_ASUS_P5Q] = {
10367 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10368 .init_verbs = { alc883_init_verbs },
10369 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10370 .dac_nids = alc883_dac_nids,
10371 .dig_out_nid = ALC1200_DIGOUT_NID,
10372 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10373 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10374 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10375 .channel_mode = alc883_sixstack_modes,
10376 .input_mux = &alc883_capture_source,
10377 },
eb4c41d3
TS
10378 [ALC889A_MB31] = {
10379 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10380 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10381 alc880_gpio1_init_verbs },
10382 .adc_nids = alc883_adc_nids,
10383 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10384 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10385 .dac_nids = alc883_dac_nids,
10386 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10387 .channel_mode = alc889A_mb31_6ch_modes,
10388 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10389 .input_mux = &alc889A_mb31_capture_source,
10390 .dig_out_nid = ALC883_DIGOUT_NID,
10391 .unsol_event = alc889A_mb31_unsol_event,
10392 .init_hook = alc889A_mb31_automute,
10393 },
3e1647c5
GG
10394 [ALC883_SONY_VAIO_TT] = {
10395 .mixers = { alc883_vaiott_mixer },
10396 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10397 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10398 .dac_nids = alc883_dac_nids,
10399 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10400 .channel_mode = alc883_3ST_2ch_modes,
10401 .input_mux = &alc883_capture_source,
10402 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
10403 .setup = alc883_vaiott_setup,
10404 .init_hook = alc_automute_amp,
3e1647c5 10405 },
9c7f852e
TI
10406};
10407
10408
4953550a
TI
10409/*
10410 * Pin config fixes
10411 */
10412enum {
954a29c8
TI
10413 PINFIX_ABIT_AW9D_MAX,
10414 PINFIX_PB_M5210,
4953550a
TI
10415};
10416
10417static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
10418 { 0x15, 0x01080104 }, /* side */
10419 { 0x16, 0x01011012 }, /* rear */
10420 { 0x17, 0x01016011 }, /* clfe */
10421 { }
10422};
10423
954a29c8
TI
10424static const struct hda_verb pb_m5210_verbs[] = {
10425 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10426 {}
10427};
10428
f8f25ba3
TI
10429static const struct alc_fixup alc882_fixups[] = {
10430 [PINFIX_ABIT_AW9D_MAX] = {
10431 .pins = alc882_abit_aw9d_pinfix
10432 },
954a29c8
TI
10433 [PINFIX_PB_M5210] = {
10434 .verbs = pb_m5210_verbs
10435 },
4953550a
TI
10436};
10437
f8f25ba3 10438static struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10439 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
4953550a
TI
10440 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10441 {}
10442};
10443
9c7f852e
TI
10444/*
10445 * BIOS auto configuration
10446 */
05f5f477
TI
10447static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10448 const struct auto_pin_cfg *cfg)
10449{
10450 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10451}
10452
4953550a 10453static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10454 hda_nid_t nid, int pin_type,
489008cd 10455 hda_nid_t dac)
9c7f852e 10456{
f12ab1e0
TI
10457 int idx;
10458
489008cd 10459 /* set as output */
f6c7e546 10460 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10461
10462 if (dac == 0x25)
9c7f852e 10463 idx = 4;
489008cd
TI
10464 else if (dac >= 0x02 && dac <= 0x05)
10465 idx = dac - 2;
f9700d5a 10466 else
489008cd 10467 return;
9c7f852e 10468 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
10469}
10470
4953550a 10471static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
10472{
10473 struct alc_spec *spec = codec->spec;
10474 int i;
10475
10476 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 10477 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10478 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 10479 if (nid)
4953550a 10480 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 10481 spec->multiout.dac_nids[i]);
9c7f852e
TI
10482 }
10483}
10484
4953550a 10485static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
10486{
10487 struct alc_spec *spec = codec->spec;
489008cd 10488 hda_nid_t pin, dac;
9c7f852e 10489
eb06ed8f 10490 pin = spec->autocfg.hp_pins[0];
489008cd
TI
10491 if (pin) {
10492 dac = spec->multiout.hp_nid;
10493 if (!dac)
10494 dac = spec->multiout.dac_nids[0]; /* to front */
10495 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10496 }
f6c7e546 10497 pin = spec->autocfg.speaker_pins[0];
489008cd
TI
10498 if (pin) {
10499 dac = spec->multiout.extra_out_nid[0];
10500 if (!dac)
10501 dac = spec->multiout.dac_nids[0]; /* to front */
10502 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10503 }
9c7f852e
TI
10504}
10505
4953550a 10506static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
10507{
10508 struct alc_spec *spec = codec->spec;
10509 int i;
10510
10511 for (i = 0; i < AUTO_PIN_LAST; i++) {
10512 hda_nid_t nid = spec->autocfg.input_pins[i];
4953550a
TI
10513 if (!nid)
10514 continue;
0d971c9f 10515 alc_set_input_pin(codec, nid, i);
4953550a
TI
10516 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10517 snd_hda_codec_write(codec, nid, 0,
10518 AC_VERB_SET_AMP_GAIN_MUTE,
10519 AMP_OUT_MUTE);
10520 }
10521}
10522
10523static void alc882_auto_init_input_src(struct hda_codec *codec)
10524{
10525 struct alc_spec *spec = codec->spec;
10526 int c;
10527
10528 for (c = 0; c < spec->num_adc_nids; c++) {
10529 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10530 hda_nid_t nid = spec->capsrc_nids[c];
10531 unsigned int mux_idx;
10532 const struct hda_input_mux *imux;
10533 int conns, mute, idx, item;
10534
10535 conns = snd_hda_get_connections(codec, nid, conn_list,
10536 ARRAY_SIZE(conn_list));
10537 if (conns < 0)
10538 continue;
10539 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10540 imux = &spec->input_mux[mux_idx];
5311114d
TI
10541 if (!imux->num_items && mux_idx > 0)
10542 imux = &spec->input_mux[0];
4953550a
TI
10543 for (idx = 0; idx < conns; idx++) {
10544 /* if the current connection is the selected one,
10545 * unmute it as default - otherwise mute it
10546 */
10547 mute = AMP_IN_MUTE(idx);
10548 for (item = 0; item < imux->num_items; item++) {
10549 if (imux->items[item].index == idx) {
10550 if (spec->cur_mux[c] == item)
10551 mute = AMP_IN_UNMUTE(idx);
10552 break;
10553 }
10554 }
10555 /* check if we have a selector or mixer
10556 * we could check for the widget type instead, but
10557 * just check for Amp-In presence (in case of mixer
10558 * without amp-in there is something wrong, this
10559 * function shouldn't be used or capsrc nid is wrong)
10560 */
10561 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
10562 snd_hda_codec_write(codec, nid, 0,
10563 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
10564 mute);
10565 else if (mute != AMP_IN_MUTE(idx))
10566 snd_hda_codec_write(codec, nid, 0,
10567 AC_VERB_SET_CONNECT_SEL,
10568 idx);
9c7f852e
TI
10569 }
10570 }
10571}
10572
4953550a
TI
10573/* add mic boosts if needed */
10574static int alc_auto_add_mic_boost(struct hda_codec *codec)
10575{
10576 struct alc_spec *spec = codec->spec;
10577 int err;
10578 hda_nid_t nid;
10579
10580 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
10581 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10582 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10583 "Mic Boost",
10584 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10585 if (err < 0)
10586 return err;
10587 }
10588 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
10589 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10590 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10591 "Front Mic Boost",
10592 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10593 if (err < 0)
10594 return err;
10595 }
10596 return 0;
10597}
f511b01c 10598
9c7f852e 10599/* almost identical with ALC880 parser... */
4953550a 10600static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10601{
10602 struct alc_spec *spec = codec->spec;
05f5f477 10603 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 10604 int err;
9c7f852e 10605
05f5f477
TI
10606 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10607 alc882_ignore);
9c7f852e
TI
10608 if (err < 0)
10609 return err;
05f5f477
TI
10610 if (!spec->autocfg.line_outs)
10611 return 0; /* can't find valid BIOS pin config */
776e184e 10612
05f5f477
TI
10613 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10614 if (err < 0)
10615 return err;
10616 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
10617 if (err < 0)
10618 return err;
10619 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10620 "Headphone");
05f5f477
TI
10621 if (err < 0)
10622 return err;
10623 err = alc880_auto_create_extra_out(spec,
10624 spec->autocfg.speaker_pins[0],
10625 "Speaker");
10626 if (err < 0)
10627 return err;
05f5f477 10628 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
10629 if (err < 0)
10630 return err;
10631
05f5f477
TI
10632 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10633
757899ac 10634 alc_auto_parse_digital(codec);
05f5f477
TI
10635
10636 if (spec->kctls.list)
10637 add_mixer(spec, spec->kctls.list);
10638
10639 add_verb(spec, alc883_auto_init_verbs);
4953550a 10640 /* if ADC 0x07 is available, initialize it, too */
05f5f477 10641 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 10642 add_verb(spec, alc882_adc1_init_verbs);
776e184e 10643
05f5f477
TI
10644 spec->num_mux_defs = 1;
10645 spec->input_mux = &spec->private_imux[0];
10646
6227cdce 10647 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10648
10649 err = alc_auto_add_mic_boost(codec);
10650 if (err < 0)
10651 return err;
61b9b9b1 10652
776e184e 10653 return 1; /* config found */
9c7f852e
TI
10654}
10655
10656/* additional initialization for auto-configuration model */
4953550a 10657static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10658{
f6c7e546 10659 struct alc_spec *spec = codec->spec;
4953550a
TI
10660 alc882_auto_init_multi_out(codec);
10661 alc882_auto_init_hp_out(codec);
10662 alc882_auto_init_analog_input(codec);
10663 alc882_auto_init_input_src(codec);
757899ac 10664 alc_auto_init_digital(codec);
f6c7e546 10665 if (spec->unsol_event)
7fb0d78f 10666 alc_inithook(codec);
9c7f852e
TI
10667}
10668
4953550a 10669static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10670{
10671 struct alc_spec *spec;
10672 int err, board_config;
10673
10674 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10675 if (spec == NULL)
10676 return -ENOMEM;
10677
10678 codec->spec = spec;
10679
da00c244
KY
10680 alc_auto_parse_customize_define(codec);
10681
4953550a
TI
10682 switch (codec->vendor_id) {
10683 case 0x10ec0882:
10684 case 0x10ec0885:
10685 break;
10686 default:
10687 /* ALC883 and variants */
10688 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10689 break;
10690 }
2c3bf9ab 10691
4953550a
TI
10692 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10693 alc882_models,
10694 alc882_cfg_tbl);
10695
10696 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10697 board_config = snd_hda_check_board_codec_sid_config(codec,
10698 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10699
10700 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 10701 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
10702 codec->chip_name);
10703 board_config = ALC882_AUTO;
9c7f852e
TI
10704 }
10705
7fa90e87
TI
10706 if (board_config == ALC882_AUTO)
10707 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
4953550a
TI
10708
10709 if (board_config == ALC882_AUTO) {
9c7f852e 10710 /* automatic parse from the BIOS config */
4953550a 10711 err = alc882_parse_auto_config(codec);
9c7f852e
TI
10712 if (err < 0) {
10713 alc_free(codec);
10714 return err;
f12ab1e0 10715 } else if (!err) {
9c7f852e
TI
10716 printk(KERN_INFO
10717 "hda_codec: Cannot set up configuration "
10718 "from BIOS. Using base mode...\n");
4953550a 10719 board_config = ALC882_3ST_DIG;
9c7f852e
TI
10720 }
10721 }
10722
dc1eae25 10723 if (has_cdefine_beep(codec)) {
8af2591d
TI
10724 err = snd_hda_attach_beep_device(codec, 0x1);
10725 if (err < 0) {
10726 alc_free(codec);
10727 return err;
10728 }
680cd536
KK
10729 }
10730
4953550a 10731 if (board_config != ALC882_AUTO)
e9c364c0 10732 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 10733
4953550a
TI
10734 spec->stream_analog_playback = &alc882_pcm_analog_playback;
10735 spec->stream_analog_capture = &alc882_pcm_analog_capture;
10736 /* FIXME: setup DAC5 */
10737 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
10738 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
10739
10740 spec->stream_digital_playback = &alc882_pcm_digital_playback;
10741 spec->stream_digital_capture = &alc882_pcm_digital_capture;
10742
4953550a 10743 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 10744 int i, j;
4953550a
TI
10745 spec->num_adc_nids = 0;
10746 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 10747 const struct hda_input_mux *imux = spec->input_mux;
4953550a 10748 hda_nid_t cap;
d11f74c6 10749 hda_nid_t items[16];
4953550a
TI
10750 hda_nid_t nid = alc882_adc_nids[i];
10751 unsigned int wcap = get_wcaps(codec, nid);
10752 /* get type */
a22d543a 10753 wcap = get_wcaps_type(wcap);
4953550a
TI
10754 if (wcap != AC_WID_AUD_IN)
10755 continue;
10756 spec->private_adc_nids[spec->num_adc_nids] = nid;
10757 err = snd_hda_get_connections(codec, nid, &cap, 1);
10758 if (err < 0)
10759 continue;
d11f74c6
TI
10760 err = snd_hda_get_connections(codec, cap, items,
10761 ARRAY_SIZE(items));
10762 if (err < 0)
10763 continue;
10764 for (j = 0; j < imux->num_items; j++)
10765 if (imux->items[j].index >= err)
10766 break;
10767 if (j < imux->num_items)
10768 continue;
4953550a
TI
10769 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
10770 spec->num_adc_nids++;
61b9b9b1 10771 }
4953550a
TI
10772 spec->adc_nids = spec->private_adc_nids;
10773 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
10774 }
10775
b59bdf3b 10776 set_capture_mixer(codec);
da00c244 10777
dc1eae25 10778 if (has_cdefine_beep(codec))
da00c244 10779 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 10780
7fa90e87
TI
10781 if (board_config == ALC882_AUTO)
10782 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
10783
2134ea4f
TI
10784 spec->vmaster_nid = 0x0c;
10785
9c7f852e 10786 codec->patch_ops = alc_patch_ops;
4953550a
TI
10787 if (board_config == ALC882_AUTO)
10788 spec->init_hook = alc882_auto_init;
cb53c626
TI
10789#ifdef CONFIG_SND_HDA_POWER_SAVE
10790 if (!spec->loopback.amplist)
4953550a 10791 spec->loopback.amplist = alc882_loopbacks;
cb53c626 10792#endif
9c7f852e
TI
10793
10794 return 0;
10795}
10796
4953550a 10797
9c7f852e
TI
10798/*
10799 * ALC262 support
10800 */
10801
10802#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
10803#define ALC262_DIGIN_NID ALC880_DIGIN_NID
10804
10805#define alc262_dac_nids alc260_dac_nids
10806#define alc262_adc_nids alc882_adc_nids
10807#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
10808#define alc262_capsrc_nids alc882_capsrc_nids
10809#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
10810
10811#define alc262_modes alc260_modes
10812#define alc262_capture_source alc882_capture_source
10813
4e555fe5
KY
10814static hda_nid_t alc262_dmic_adc_nids[1] = {
10815 /* ADC0 */
10816 0x09
10817};
10818
10819static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
10820
9c7f852e
TI
10821static struct snd_kcontrol_new alc262_base_mixer[] = {
10822 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10823 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10824 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10825 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10826 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10827 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10828 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10829 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10830 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
10831 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10832 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 10833 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
10834 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
10835 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10836 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
10837 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10838 { } /* end */
10839};
10840
ce875f07
TI
10841/* update HP, line and mono-out pins according to the master switch */
10842static void alc262_hp_master_update(struct hda_codec *codec)
10843{
10844 struct alc_spec *spec = codec->spec;
10845 int val = spec->master_sw;
10846
10847 /* HP & line-out */
10848 snd_hda_codec_write_cache(codec, 0x1b, 0,
10849 AC_VERB_SET_PIN_WIDGET_CONTROL,
10850 val ? PIN_HP : 0);
10851 snd_hda_codec_write_cache(codec, 0x15, 0,
10852 AC_VERB_SET_PIN_WIDGET_CONTROL,
10853 val ? PIN_HP : 0);
10854 /* mono (speaker) depending on the HP jack sense */
10855 val = val && !spec->jack_present;
10856 snd_hda_codec_write_cache(codec, 0x16, 0,
10857 AC_VERB_SET_PIN_WIDGET_CONTROL,
10858 val ? PIN_OUT : 0);
10859}
10860
10861static void alc262_hp_bpc_automute(struct hda_codec *codec)
10862{
10863 struct alc_spec *spec = codec->spec;
864f92be
WF
10864
10865 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
ce875f07
TI
10866 alc262_hp_master_update(codec);
10867}
10868
10869static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
10870{
10871 if ((res >> 26) != ALC880_HP_EVENT)
10872 return;
10873 alc262_hp_bpc_automute(codec);
10874}
10875
10876static void alc262_hp_wildwest_automute(struct hda_codec *codec)
10877{
10878 struct alc_spec *spec = codec->spec;
864f92be
WF
10879
10880 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
ce875f07
TI
10881 alc262_hp_master_update(codec);
10882}
10883
10884static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
10885 unsigned int res)
10886{
10887 if ((res >> 26) != ALC880_HP_EVENT)
10888 return;
10889 alc262_hp_wildwest_automute(codec);
10890}
10891
b72519b5 10892#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
10893
10894static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10895 struct snd_ctl_elem_value *ucontrol)
10896{
10897 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10898 struct alc_spec *spec = codec->spec;
10899 int val = !!*ucontrol->value.integer.value;
10900
10901 if (val == spec->master_sw)
10902 return 0;
10903 spec->master_sw = val;
10904 alc262_hp_master_update(codec);
10905 return 1;
10906}
10907
b72519b5
TI
10908#define ALC262_HP_MASTER_SWITCH \
10909 { \
10910 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10911 .name = "Master Playback Switch", \
10912 .info = snd_ctl_boolean_mono_info, \
10913 .get = alc262_hp_master_sw_get, \
10914 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
10915 }, \
10916 { \
10917 .iface = NID_MAPPING, \
10918 .name = "Master Playback Switch", \
10919 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
10920 }
10921
5b0cb1d8 10922
9c7f852e 10923static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 10924 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
10925 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10926 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10927 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
10928 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10929 HDA_OUTPUT),
10930 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10931 HDA_OUTPUT),
9c7f852e
TI
10932 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10933 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10934 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
10935 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10936 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 10937 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
10938 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10939 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10940 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10941 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
10942 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
10943 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
10944 { } /* end */
10945};
10946
cd7509a4 10947static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 10948 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
10949 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10950 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10951 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10952 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
10953 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10954 HDA_OUTPUT),
10955 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10956 HDA_OUTPUT),
cd7509a4
KY
10957 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
10958 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 10959 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
10960 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10961 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10962 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10963 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
10964 { } /* end */
10965};
10966
10967static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
10968 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10969 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 10970 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
10971 { } /* end */
10972};
10973
66d2a9d6 10974/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 10975static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
10976{
10977 struct alc_spec *spec = codec->spec;
66d2a9d6 10978
a9fd4f3f 10979 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 10980 spec->autocfg.speaker_pins[0] = 0x14;
66d2a9d6
KY
10981}
10982
66d2a9d6 10983static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
10984 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10985 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
10986 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10987 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10988 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10989 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10990 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10991 { } /* end */
10992};
10993
10994static struct hda_verb alc262_hp_t5735_verbs[] = {
10995 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10996 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10997
10998 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10999 { }
11000};
11001
8c427226 11002static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11003 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11004 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11005 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11006 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11007 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11008 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11009 { } /* end */
11010};
11011
11012static struct hda_verb alc262_hp_rp5700_verbs[] = {
11013 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11014 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11015 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11016 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11017 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11018 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11019 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11020 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11021 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11022 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11023 {}
11024};
11025
11026static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11027 .num_items = 1,
11028 .items = {
11029 { "Line", 0x1 },
11030 },
11031};
11032
42171c17
TI
11033/* bind hp and internal speaker mute (with plug check) as master switch */
11034static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 11035{
42171c17
TI
11036 struct alc_spec *spec = codec->spec;
11037 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11038 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11039 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11040 unsigned int mute;
0724ea2a 11041
42171c17
TI
11042 /* HP */
11043 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11044 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11045 HDA_AMP_MUTE, mute);
11046 /* mute internal speaker per jack sense */
11047 if (spec->jack_present)
11048 mute = HDA_AMP_MUTE;
11049 if (line_nid)
11050 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11051 HDA_AMP_MUTE, mute);
11052 if (speaker_nid && speaker_nid != line_nid)
11053 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 11054 HDA_AMP_MUTE, mute);
42171c17
TI
11055}
11056
11057#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11058
11059static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11060 struct snd_ctl_elem_value *ucontrol)
11061{
11062 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11063 struct alc_spec *spec = codec->spec;
11064 int val = !!*ucontrol->value.integer.value;
11065
11066 if (val == spec->master_sw)
11067 return 0;
11068 spec->master_sw = val;
11069 alc262_hippo_master_update(codec);
11070 return 1;
11071}
11072
11073#define ALC262_HIPPO_MASTER_SWITCH \
11074 { \
11075 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11076 .name = "Master Playback Switch", \
11077 .info = snd_ctl_boolean_mono_info, \
11078 .get = alc262_hippo_master_sw_get, \
11079 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11080 }, \
11081 { \
11082 .iface = NID_MAPPING, \
11083 .name = "Master Playback Switch", \
11084 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11085 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11086 }
42171c17
TI
11087
11088static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11089 ALC262_HIPPO_MASTER_SWITCH,
11090 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11091 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11092 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11093 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11094 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11095 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11096 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11097 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11098 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11099 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11100 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11101 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11102 { } /* end */
11103};
11104
11105static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11106 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11107 ALC262_HIPPO_MASTER_SWITCH,
11108 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11109 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11110 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11111 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11112 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11113 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11114 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11115 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11116 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11117 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11118 { } /* end */
11119};
11120
11121/* mute/unmute internal speaker according to the hp jack and mute state */
11122static void alc262_hippo_automute(struct hda_codec *codec)
11123{
11124 struct alc_spec *spec = codec->spec;
11125 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
42171c17 11126
864f92be 11127 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
42171c17 11128 alc262_hippo_master_update(codec);
0724ea2a 11129}
5b31954e 11130
42171c17
TI
11131static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11132{
11133 if ((res >> 26) != ALC880_HP_EVENT)
11134 return;
11135 alc262_hippo_automute(codec);
11136}
11137
4f5d1706 11138static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11139{
11140 struct alc_spec *spec = codec->spec;
11141
11142 spec->autocfg.hp_pins[0] = 0x15;
11143 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11144}
11145
4f5d1706 11146static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11147{
11148 struct alc_spec *spec = codec->spec;
11149
11150 spec->autocfg.hp_pins[0] = 0x1b;
11151 spec->autocfg.speaker_pins[0] = 0x14;
42171c17
TI
11152}
11153
11154
272a527c 11155static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11156 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11157 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11158 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11159 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11160 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11161 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11162 { } /* end */
11163};
11164
83c34218 11165static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11166 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11167 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11168 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11169 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11170 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11171 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11172 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11173 { } /* end */
11174};
272a527c 11175
ba340e82
TV
11176static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11177 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11178 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11179 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11180 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11181 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11182 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11183 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11184 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11185 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11186 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11187 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11188 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11189 { } /* end */
11190};
11191
11192static struct hda_verb alc262_tyan_verbs[] = {
11193 /* Headphone automute */
11194 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11195 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11196 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11197
11198 /* P11 AUX_IN, white 4-pin connector */
11199 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11200 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11201 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11202 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11203
11204 {}
11205};
11206
11207/* unsolicited event for HP jack sensing */
4f5d1706 11208static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11209{
a9fd4f3f 11210 struct alc_spec *spec = codec->spec;
ba340e82 11211
a9fd4f3f
TI
11212 spec->autocfg.hp_pins[0] = 0x1b;
11213 spec->autocfg.speaker_pins[0] = 0x15;
ba340e82
TV
11214}
11215
ba340e82 11216
9c7f852e
TI
11217#define alc262_capture_mixer alc882_capture_mixer
11218#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11219
11220/*
11221 * generic initialization of ADC, input mixers and output mixers
11222 */
11223static struct hda_verb alc262_init_verbs[] = {
11224 /*
11225 * Unmute ADC0-2 and set the default input to mic-in
11226 */
11227 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11228 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11229 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11230 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11231 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11232 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11233
cb53c626 11234 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11235 * mixer widget
f12ab1e0
TI
11236 * Note: PASD motherboards uses the Line In 2 as the input for
11237 * front panel mic (mic 2)
9c7f852e
TI
11238 */
11239 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11240 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11241 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11242 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11243 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11244 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11245
11246 /*
df694daa
KY
11247 * Set up output mixers (0x0c - 0x0e)
11248 */
11249 /* set vol=0 to output mixers */
11250 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11251 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11252 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11253 /* set up input amps for analog loopback */
11254 /* Amp Indices: DAC = 0, mixer = 1 */
11255 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11256 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11257 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11258 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11259 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11260 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11261
11262 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11263 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11264 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11265 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11266 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11267 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11268
11269 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11270 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11271 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11272 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11273 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11274
df694daa
KY
11275 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11276 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11277
df694daa
KY
11278 /* FIXME: use matrix-type input source selection */
11279 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11280 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11281 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11282 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11283 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11284 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11285 /* Input mixer2 */
11286 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11287 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11288 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11289 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11290 /* Input mixer3 */
11291 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11292 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11293 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11294 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11295
11296 { }
11297};
1da177e4 11298
4e555fe5
KY
11299static struct hda_verb alc262_eapd_verbs[] = {
11300 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11301 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11302 { }
11303};
11304
ccc656ce
KY
11305static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11306 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11307 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11308 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11309
11310 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11311 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11312 {}
11313};
11314
272a527c
KY
11315static struct hda_verb alc262_sony_unsol_verbs[] = {
11316 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11317 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11318 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11319
11320 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11321 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11322 {}
272a527c
KY
11323};
11324
4e555fe5
KY
11325static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11326 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11327 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11328 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11329 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11330 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11331 { } /* end */
11332};
11333
11334static struct hda_verb alc262_toshiba_s06_verbs[] = {
11335 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11336 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11337 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11338 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11339 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11340 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11341 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11342 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11343 {}
11344};
11345
4f5d1706 11346static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11347{
a9fd4f3f
TI
11348 struct alc_spec *spec = codec->spec;
11349
11350 spec->autocfg.hp_pins[0] = 0x15;
11351 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11352 spec->ext_mic.pin = 0x18;
11353 spec->ext_mic.mux_idx = 0;
11354 spec->int_mic.pin = 0x12;
11355 spec->int_mic.mux_idx = 9;
11356 spec->auto_mic = 1;
4e555fe5
KY
11357}
11358
e8f9ae2a
PT
11359/*
11360 * nec model
11361 * 0x15 = headphone
11362 * 0x16 = internal speaker
11363 * 0x18 = external mic
11364 */
11365
11366static struct snd_kcontrol_new alc262_nec_mixer[] = {
11367 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11368 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11369
11370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11371 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11372 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11373
11374 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11375 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11376 { } /* end */
11377};
11378
11379static struct hda_verb alc262_nec_verbs[] = {
11380 /* Unmute Speaker */
11381 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11382
11383 /* Headphone */
11384 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11385 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11386
11387 /* External mic to headphone */
11388 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11389 /* External mic to speaker */
11390 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11391 {}
11392};
11393
834be88d
TI
11394/*
11395 * fujitsu model
5d9fab2d
TV
11396 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11397 * 0x1b = port replicator headphone out
834be88d
TI
11398 */
11399
11400#define ALC_HP_EVENT 0x37
11401
11402static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11403 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11404 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11405 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11406 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11407 {}
11408};
11409
0e31daf7
J
11410static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11411 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11412 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11413 {}
11414};
11415
e2595322
DC
11416static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11417 /* Front Mic pin: input vref at 50% */
11418 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11419 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11420 {}
11421};
11422
834be88d 11423static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11424 .num_items = 3,
834be88d
TI
11425 .items = {
11426 { "Mic", 0x0 },
39d3ed38 11427 { "Int Mic", 0x1 },
834be88d
TI
11428 { "CD", 0x4 },
11429 },
11430};
11431
9c7f852e
TI
11432static struct hda_input_mux alc262_HP_capture_source = {
11433 .num_items = 5,
11434 .items = {
11435 { "Mic", 0x0 },
accbe498 11436 { "Front Mic", 0x1 },
9c7f852e
TI
11437 { "Line", 0x2 },
11438 { "CD", 0x4 },
11439 { "AUX IN", 0x6 },
11440 },
11441};
11442
accbe498 11443static struct hda_input_mux alc262_HP_D7000_capture_source = {
11444 .num_items = 4,
11445 .items = {
11446 { "Mic", 0x0 },
11447 { "Front Mic", 0x2 },
11448 { "Line", 0x1 },
11449 { "CD", 0x4 },
11450 },
11451};
11452
ebc7a406 11453/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
11454static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11455{
11456 struct alc_spec *spec = codec->spec;
11457 unsigned int mute;
11458
f12ab1e0 11459 if (force || !spec->sense_updated) {
864f92be
WF
11460 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11461 snd_hda_jack_detect(codec, 0x1b);
834be88d
TI
11462 spec->sense_updated = 1;
11463 }
ebc7a406
TI
11464 /* unmute internal speaker only if both HPs are unplugged and
11465 * master switch is on
11466 */
11467 if (spec->jack_present)
11468 mute = HDA_AMP_MUTE;
11469 else
834be88d 11470 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
11471 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11472 HDA_AMP_MUTE, mute);
834be88d
TI
11473}
11474
11475/* unsolicited event for HP jack sensing */
11476static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11477 unsigned int res)
11478{
11479 if ((res >> 26) != ALC_HP_EVENT)
11480 return;
11481 alc262_fujitsu_automute(codec, 1);
11482}
11483
ebc7a406
TI
11484static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11485{
11486 alc262_fujitsu_automute(codec, 1);
11487}
11488
834be88d 11489/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
11490static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11491 .ops = &snd_hda_bind_vol,
11492 .values = {
11493 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11494 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11495 0
11496 },
11497};
834be88d 11498
0e31daf7
J
11499/* mute/unmute internal speaker according to the hp jack and mute state */
11500static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11501{
11502 struct alc_spec *spec = codec->spec;
11503 unsigned int mute;
11504
11505 if (force || !spec->sense_updated) {
864f92be 11506 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
0e31daf7
J
11507 spec->sense_updated = 1;
11508 }
11509 if (spec->jack_present) {
11510 /* mute internal speaker */
11511 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11512 HDA_AMP_MUTE, HDA_AMP_MUTE);
11513 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11514 HDA_AMP_MUTE, HDA_AMP_MUTE);
11515 } else {
11516 /* unmute internal speaker if necessary */
11517 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11518 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11519 HDA_AMP_MUTE, mute);
11520 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11521 HDA_AMP_MUTE, mute);
11522 }
11523}
11524
11525/* unsolicited event for HP jack sensing */
11526static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11527 unsigned int res)
11528{
11529 if ((res >> 26) != ALC_HP_EVENT)
11530 return;
11531 alc262_lenovo_3000_automute(codec, 1);
11532}
11533
8de56b7d
TI
11534static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11535 int dir, int idx, long *valp)
11536{
11537 int i, change = 0;
11538
11539 for (i = 0; i < 2; i++, valp++)
11540 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11541 HDA_AMP_MUTE,
11542 *valp ? 0 : HDA_AMP_MUTE);
11543 return change;
11544}
11545
834be88d
TI
11546/* bind hp and internal speaker mute (with plug check) */
11547static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11548 struct snd_ctl_elem_value *ucontrol)
11549{
11550 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11551 long *valp = ucontrol->value.integer.value;
11552 int change;
11553
8de56b7d
TI
11554 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11555 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
82beb8fd
TI
11556 if (change)
11557 alc262_fujitsu_automute(codec, 0);
834be88d
TI
11558 return change;
11559}
11560
11561static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11562 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11563 {
11564 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11565 .name = "Master Playback Switch",
5e26dfd0 11566 .subdevice = HDA_SUBDEV_AMP_FLAG,
834be88d
TI
11567 .info = snd_hda_mixer_amp_switch_info,
11568 .get = snd_hda_mixer_amp_switch_get,
11569 .put = alc262_fujitsu_master_sw_put,
11570 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11571 },
5b0cb1d8
JK
11572 {
11573 .iface = NID_MAPPING,
11574 .name = "Master Playback Switch",
11575 .private_value = 0x1b,
11576 },
834be88d
TI
11577 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11578 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11579 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11580 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11581 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
11582 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11583 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11584 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11585 { } /* end */
11586};
11587
0e31daf7
J
11588/* bind hp and internal speaker mute (with plug check) */
11589static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11590 struct snd_ctl_elem_value *ucontrol)
11591{
11592 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11593 long *valp = ucontrol->value.integer.value;
11594 int change;
11595
8de56b7d 11596 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
0e31daf7
J
11597 if (change)
11598 alc262_lenovo_3000_automute(codec, 0);
11599 return change;
11600}
11601
11602static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11603 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11604 {
11605 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11606 .name = "Master Playback Switch",
5e26dfd0 11607 .subdevice = HDA_SUBDEV_AMP_FLAG,
0e31daf7
J
11608 .info = snd_hda_mixer_amp_switch_info,
11609 .get = snd_hda_mixer_amp_switch_get,
11610 .put = alc262_lenovo_3000_master_sw_put,
11611 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11612 },
11613 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11614 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11615 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11616 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11617 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11618 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11619 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11620 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11621 { } /* end */
11622};
11623
9f99a638
HM
11624static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11625 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11626 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11627 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11628 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11629 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11630 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11631 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11632 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11633 { } /* end */
11634};
11635
304dcaac
TI
11636/* additional init verbs for Benq laptops */
11637static struct hda_verb alc262_EAPD_verbs[] = {
11638 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11639 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11640 {}
11641};
11642
83c34218
KY
11643static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11644 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11645 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11646
11647 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11648 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11649 {}
11650};
11651
f651b50b
TD
11652/* Samsung Q1 Ultra Vista model setup */
11653static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11654 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11655 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11656 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11657 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11658 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 11659 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
11660 { } /* end */
11661};
11662
11663static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11664 /* output mixer */
11665 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11666 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11667 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11668 /* speaker */
11669 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11670 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11671 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11672 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11673 /* HP */
f651b50b 11674 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11675 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11676 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11677 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11678 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11679 /* internal mic */
11680 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11681 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11682 /* ADC, choose mic */
11683 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11684 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11685 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11686 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11687 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11688 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11689 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11690 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11691 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11692 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
11693 {}
11694};
11695
f651b50b
TD
11696/* mute/unmute internal speaker according to the hp jack and mute state */
11697static void alc262_ultra_automute(struct hda_codec *codec)
11698{
11699 struct alc_spec *spec = codec->spec;
11700 unsigned int mute;
f651b50b 11701
bb9f76cd
TI
11702 mute = 0;
11703 /* auto-mute only when HP is used as HP */
11704 if (!spec->cur_mux[0]) {
864f92be 11705 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
11706 if (spec->jack_present)
11707 mute = HDA_AMP_MUTE;
f651b50b 11708 }
bb9f76cd
TI
11709 /* mute/unmute internal speaker */
11710 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11711 HDA_AMP_MUTE, mute);
11712 /* mute/unmute HP */
11713 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11714 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
11715}
11716
11717/* unsolicited event for HP jack sensing */
11718static void alc262_ultra_unsol_event(struct hda_codec *codec,
11719 unsigned int res)
11720{
11721 if ((res >> 26) != ALC880_HP_EVENT)
11722 return;
11723 alc262_ultra_automute(codec);
11724}
11725
bb9f76cd
TI
11726static struct hda_input_mux alc262_ultra_capture_source = {
11727 .num_items = 2,
11728 .items = {
11729 { "Mic", 0x1 },
11730 { "Headphone", 0x7 },
11731 },
11732};
11733
11734static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11735 struct snd_ctl_elem_value *ucontrol)
11736{
11737 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11738 struct alc_spec *spec = codec->spec;
11739 int ret;
11740
54cbc9ab 11741 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
11742 if (!ret)
11743 return 0;
11744 /* reprogram the HP pin as mic or HP according to the input source */
11745 snd_hda_codec_write_cache(codec, 0x15, 0,
11746 AC_VERB_SET_PIN_WIDGET_CONTROL,
11747 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11748 alc262_ultra_automute(codec); /* mute/unmute HP */
11749 return ret;
11750}
11751
11752static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11753 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11754 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11755 {
11756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11757 .name = "Capture Source",
54cbc9ab
TI
11758 .info = alc_mux_enum_info,
11759 .get = alc_mux_enum_get,
bb9f76cd
TI
11760 .put = alc262_ultra_mux_enum_put,
11761 },
5b0cb1d8
JK
11762 {
11763 .iface = NID_MAPPING,
11764 .name = "Capture Source",
11765 .private_value = 0x15,
11766 },
bb9f76cd
TI
11767 { } /* end */
11768};
11769
c3fc1f50
TI
11770/* We use two mixers depending on the output pin; 0x16 is a mono output
11771 * and thus it's bound with a different mixer.
11772 * This function returns which mixer amp should be used.
11773 */
11774static int alc262_check_volbit(hda_nid_t nid)
11775{
11776 if (!nid)
11777 return 0;
11778 else if (nid == 0x16)
11779 return 2;
11780 else
11781 return 1;
11782}
11783
11784static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
11785 const char *pfx, int *vbits)
11786{
c3fc1f50
TI
11787 unsigned long val;
11788 int vbit;
11789
11790 vbit = alc262_check_volbit(nid);
11791 if (!vbit)
11792 return 0;
11793 if (*vbits & vbit) /* a volume control for this mixer already there */
11794 return 0;
11795 *vbits |= vbit;
c3fc1f50
TI
11796 if (vbit == 2)
11797 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11798 else
11799 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
0afe5f89 11800 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val);
c3fc1f50
TI
11801}
11802
11803static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
11804 const char *pfx)
11805{
c3fc1f50
TI
11806 unsigned long val;
11807
11808 if (!nid)
11809 return 0;
c3fc1f50
TI
11810 if (nid == 0x16)
11811 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11812 else
11813 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
0afe5f89 11814 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
c3fc1f50
TI
11815}
11816
df694daa 11817/* add playback controls from the parsed DAC table */
f12ab1e0
TI
11818static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11819 const struct auto_pin_cfg *cfg)
df694daa 11820{
c3fc1f50
TI
11821 const char *pfx;
11822 int vbits;
df694daa
KY
11823 int err;
11824
11825 spec->multiout.num_dacs = 1; /* only use one dac */
11826 spec->multiout.dac_nids = spec->private_dac_nids;
11827 spec->multiout.dac_nids[0] = 2;
11828
c3fc1f50
TI
11829 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
11830 pfx = "Master";
11831 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11832 pfx = "Speaker";
11833 else
11834 pfx = "Front";
11835 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx);
11836 if (err < 0)
11837 return err;
11838 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker");
11839 if (err < 0)
11840 return err;
11841 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone");
11842 if (err < 0)
11843 return err;
df694daa 11844
c3fc1f50
TI
11845 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
11846 alc262_check_volbit(cfg->speaker_pins[0]) |
11847 alc262_check_volbit(cfg->hp_pins[0]);
11848 if (vbits == 1 || vbits == 2)
11849 pfx = "Master"; /* only one mixer is used */
11850 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11851 pfx = "Speaker";
11852 else
11853 pfx = "Front";
11854 vbits = 0;
11855 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits);
11856 if (err < 0)
11857 return err;
11858 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker",
11859 &vbits);
11860 if (err < 0)
11861 return err;
11862 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone",
11863 &vbits);
11864 if (err < 0)
11865 return err;
f12ab1e0 11866 return 0;
df694daa
KY
11867}
11868
05f5f477 11869#define alc262_auto_create_input_ctls \
eaa9b3a7 11870 alc882_auto_create_input_ctls
df694daa
KY
11871
11872/*
11873 * generic initialization of ADC, input mixers and output mixers
11874 */
11875static struct hda_verb alc262_volume_init_verbs[] = {
11876 /*
11877 * Unmute ADC0-2 and set the default input to mic-in
11878 */
11879 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11880 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11881 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11882 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11883 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11884 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11885
cb53c626 11886 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 11887 * mixer widget
f12ab1e0
TI
11888 * Note: PASD motherboards uses the Line In 2 as the input for
11889 * front panel mic (mic 2)
df694daa
KY
11890 */
11891 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11892 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11893 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11894 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11895 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11896 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
11897
11898 /*
11899 * Set up output mixers (0x0c - 0x0f)
11900 */
11901 /* set vol=0 to output mixers */
11902 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11903 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11904 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 11905
df694daa
KY
11906 /* set up input amps for analog loopback */
11907 /* Amp Indices: DAC = 0, mixer = 1 */
11908 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11909 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11910 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11911 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11912 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11913 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11914
11915 /* FIXME: use matrix-type input source selection */
11916 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11917 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11918 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11919 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11920 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11921 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11922 /* Input mixer2 */
11923 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11924 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11925 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11926 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11927 /* Input mixer3 */
11928 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11929 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11930 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11931 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11932
11933 { }
11934};
11935
9c7f852e
TI
11936static struct hda_verb alc262_HP_BPC_init_verbs[] = {
11937 /*
11938 * Unmute ADC0-2 and set the default input to mic-in
11939 */
11940 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11941 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11942 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11943 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11944 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11945 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11946
cb53c626 11947 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11948 * mixer widget
f12ab1e0
TI
11949 * Note: PASD motherboards uses the Line In 2 as the input for
11950 * front panel mic (mic 2)
9c7f852e
TI
11951 */
11952 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11953 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11954 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11955 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11956 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11957 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11958 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11959 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 11960
9c7f852e
TI
11961 /*
11962 * Set up output mixers (0x0c - 0x0e)
11963 */
11964 /* set vol=0 to output mixers */
11965 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11966 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11967 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11968
11969 /* set up input amps for analog loopback */
11970 /* Amp Indices: DAC = 0, mixer = 1 */
11971 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11972 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11973 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11974 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11975 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11976 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11977
ce875f07 11978 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
11979 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11980 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11981
11982 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11983 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11984
11985 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11986 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11987
11988 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11989 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11990 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11991 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11992 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11993
0e4835c1 11994 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
11995 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11996 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 11997 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
11998 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11999 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12000
12001
12002 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12003 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12004 /* Input mixer1: only unmute Mic */
9c7f852e 12005 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12006 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12007 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12008 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12009 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12010 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12011 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12012 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12013 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12014 /* Input mixer2 */
12015 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12016 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12017 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12018 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12019 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12020 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12021 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12022 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12023 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12024 /* Input mixer3 */
12025 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12026 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12027 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12028 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12029 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12030 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12031 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12032 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12033 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12034
ce875f07
TI
12035 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12036
9c7f852e
TI
12037 { }
12038};
12039
cd7509a4
KY
12040static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12041 /*
12042 * Unmute ADC0-2 and set the default input to mic-in
12043 */
12044 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12045 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12046 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12047 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12048 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12049 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12050
cb53c626 12051 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12052 * mixer widget
12053 * Note: PASD motherboards uses the Line In 2 as the input for front
12054 * panel mic (mic 2)
12055 */
12056 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12057 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12058 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12059 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12060 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12061 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12062 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12063 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12064 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12065 /*
12066 * Set up output mixers (0x0c - 0x0e)
12067 */
12068 /* set vol=0 to output mixers */
12069 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12070 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12071 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12072
12073 /* set up input amps for analog loopback */
12074 /* Amp Indices: DAC = 0, mixer = 1 */
12075 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12076 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12077 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12078 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12079 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12080 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12081
12082
12083 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12084 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12085 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12086 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12087 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12088 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12089 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12090
12091 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12092 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12093
12094 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12095 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12096
12097 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12098 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12099 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12100 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12101 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12102 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12103
12104 /* FIXME: use matrix-type input source selection */
12105 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12106 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12107 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12108 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12109 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12110 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12111 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12112 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12113 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12114 /* Input mixer2 */
12115 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12116 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12117 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12118 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12119 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12120 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12121 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12122 /* Input mixer3 */
12123 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12124 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12125 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12126 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12127 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12128 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12129 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12130
ce875f07
TI
12131 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12132
cd7509a4
KY
12133 { }
12134};
12135
9f99a638
HM
12136static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12137
12138 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12139 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12140 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12141
12142 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12143 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12144 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12145 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12146
12147 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12148 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12149 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12150 {}
12151};
12152
12153
cb53c626
TI
12154#ifdef CONFIG_SND_HDA_POWER_SAVE
12155#define alc262_loopbacks alc880_loopbacks
12156#endif
12157
def319f9 12158/* pcm configuration: identical with ALC880 */
df694daa
KY
12159#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12160#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12161#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12162#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12163
12164/*
12165 * BIOS auto configuration
12166 */
12167static int alc262_parse_auto_config(struct hda_codec *codec)
12168{
12169 struct alc_spec *spec = codec->spec;
12170 int err;
12171 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12172
f12ab1e0
TI
12173 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12174 alc262_ignore);
12175 if (err < 0)
df694daa 12176 return err;
e64f14f4 12177 if (!spec->autocfg.line_outs) {
0852d7a6 12178 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12179 spec->multiout.max_channels = 2;
12180 spec->no_analog = 1;
12181 goto dig_only;
12182 }
df694daa 12183 return 0; /* can't find valid BIOS pin config */
e64f14f4 12184 }
f12ab1e0
TI
12185 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12186 if (err < 0)
12187 return err;
05f5f477 12188 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12189 if (err < 0)
df694daa
KY
12190 return err;
12191
12192 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12193
e64f14f4 12194 dig_only:
757899ac 12195 alc_auto_parse_digital(codec);
df694daa 12196
603c4019 12197 if (spec->kctls.list)
d88897ea 12198 add_mixer(spec, spec->kctls.list);
df694daa 12199
d88897ea 12200 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12201 spec->num_mux_defs = 1;
61b9b9b1 12202 spec->input_mux = &spec->private_imux[0];
df694daa 12203
776e184e
TI
12204 err = alc_auto_add_mic_boost(codec);
12205 if (err < 0)
12206 return err;
12207
6227cdce 12208 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12209
df694daa
KY
12210 return 1;
12211}
12212
12213#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12214#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12215#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12216#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12217
12218
12219/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12220static void alc262_auto_init(struct hda_codec *codec)
df694daa 12221{
f6c7e546 12222 struct alc_spec *spec = codec->spec;
df694daa
KY
12223 alc262_auto_init_multi_out(codec);
12224 alc262_auto_init_hp_out(codec);
12225 alc262_auto_init_analog_input(codec);
f511b01c 12226 alc262_auto_init_input_src(codec);
757899ac 12227 alc_auto_init_digital(codec);
f6c7e546 12228 if (spec->unsol_event)
7fb0d78f 12229 alc_inithook(codec);
df694daa
KY
12230}
12231
12232/*
12233 * configuration and preset
12234 */
f5fcc13c
TI
12235static const char *alc262_models[ALC262_MODEL_LAST] = {
12236 [ALC262_BASIC] = "basic",
12237 [ALC262_HIPPO] = "hippo",
12238 [ALC262_HIPPO_1] = "hippo_1",
12239 [ALC262_FUJITSU] = "fujitsu",
12240 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12241 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12242 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12243 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12244 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12245 [ALC262_BENQ_T31] = "benq-t31",
12246 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12247 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12248 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12249 [ALC262_ULTRA] = "ultra",
0e31daf7 12250 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12251 [ALC262_NEC] = "nec",
ba340e82 12252 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12253 [ALC262_AUTO] = "auto",
12254};
12255
12256static struct snd_pci_quirk alc262_cfg_tbl[] = {
12257 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12258 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12259 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12260 ALC262_HP_BPC),
12261 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12262 ALC262_HP_BPC),
53eff7e1
TI
12263 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12264 ALC262_HP_BPC),
cd7509a4 12265 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12266 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12267 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12268 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12269 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12270 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12271 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12272 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12273 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12274 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12275 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12276 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12277 ALC262_HP_TC_T5735),
8c427226 12278 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12279 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12280 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12281 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12282 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12283 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12284 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12285 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12286#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12287 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12288 ALC262_SONY_ASSAMD),
c5b5165c 12289#endif
36ca6e13 12290 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12291 ALC262_TOSHIBA_RX1),
80ffe869 12292 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12293 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12294 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12295 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12296 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12297 ALC262_ULTRA),
3e420e78 12298 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12299 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12300 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12301 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12302 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12303 {}
12304};
12305
12306static struct alc_config_preset alc262_presets[] = {
12307 [ALC262_BASIC] = {
12308 .mixers = { alc262_base_mixer },
12309 .init_verbs = { alc262_init_verbs },
12310 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12311 .dac_nids = alc262_dac_nids,
12312 .hp_nid = 0x03,
12313 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12314 .channel_mode = alc262_modes,
a3bcba38 12315 .input_mux = &alc262_capture_source,
df694daa 12316 },
ccc656ce 12317 [ALC262_HIPPO] = {
42171c17 12318 .mixers = { alc262_hippo_mixer },
6732bd0d 12319 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12320 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12321 .dac_nids = alc262_dac_nids,
12322 .hp_nid = 0x03,
12323 .dig_out_nid = ALC262_DIGOUT_NID,
12324 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12325 .channel_mode = alc262_modes,
12326 .input_mux = &alc262_capture_source,
12327 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12328 .setup = alc262_hippo_setup,
12329 .init_hook = alc262_hippo_automute,
ccc656ce
KY
12330 },
12331 [ALC262_HIPPO_1] = {
12332 .mixers = { alc262_hippo1_mixer },
12333 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12334 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12335 .dac_nids = alc262_dac_nids,
12336 .hp_nid = 0x02,
12337 .dig_out_nid = ALC262_DIGOUT_NID,
12338 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12339 .channel_mode = alc262_modes,
12340 .input_mux = &alc262_capture_source,
42171c17 12341 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12342 .setup = alc262_hippo1_setup,
12343 .init_hook = alc262_hippo_automute,
ccc656ce 12344 },
834be88d
TI
12345 [ALC262_FUJITSU] = {
12346 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12347 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12348 alc262_fujitsu_unsol_verbs },
834be88d
TI
12349 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12350 .dac_nids = alc262_dac_nids,
12351 .hp_nid = 0x03,
12352 .dig_out_nid = ALC262_DIGOUT_NID,
12353 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12354 .channel_mode = alc262_modes,
12355 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 12356 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 12357 .init_hook = alc262_fujitsu_init_hook,
834be88d 12358 },
9c7f852e
TI
12359 [ALC262_HP_BPC] = {
12360 .mixers = { alc262_HP_BPC_mixer },
12361 .init_verbs = { alc262_HP_BPC_init_verbs },
12362 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12363 .dac_nids = alc262_dac_nids,
12364 .hp_nid = 0x03,
12365 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12366 .channel_mode = alc262_modes,
12367 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
12368 .unsol_event = alc262_hp_bpc_unsol_event,
12369 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 12370 },
cd7509a4
KY
12371 [ALC262_HP_BPC_D7000_WF] = {
12372 .mixers = { alc262_HP_BPC_WildWest_mixer },
12373 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12374 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12375 .dac_nids = alc262_dac_nids,
12376 .hp_nid = 0x03,
12377 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12378 .channel_mode = alc262_modes,
accbe498 12379 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12380 .unsol_event = alc262_hp_wildwest_unsol_event,
12381 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12382 },
cd7509a4
KY
12383 [ALC262_HP_BPC_D7000_WL] = {
12384 .mixers = { alc262_HP_BPC_WildWest_mixer,
12385 alc262_HP_BPC_WildWest_option_mixer },
12386 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12387 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12388 .dac_nids = alc262_dac_nids,
12389 .hp_nid = 0x03,
12390 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12391 .channel_mode = alc262_modes,
accbe498 12392 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
12393 .unsol_event = alc262_hp_wildwest_unsol_event,
12394 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 12395 },
66d2a9d6
KY
12396 [ALC262_HP_TC_T5735] = {
12397 .mixers = { alc262_hp_t5735_mixer },
12398 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12399 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12400 .dac_nids = alc262_dac_nids,
12401 .hp_nid = 0x03,
12402 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12403 .channel_mode = alc262_modes,
12404 .input_mux = &alc262_capture_source,
dc99be47 12405 .unsol_event = alc_sku_unsol_event,
4f5d1706 12406 .setup = alc262_hp_t5735_setup,
dc99be47 12407 .init_hook = alc_inithook,
8c427226
KY
12408 },
12409 [ALC262_HP_RP5700] = {
12410 .mixers = { alc262_hp_rp5700_mixer },
12411 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12412 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12413 .dac_nids = alc262_dac_nids,
12414 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12415 .channel_mode = alc262_modes,
12416 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12417 },
304dcaac
TI
12418 [ALC262_BENQ_ED8] = {
12419 .mixers = { alc262_base_mixer },
12420 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12421 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12422 .dac_nids = alc262_dac_nids,
12423 .hp_nid = 0x03,
12424 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12425 .channel_mode = alc262_modes,
12426 .input_mux = &alc262_capture_source,
f12ab1e0 12427 },
272a527c
KY
12428 [ALC262_SONY_ASSAMD] = {
12429 .mixers = { alc262_sony_mixer },
12430 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12431 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12432 .dac_nids = alc262_dac_nids,
12433 .hp_nid = 0x02,
12434 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12435 .channel_mode = alc262_modes,
12436 .input_mux = &alc262_capture_source,
12437 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12438 .setup = alc262_hippo_setup,
12439 .init_hook = alc262_hippo_automute,
83c34218
KY
12440 },
12441 [ALC262_BENQ_T31] = {
12442 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12443 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12444 alc_hp15_unsol_verbs },
83c34218
KY
12445 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12446 .dac_nids = alc262_dac_nids,
12447 .hp_nid = 0x03,
12448 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12449 .channel_mode = alc262_modes,
12450 .input_mux = &alc262_capture_source,
12451 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12452 .setup = alc262_hippo_setup,
12453 .init_hook = alc262_hippo_automute,
ea1fb29a 12454 },
f651b50b 12455 [ALC262_ULTRA] = {
f9e336f6
TI
12456 .mixers = { alc262_ultra_mixer },
12457 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12458 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12459 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12460 .dac_nids = alc262_dac_nids,
f651b50b
TD
12461 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12462 .channel_mode = alc262_modes,
12463 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12464 .adc_nids = alc262_adc_nids, /* ADC0 */
12465 .capsrc_nids = alc262_capsrc_nids,
12466 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12467 .unsol_event = alc262_ultra_unsol_event,
12468 .init_hook = alc262_ultra_automute,
12469 },
0e31daf7
J
12470 [ALC262_LENOVO_3000] = {
12471 .mixers = { alc262_lenovo_3000_mixer },
12472 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12473 alc262_lenovo_3000_unsol_verbs,
12474 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12475 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12476 .dac_nids = alc262_dac_nids,
12477 .hp_nid = 0x03,
12478 .dig_out_nid = ALC262_DIGOUT_NID,
12479 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12480 .channel_mode = alc262_modes,
12481 .input_mux = &alc262_fujitsu_capture_source,
12482 .unsol_event = alc262_lenovo_3000_unsol_event,
12483 },
e8f9ae2a
PT
12484 [ALC262_NEC] = {
12485 .mixers = { alc262_nec_mixer },
12486 .init_verbs = { alc262_nec_verbs },
12487 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12488 .dac_nids = alc262_dac_nids,
12489 .hp_nid = 0x03,
12490 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12491 .channel_mode = alc262_modes,
12492 .input_mux = &alc262_capture_source,
12493 },
4e555fe5
KY
12494 [ALC262_TOSHIBA_S06] = {
12495 .mixers = { alc262_toshiba_s06_mixer },
12496 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12497 alc262_eapd_verbs },
12498 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12499 .capsrc_nids = alc262_dmic_capsrc_nids,
12500 .dac_nids = alc262_dac_nids,
12501 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12502 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12503 .dig_out_nid = ALC262_DIGOUT_NID,
12504 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12505 .channel_mode = alc262_modes,
4f5d1706
TI
12506 .unsol_event = alc_sku_unsol_event,
12507 .setup = alc262_toshiba_s06_setup,
12508 .init_hook = alc_inithook,
4e555fe5 12509 },
9f99a638
HM
12510 [ALC262_TOSHIBA_RX1] = {
12511 .mixers = { alc262_toshiba_rx1_mixer },
12512 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12513 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12514 .dac_nids = alc262_dac_nids,
12515 .hp_nid = 0x03,
12516 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12517 .channel_mode = alc262_modes,
12518 .input_mux = &alc262_capture_source,
12519 .unsol_event = alc262_hippo_unsol_event,
4f5d1706
TI
12520 .setup = alc262_hippo_setup,
12521 .init_hook = alc262_hippo_automute,
9f99a638 12522 },
ba340e82
TV
12523 [ALC262_TYAN] = {
12524 .mixers = { alc262_tyan_mixer },
12525 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12526 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12527 .dac_nids = alc262_dac_nids,
12528 .hp_nid = 0x02,
12529 .dig_out_nid = ALC262_DIGOUT_NID,
12530 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12531 .channel_mode = alc262_modes,
12532 .input_mux = &alc262_capture_source,
a9fd4f3f 12533 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
12534 .setup = alc262_tyan_setup,
12535 .init_hook = alc_automute_amp,
ba340e82 12536 },
df694daa
KY
12537};
12538
12539static int patch_alc262(struct hda_codec *codec)
12540{
12541 struct alc_spec *spec;
12542 int board_config;
12543 int err;
12544
dc041e0b 12545 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12546 if (spec == NULL)
12547 return -ENOMEM;
12548
12549 codec->spec = spec;
12550#if 0
f12ab1e0
TI
12551 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12552 * under-run
12553 */
df694daa
KY
12554 {
12555 int tmp;
12556 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12557 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12558 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12559 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12560 }
12561#endif
da00c244 12562 alc_auto_parse_customize_define(codec);
df694daa 12563
2c3bf9ab
TI
12564 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12565
f5fcc13c
TI
12566 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12567 alc262_models,
12568 alc262_cfg_tbl);
cd7509a4 12569
f5fcc13c 12570 if (board_config < 0) {
9a11f1aa
TI
12571 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12572 codec->chip_name);
df694daa
KY
12573 board_config = ALC262_AUTO;
12574 }
12575
12576 if (board_config == ALC262_AUTO) {
12577 /* automatic parse from the BIOS config */
12578 err = alc262_parse_auto_config(codec);
12579 if (err < 0) {
12580 alc_free(codec);
12581 return err;
f12ab1e0 12582 } else if (!err) {
9c7f852e
TI
12583 printk(KERN_INFO
12584 "hda_codec: Cannot set up configuration "
12585 "from BIOS. Using base mode...\n");
df694daa
KY
12586 board_config = ALC262_BASIC;
12587 }
12588 }
12589
dc1eae25 12590 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12591 err = snd_hda_attach_beep_device(codec, 0x1);
12592 if (err < 0) {
12593 alc_free(codec);
12594 return err;
12595 }
680cd536
KK
12596 }
12597
df694daa 12598 if (board_config != ALC262_AUTO)
e9c364c0 12599 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12600
df694daa
KY
12601 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12602 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12603
df694daa
KY
12604 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12605 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12606
f12ab1e0 12607 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12608 int i;
12609 /* check whether the digital-mic has to be supported */
12610 for (i = 0; i < spec->input_mux->num_items; i++) {
12611 if (spec->input_mux->items[i].index >= 9)
12612 break;
12613 }
12614 if (i < spec->input_mux->num_items) {
12615 /* use only ADC0 */
12616 spec->adc_nids = alc262_dmic_adc_nids;
12617 spec->num_adc_nids = 1;
12618 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 12619 } else {
8c927b4a
TI
12620 /* all analog inputs */
12621 /* check whether NID 0x07 is valid */
12622 unsigned int wcap = get_wcaps(codec, 0x07);
12623
12624 /* get type */
a22d543a 12625 wcap = get_wcaps_type(wcap);
8c927b4a
TI
12626 if (wcap != AC_WID_AUD_IN) {
12627 spec->adc_nids = alc262_adc_nids_alt;
12628 spec->num_adc_nids =
12629 ARRAY_SIZE(alc262_adc_nids_alt);
12630 spec->capsrc_nids = alc262_capsrc_nids_alt;
12631 } else {
12632 spec->adc_nids = alc262_adc_nids;
12633 spec->num_adc_nids =
12634 ARRAY_SIZE(alc262_adc_nids);
12635 spec->capsrc_nids = alc262_capsrc_nids;
12636 }
df694daa
KY
12637 }
12638 }
e64f14f4 12639 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12640 set_capture_mixer(codec);
dc1eae25 12641 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 12642 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12643
2134ea4f
TI
12644 spec->vmaster_nid = 0x0c;
12645
df694daa
KY
12646 codec->patch_ops = alc_patch_ops;
12647 if (board_config == ALC262_AUTO)
ae6b813a 12648 spec->init_hook = alc262_auto_init;
cb53c626
TI
12649#ifdef CONFIG_SND_HDA_POWER_SAVE
12650 if (!spec->loopback.amplist)
12651 spec->loopback.amplist = alc262_loopbacks;
12652#endif
ea1fb29a 12653
df694daa
KY
12654 return 0;
12655}
12656
a361d84b
KY
12657/*
12658 * ALC268 channel source setting (2 channel)
12659 */
12660#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12661#define alc268_modes alc260_modes
ea1fb29a 12662
a361d84b
KY
12663static hda_nid_t alc268_dac_nids[2] = {
12664 /* front, hp */
12665 0x02, 0x03
12666};
12667
12668static hda_nid_t alc268_adc_nids[2] = {
12669 /* ADC0-1 */
12670 0x08, 0x07
12671};
12672
12673static hda_nid_t alc268_adc_nids_alt[1] = {
12674 /* ADC0 */
12675 0x08
12676};
12677
e1406348
TI
12678static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12679
a361d84b
KY
12680static struct snd_kcontrol_new alc268_base_mixer[] = {
12681 /* output mixer control */
12682 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12683 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12684 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12685 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
12686 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12687 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12688 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
12689 { }
12690};
12691
42171c17
TI
12692static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12693 /* output mixer control */
12694 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12695 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12696 ALC262_HIPPO_MASTER_SWITCH,
12697 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12698 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12699 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12700 { }
12701};
12702
aef9d318
TI
12703/* bind Beep switches of both NID 0x0f and 0x10 */
12704static struct hda_bind_ctls alc268_bind_beep_sw = {
12705 .ops = &snd_hda_bind_sw,
12706 .values = {
12707 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12708 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12709 0
12710 },
12711};
12712
12713static struct snd_kcontrol_new alc268_beep_mixer[] = {
12714 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12715 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12716 { }
12717};
12718
d1a991a6
KY
12719static struct hda_verb alc268_eapd_verbs[] = {
12720 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12721 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12722 { }
12723};
12724
d273809e 12725/* Toshiba specific */
d273809e
TI
12726static struct hda_verb alc268_toshiba_verbs[] = {
12727 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12728 { } /* end */
12729};
12730
12731/* Acer specific */
889c4395 12732/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
12733static struct hda_bind_ctls alc268_acer_bind_master_vol = {
12734 .ops = &snd_hda_bind_vol,
12735 .values = {
12736 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12737 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12738 0
12739 },
12740};
12741
889c4395
TI
12742/* mute/unmute internal speaker according to the hp jack and mute state */
12743static void alc268_acer_automute(struct hda_codec *codec, int force)
12744{
12745 struct alc_spec *spec = codec->spec;
12746 unsigned int mute;
12747
12748 if (force || !spec->sense_updated) {
864f92be 12749 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
889c4395
TI
12750 spec->sense_updated = 1;
12751 }
12752 if (spec->jack_present)
12753 mute = HDA_AMP_MUTE; /* mute internal speaker */
12754 else /* unmute internal speaker if necessary */
12755 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
12756 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12757 HDA_AMP_MUTE, mute);
12758}
12759
12760
12761/* bind hp and internal speaker mute (with plug check) */
12762static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
12763 struct snd_ctl_elem_value *ucontrol)
12764{
12765 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12766 long *valp = ucontrol->value.integer.value;
12767 int change;
12768
8de56b7d 12769 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
889c4395
TI
12770 if (change)
12771 alc268_acer_automute(codec, 0);
12772 return change;
12773}
d273809e 12774
8ef355da
KY
12775static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12776 /* output mixer control */
12777 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12778 {
12779 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12780 .name = "Master Playback Switch",
5e26dfd0 12781 .subdevice = HDA_SUBDEV_AMP_FLAG,
8ef355da
KY
12782 .info = snd_hda_mixer_amp_switch_info,
12783 .get = snd_hda_mixer_amp_switch_get,
12784 .put = alc268_acer_master_sw_put,
12785 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12786 },
12787 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12788 { }
12789};
12790
d273809e
TI
12791static struct snd_kcontrol_new alc268_acer_mixer[] = {
12792 /* output mixer control */
12793 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12794 {
12795 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12796 .name = "Master Playback Switch",
5e26dfd0 12797 .subdevice = HDA_SUBDEV_AMP_FLAG,
d273809e
TI
12798 .info = snd_hda_mixer_amp_switch_info,
12799 .get = snd_hda_mixer_amp_switch_get,
12800 .put = alc268_acer_master_sw_put,
12801 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12802 },
33bf17ab
TI
12803 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12804 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12805 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
12806 { }
12807};
12808
c238b4f4
TI
12809static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12810 /* output mixer control */
12811 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12812 {
12813 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12814 .name = "Master Playback Switch",
5e26dfd0 12815 .subdevice = HDA_SUBDEV_AMP_FLAG,
c238b4f4
TI
12816 .info = snd_hda_mixer_amp_switch_info,
12817 .get = snd_hda_mixer_amp_switch_get,
12818 .put = alc268_acer_master_sw_put,
12819 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12820 },
12821 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12822 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12823 { }
12824};
12825
8ef355da
KY
12826static struct hda_verb alc268_acer_aspire_one_verbs[] = {
12827 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12828 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12829 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12830 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12831 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12832 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12833 { }
12834};
12835
d273809e 12836static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
12837 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12838 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
12839 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12840 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
12841 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12842 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
12843 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12844 { }
12845};
12846
12847/* unsolicited event for HP jack sensing */
42171c17 12848#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
4f5d1706
TI
12849#define alc268_toshiba_setup alc262_hippo_setup
12850#define alc268_toshiba_automute alc262_hippo_automute
d273809e
TI
12851
12852static void alc268_acer_unsol_event(struct hda_codec *codec,
12853 unsigned int res)
12854{
889c4395 12855 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
12856 return;
12857 alc268_acer_automute(codec, 1);
12858}
12859
889c4395
TI
12860static void alc268_acer_init_hook(struct hda_codec *codec)
12861{
12862 alc268_acer_automute(codec, 1);
12863}
12864
8ef355da
KY
12865/* toggle speaker-output according to the hp-jack state */
12866static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
12867{
12868 unsigned int present;
12869 unsigned char bits;
12870
864f92be 12871 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 12872 bits = present ? HDA_AMP_MUTE : 0;
8ef355da 12873 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
5dbd5ec6 12874 HDA_AMP_MUTE, bits);
8ef355da 12875 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
5dbd5ec6 12876 HDA_AMP_MUTE, bits);
8ef355da
KY
12877}
12878
8ef355da
KY
12879static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
12880 unsigned int res)
12881{
4f5d1706
TI
12882 switch (res >> 26) {
12883 case ALC880_HP_EVENT:
8ef355da 12884 alc268_aspire_one_speaker_automute(codec);
4f5d1706
TI
12885 break;
12886 case ALC880_MIC_EVENT:
12887 alc_mic_automute(codec);
12888 break;
12889 }
12890}
12891
12892static void alc268_acer_lc_setup(struct hda_codec *codec)
12893{
12894 struct alc_spec *spec = codec->spec;
12895 spec->ext_mic.pin = 0x18;
12896 spec->ext_mic.mux_idx = 0;
12897 spec->int_mic.pin = 0x12;
12898 spec->int_mic.mux_idx = 6;
12899 spec->auto_mic = 1;
8ef355da
KY
12900}
12901
12902static void alc268_acer_lc_init_hook(struct hda_codec *codec)
12903{
12904 alc268_aspire_one_speaker_automute(codec);
4f5d1706 12905 alc_mic_automute(codec);
8ef355da
KY
12906}
12907
3866f0b0
TI
12908static struct snd_kcontrol_new alc268_dell_mixer[] = {
12909 /* output mixer control */
12910 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12911 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12912 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12913 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12914 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12915 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12916 { }
12917};
12918
12919static struct hda_verb alc268_dell_verbs[] = {
12920 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12921 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12922 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 12923 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
12924 { }
12925};
12926
12927/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 12928static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 12929{
a9fd4f3f 12930 struct alc_spec *spec = codec->spec;
3866f0b0 12931
a9fd4f3f
TI
12932 spec->autocfg.hp_pins[0] = 0x15;
12933 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12934 spec->ext_mic.pin = 0x18;
12935 spec->ext_mic.mux_idx = 0;
12936 spec->int_mic.pin = 0x19;
12937 spec->int_mic.mux_idx = 1;
12938 spec->auto_mic = 1;
3866f0b0
TI
12939}
12940
eb5a6621
HRK
12941static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12942 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12943 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12944 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12945 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12946 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12947 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12948 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12949 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12950 { }
12951};
12952
12953static struct hda_verb alc267_quanta_il1_verbs[] = {
12954 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12955 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12956 { }
12957};
12958
4f5d1706 12959static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 12960{
a9fd4f3f 12961 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
12962 spec->autocfg.hp_pins[0] = 0x15;
12963 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12964 spec->ext_mic.pin = 0x18;
12965 spec->ext_mic.mux_idx = 0;
12966 spec->int_mic.pin = 0x19;
12967 spec->int_mic.mux_idx = 1;
12968 spec->auto_mic = 1;
eb5a6621
HRK
12969}
12970
a361d84b
KY
12971/*
12972 * generic initialization of ADC, input mixers and output mixers
12973 */
12974static struct hda_verb alc268_base_init_verbs[] = {
12975 /* Unmute DAC0-1 and set vol = 0 */
12976 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 12977 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
12978
12979 /*
12980 * Set up output mixers (0x0c - 0x0e)
12981 */
12982 /* set vol=0 to output mixers */
12983 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
12984 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12985
12986 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12987 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12988
12989 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12990 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12991 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12992 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12993 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12994 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12995 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12996 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12997
12998 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12999 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13000 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13001 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13002 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13003
13004 /* set PCBEEP vol = 0, mute connections */
13005 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13006 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13007 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13008
a9b3aa8a 13009 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13010
a9b3aa8a
JZ
13011 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13012 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13013 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13014 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13015
a361d84b
KY
13016 { }
13017};
13018
13019/*
13020 * generic initialization of ADC, input mixers and output mixers
13021 */
13022static struct hda_verb alc268_volume_init_verbs[] = {
13023 /* set output DAC */
4cfb91c6
TI
13024 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13025 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13026
13027 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13028 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13029 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13030 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13031 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13032
a361d84b 13033 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13034 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13035 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13036
13037 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13038 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13039
aef9d318
TI
13040 /* set PCBEEP vol = 0, mute connections */
13041 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13042 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13043 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13044
13045 { }
13046};
13047
fdbc6626
TI
13048static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13049 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13050 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13051 { } /* end */
13052};
13053
a361d84b
KY
13054static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13055 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13056 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13057 _DEFINE_CAPSRC(1),
a361d84b
KY
13058 { } /* end */
13059};
13060
13061static struct snd_kcontrol_new alc268_capture_mixer[] = {
13062 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13063 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13064 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13065 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13066 _DEFINE_CAPSRC(2),
a361d84b
KY
13067 { } /* end */
13068};
13069
13070static struct hda_input_mux alc268_capture_source = {
13071 .num_items = 4,
13072 .items = {
13073 { "Mic", 0x0 },
13074 { "Front Mic", 0x1 },
13075 { "Line", 0x2 },
13076 { "CD", 0x3 },
13077 },
13078};
13079
0ccb541c 13080static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13081 .num_items = 3,
13082 .items = {
13083 { "Mic", 0x0 },
13084 { "Internal Mic", 0x1 },
13085 { "Line", 0x2 },
13086 },
13087};
13088
13089static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13090 .num_items = 3,
13091 .items = {
13092 { "Mic", 0x0 },
13093 { "Internal Mic", 0x6 },
13094 { "Line", 0x2 },
13095 },
13096};
13097
86c53bd2
JW
13098#ifdef CONFIG_SND_DEBUG
13099static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13100 /* Volume widgets */
13101 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13102 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13103 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13104 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13105 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13106 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13107 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13108 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13109 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13110 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13111 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13112 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13113 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13114 /* The below appears problematic on some hardwares */
13115 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13116 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13117 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13118 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13119 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13120
13121 /* Modes for retasking pin widgets */
13122 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13123 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13124 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13125 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13126
13127 /* Controls for GPIO pins, assuming they are configured as outputs */
13128 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13129 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13130 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13131 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13132
13133 /* Switches to allow the digital SPDIF output pin to be enabled.
13134 * The ALC268 does not have an SPDIF input.
13135 */
13136 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13137
13138 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13139 * this output to turn on an external amplifier.
13140 */
13141 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13142 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13143
13144 { } /* end */
13145};
13146#endif
13147
a361d84b
KY
13148/* create input playback/capture controls for the given pin */
13149static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13150 const char *ctlname, int idx)
13151{
3f3b7c1a 13152 hda_nid_t dac;
a361d84b
KY
13153 int err;
13154
3f3b7c1a
TI
13155 switch (nid) {
13156 case 0x14:
13157 case 0x16:
13158 dac = 0x02;
13159 break;
13160 case 0x15:
b08b1637
TI
13161 case 0x1a: /* ALC259/269 only */
13162 case 0x1b: /* ALC259/269 only */
531d8791 13163 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13164 dac = 0x03;
13165 break;
13166 default:
c7a9434d
TI
13167 snd_printd(KERN_WARNING "hda_codec: "
13168 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13169 return 0;
13170 }
13171 if (spec->multiout.dac_nids[0] != dac &&
13172 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13173 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13174 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13175 HDA_OUTPUT));
13176 if (err < 0)
13177 return err;
3f3b7c1a
TI
13178 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13179 }
13180
3f3b7c1a 13181 if (nid != 0x16)
0afe5f89 13182 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13183 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13184 else /* mono */
0afe5f89 13185 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13186 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13187 if (err < 0)
13188 return err;
13189 return 0;
13190}
13191
13192/* add playback controls from the parsed DAC table */
13193static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13194 const struct auto_pin_cfg *cfg)
13195{
13196 hda_nid_t nid;
13197 int err;
13198
a361d84b 13199 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13200
13201 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13202 if (nid) {
13203 const char *name;
13204 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13205 name = "Speaker";
13206 else
13207 name = "Front";
13208 err = alc268_new_analog_output(spec, nid, name, 0);
13209 if (err < 0)
13210 return err;
13211 }
a361d84b
KY
13212
13213 nid = cfg->speaker_pins[0];
13214 if (nid == 0x1d) {
0afe5f89 13215 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13216 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13217 if (err < 0)
13218 return err;
3f3b7c1a
TI
13219 } else {
13220 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13221 if (err < 0)
13222 return err;
a361d84b
KY
13223 }
13224 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13225 if (nid) {
13226 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13227 if (err < 0)
13228 return err;
13229 }
a361d84b
KY
13230
13231 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13232 if (nid == 0x16) {
0afe5f89 13233 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13234 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13235 if (err < 0)
13236 return err;
13237 }
ea1fb29a 13238 return 0;
a361d84b
KY
13239}
13240
13241/* create playback/capture controls for input pins */
05f5f477 13242static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13243 const struct auto_pin_cfg *cfg)
13244{
05f5f477 13245 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13246}
13247
e9af4f36
TI
13248static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13249 hda_nid_t nid, int pin_type)
13250{
13251 int idx;
13252
13253 alc_set_pin_output(codec, nid, pin_type);
13254 if (nid == 0x14 || nid == 0x16)
13255 idx = 0;
13256 else
13257 idx = 1;
13258 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13259}
13260
13261static void alc268_auto_init_multi_out(struct hda_codec *codec)
13262{
13263 struct alc_spec *spec = codec->spec;
13264 hda_nid_t nid = spec->autocfg.line_out_pins[0];
13265 if (nid) {
13266 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13267 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13268 }
13269}
13270
13271static void alc268_auto_init_hp_out(struct hda_codec *codec)
13272{
13273 struct alc_spec *spec = codec->spec;
13274 hda_nid_t pin;
13275
13276 pin = spec->autocfg.hp_pins[0];
13277 if (pin)
13278 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13279 pin = spec->autocfg.speaker_pins[0];
13280 if (pin)
13281 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13282}
13283
a361d84b
KY
13284static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13285{
13286 struct alc_spec *spec = codec->spec;
13287 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13288 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13289 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13290 unsigned int dac_vol1, dac_vol2;
13291
e9af4f36 13292 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13293 snd_hda_codec_write(codec, speaker_nid, 0,
13294 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13295 /* mute mixer inputs from 0x1d */
a361d84b
KY
13296 snd_hda_codec_write(codec, 0x0f, 0,
13297 AC_VERB_SET_AMP_GAIN_MUTE,
13298 AMP_IN_UNMUTE(1));
13299 snd_hda_codec_write(codec, 0x10, 0,
13300 AC_VERB_SET_AMP_GAIN_MUTE,
13301 AMP_IN_UNMUTE(1));
13302 } else {
e9af4f36 13303 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13304 snd_hda_codec_write(codec, 0x0f, 0,
13305 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13306 snd_hda_codec_write(codec, 0x10, 0,
13307 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13308 }
13309
13310 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13311 if (line_nid == 0x14)
a361d84b
KY
13312 dac_vol2 = AMP_OUT_ZERO;
13313 else if (line_nid == 0x15)
13314 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13315 if (hp_nid == 0x14)
a361d84b
KY
13316 dac_vol2 = AMP_OUT_ZERO;
13317 else if (hp_nid == 0x15)
13318 dac_vol1 = AMP_OUT_ZERO;
13319 if (line_nid != 0x16 || hp_nid != 0x16 ||
13320 spec->autocfg.line_out_pins[1] != 0x16 ||
13321 spec->autocfg.line_out_pins[2] != 0x16)
13322 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13323
13324 snd_hda_codec_write(codec, 0x02, 0,
13325 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13326 snd_hda_codec_write(codec, 0x03, 0,
13327 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13328}
13329
def319f9 13330/* pcm configuration: identical with ALC880 */
a361d84b
KY
13331#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13332#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13333#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13334#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13335
13336/*
13337 * BIOS auto configuration
13338 */
13339static int alc268_parse_auto_config(struct hda_codec *codec)
13340{
13341 struct alc_spec *spec = codec->spec;
13342 int err;
13343 static hda_nid_t alc268_ignore[] = { 0 };
13344
13345 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13346 alc268_ignore);
13347 if (err < 0)
13348 return err;
7e0e44d4
TI
13349 if (!spec->autocfg.line_outs) {
13350 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13351 spec->multiout.max_channels = 2;
13352 spec->no_analog = 1;
13353 goto dig_only;
13354 }
a361d84b 13355 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13356 }
a361d84b
KY
13357 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13358 if (err < 0)
13359 return err;
05f5f477 13360 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13361 if (err < 0)
13362 return err;
13363
13364 spec->multiout.max_channels = 2;
13365
7e0e44d4 13366 dig_only:
a361d84b 13367 /* digital only support output */
757899ac 13368 alc_auto_parse_digital(codec);
603c4019 13369 if (spec->kctls.list)
d88897ea 13370 add_mixer(spec, spec->kctls.list);
a361d84b 13371
892981ff 13372 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13373 add_mixer(spec, alc268_beep_mixer);
aef9d318 13374
d88897ea 13375 add_verb(spec, alc268_volume_init_verbs);
5908589f 13376 spec->num_mux_defs = 2;
61b9b9b1 13377 spec->input_mux = &spec->private_imux[0];
a361d84b 13378
776e184e
TI
13379 err = alc_auto_add_mic_boost(codec);
13380 if (err < 0)
13381 return err;
13382
6227cdce 13383 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13384
a361d84b
KY
13385 return 1;
13386}
13387
a361d84b
KY
13388#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13389
13390/* init callback for auto-configuration model -- overriding the default init */
13391static void alc268_auto_init(struct hda_codec *codec)
13392{
f6c7e546 13393 struct alc_spec *spec = codec->spec;
a361d84b
KY
13394 alc268_auto_init_multi_out(codec);
13395 alc268_auto_init_hp_out(codec);
13396 alc268_auto_init_mono_speaker_out(codec);
13397 alc268_auto_init_analog_input(codec);
757899ac 13398 alc_auto_init_digital(codec);
f6c7e546 13399 if (spec->unsol_event)
7fb0d78f 13400 alc_inithook(codec);
a361d84b
KY
13401}
13402
13403/*
13404 * configuration and preset
13405 */
13406static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13407 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13408 [ALC268_3ST] = "3stack",
983f8ae4 13409 [ALC268_TOSHIBA] = "toshiba",
d273809e 13410 [ALC268_ACER] = "acer",
c238b4f4 13411 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13412 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13413 [ALC268_DELL] = "dell",
f12462c5 13414 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13415#ifdef CONFIG_SND_DEBUG
13416 [ALC268_TEST] = "test",
13417#endif
a361d84b
KY
13418 [ALC268_AUTO] = "auto",
13419};
13420
13421static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13422 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13423 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13424 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13425 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13426 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13427 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13428 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13429 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13430 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13431 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13432 /* almost compatible with toshiba but with optional digital outs;
13433 * auto-probing seems working fine
13434 */
8871e5b9 13435 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13436 ALC268_AUTO),
a361d84b 13437 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13438 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13439 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13440 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13441 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
8871e5b9 13442 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
a361d84b
KY
13443 {}
13444};
13445
3abf2f36
TI
13446/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13447static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13448 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13449 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13450 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13451 ALC268_TOSHIBA),
13452 {}
13453};
13454
a361d84b 13455static struct alc_config_preset alc268_presets[] = {
eb5a6621 13456 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13457 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13458 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13459 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13460 alc267_quanta_il1_verbs },
13461 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13462 .dac_nids = alc268_dac_nids,
13463 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13464 .adc_nids = alc268_adc_nids_alt,
13465 .hp_nid = 0x03,
13466 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13467 .channel_mode = alc268_modes,
4f5d1706
TI
13468 .unsol_event = alc_sku_unsol_event,
13469 .setup = alc267_quanta_il1_setup,
13470 .init_hook = alc_inithook,
eb5a6621 13471 },
a361d84b 13472 [ALC268_3ST] = {
aef9d318
TI
13473 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13474 alc268_beep_mixer },
a361d84b
KY
13475 .init_verbs = { alc268_base_init_verbs },
13476 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13477 .dac_nids = alc268_dac_nids,
13478 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13479 .adc_nids = alc268_adc_nids_alt,
e1406348 13480 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13481 .hp_nid = 0x03,
13482 .dig_out_nid = ALC268_DIGOUT_NID,
13483 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13484 .channel_mode = alc268_modes,
13485 .input_mux = &alc268_capture_source,
13486 },
d1a991a6 13487 [ALC268_TOSHIBA] = {
42171c17 13488 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13489 alc268_beep_mixer },
d273809e
TI
13490 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13491 alc268_toshiba_verbs },
d1a991a6
KY
13492 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13493 .dac_nids = alc268_dac_nids,
13494 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13495 .adc_nids = alc268_adc_nids_alt,
e1406348 13496 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13497 .hp_nid = 0x03,
13498 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13499 .channel_mode = alc268_modes,
13500 .input_mux = &alc268_capture_source,
d273809e 13501 .unsol_event = alc268_toshiba_unsol_event,
4f5d1706
TI
13502 .setup = alc268_toshiba_setup,
13503 .init_hook = alc268_toshiba_automute,
d273809e
TI
13504 },
13505 [ALC268_ACER] = {
432fd133 13506 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13507 alc268_beep_mixer },
d273809e
TI
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,
e1406348 13514 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13515 .hp_nid = 0x02,
13516 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13517 .channel_mode = alc268_modes,
0ccb541c 13518 .input_mux = &alc268_acer_capture_source,
d273809e 13519 .unsol_event = alc268_acer_unsol_event,
889c4395 13520 .init_hook = alc268_acer_init_hook,
d1a991a6 13521 },
c238b4f4
TI
13522 [ALC268_ACER_DMIC] = {
13523 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13524 alc268_beep_mixer },
13525 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13526 alc268_acer_verbs },
13527 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13528 .dac_nids = alc268_dac_nids,
13529 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13530 .adc_nids = alc268_adc_nids_alt,
13531 .capsrc_nids = alc268_capsrc_nids,
13532 .hp_nid = 0x02,
13533 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13534 .channel_mode = alc268_modes,
13535 .input_mux = &alc268_acer_dmic_capture_source,
13536 .unsol_event = alc268_acer_unsol_event,
13537 .init_hook = alc268_acer_init_hook,
13538 },
8ef355da
KY
13539 [ALC268_ACER_ASPIRE_ONE] = {
13540 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13541 alc268_beep_mixer,
fdbc6626 13542 alc268_capture_nosrc_mixer },
8ef355da
KY
13543 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13544 alc268_acer_aspire_one_verbs },
13545 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13546 .dac_nids = alc268_dac_nids,
13547 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13548 .adc_nids = alc268_adc_nids_alt,
13549 .capsrc_nids = alc268_capsrc_nids,
13550 .hp_nid = 0x03,
13551 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13552 .channel_mode = alc268_modes,
8ef355da 13553 .unsol_event = alc268_acer_lc_unsol_event,
4f5d1706 13554 .setup = alc268_acer_lc_setup,
8ef355da
KY
13555 .init_hook = alc268_acer_lc_init_hook,
13556 },
3866f0b0 13557 [ALC268_DELL] = {
fdbc6626
TI
13558 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13559 alc268_capture_nosrc_mixer },
3866f0b0
TI
13560 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13561 alc268_dell_verbs },
13562 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13563 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13564 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13565 .adc_nids = alc268_adc_nids_alt,
13566 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13567 .hp_nid = 0x02,
13568 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13569 .channel_mode = alc268_modes,
a9fd4f3f 13570 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13571 .setup = alc268_dell_setup,
13572 .init_hook = alc_inithook,
3866f0b0 13573 },
f12462c5 13574 [ALC268_ZEPTO] = {
aef9d318
TI
13575 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13576 alc268_beep_mixer },
f12462c5
MT
13577 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13578 alc268_toshiba_verbs },
13579 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13580 .dac_nids = alc268_dac_nids,
13581 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13582 .adc_nids = alc268_adc_nids_alt,
e1406348 13583 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13584 .hp_nid = 0x03,
13585 .dig_out_nid = ALC268_DIGOUT_NID,
13586 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13587 .channel_mode = alc268_modes,
13588 .input_mux = &alc268_capture_source,
4f5d1706
TI
13589 .setup = alc268_toshiba_setup,
13590 .init_hook = alc268_toshiba_automute,
f12462c5 13591 },
86c53bd2
JW
13592#ifdef CONFIG_SND_DEBUG
13593 [ALC268_TEST] = {
13594 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13595 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13596 alc268_volume_init_verbs },
13597 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13598 .dac_nids = alc268_dac_nids,
13599 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13600 .adc_nids = alc268_adc_nids_alt,
e1406348 13601 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13602 .hp_nid = 0x03,
13603 .dig_out_nid = ALC268_DIGOUT_NID,
13604 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13605 .channel_mode = alc268_modes,
13606 .input_mux = &alc268_capture_source,
13607 },
13608#endif
a361d84b
KY
13609};
13610
13611static int patch_alc268(struct hda_codec *codec)
13612{
13613 struct alc_spec *spec;
13614 int board_config;
22971e3a 13615 int i, has_beep, err;
a361d84b 13616
ef86f581 13617 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13618 if (spec == NULL)
13619 return -ENOMEM;
13620
13621 codec->spec = spec;
13622
13623 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13624 alc268_models,
13625 alc268_cfg_tbl);
13626
3abf2f36
TI
13627 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13628 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13629 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13630
a361d84b 13631 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13632 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13633 codec->chip_name);
a361d84b
KY
13634 board_config = ALC268_AUTO;
13635 }
13636
13637 if (board_config == ALC268_AUTO) {
13638 /* automatic parse from the BIOS config */
13639 err = alc268_parse_auto_config(codec);
13640 if (err < 0) {
13641 alc_free(codec);
13642 return err;
13643 } else if (!err) {
13644 printk(KERN_INFO
13645 "hda_codec: Cannot set up configuration "
13646 "from BIOS. Using base mode...\n");
13647 board_config = ALC268_3ST;
13648 }
13649 }
13650
13651 if (board_config != ALC268_AUTO)
e9c364c0 13652 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 13653
a361d84b
KY
13654 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13655 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 13656 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 13657
a361d84b
KY
13658 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13659
22971e3a
TI
13660 has_beep = 0;
13661 for (i = 0; i < spec->num_mixers; i++) {
13662 if (spec->mixers[i] == alc268_beep_mixer) {
13663 has_beep = 1;
13664 break;
13665 }
13666 }
13667
13668 if (has_beep) {
13669 err = snd_hda_attach_beep_device(codec, 0x1);
13670 if (err < 0) {
13671 alc_free(codec);
13672 return err;
13673 }
13674 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13675 /* override the amp caps for beep generator */
13676 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
13677 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13678 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13679 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13680 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 13681 }
aef9d318 13682
7e0e44d4 13683 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
13684 /* check whether NID 0x07 is valid */
13685 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 13686 int i;
3866f0b0 13687
defb5ab2 13688 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 13689 /* get type */
a22d543a 13690 wcap = get_wcaps_type(wcap);
fdbc6626
TI
13691 if (spec->auto_mic ||
13692 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
13693 spec->adc_nids = alc268_adc_nids_alt;
13694 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
13695 if (spec->auto_mic)
13696 fixup_automic_adc(codec);
fdbc6626
TI
13697 if (spec->auto_mic || spec->input_mux->num_items == 1)
13698 add_mixer(spec, alc268_capture_nosrc_mixer);
13699 else
13700 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
13701 } else {
13702 spec->adc_nids = alc268_adc_nids;
13703 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 13704 add_mixer(spec, alc268_capture_mixer);
a361d84b 13705 }
85860c06
TI
13706 /* set default input source */
13707 for (i = 0; i < spec->num_adc_nids; i++)
13708 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
13709 0, AC_VERB_SET_CONNECT_SEL,
5908589f
HRK
13710 i < spec->num_mux_defs ?
13711 spec->input_mux[i].items[0].index :
85860c06 13712 spec->input_mux->items[0].index);
a361d84b 13713 }
2134ea4f
TI
13714
13715 spec->vmaster_nid = 0x02;
13716
a361d84b
KY
13717 codec->patch_ops = alc_patch_ops;
13718 if (board_config == ALC268_AUTO)
13719 spec->init_hook = alc268_auto_init;
ea1fb29a 13720
a361d84b
KY
13721 return 0;
13722}
13723
f6a92248
KY
13724/*
13725 * ALC269 channel source setting (2 channel)
13726 */
13727#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13728
13729#define alc269_dac_nids alc260_dac_nids
13730
13731static hda_nid_t alc269_adc_nids[1] = {
13732 /* ADC1 */
f53281e6
KY
13733 0x08,
13734};
13735
e01bf509
TI
13736static hda_nid_t alc269_capsrc_nids[1] = {
13737 0x23,
13738};
13739
84898e87
KY
13740static hda_nid_t alc269vb_adc_nids[1] = {
13741 /* ADC1 */
13742 0x09,
13743};
13744
13745static hda_nid_t alc269vb_capsrc_nids[1] = {
13746 0x22,
13747};
13748
6694635d
TI
13749static hda_nid_t alc269_adc_candidates[] = {
13750 0x08, 0x09, 0x07,
13751};
e01bf509 13752
f6a92248
KY
13753#define alc269_modes alc260_modes
13754#define alc269_capture_source alc880_lg_lw_capture_source
13755
13756static struct snd_kcontrol_new alc269_base_mixer[] = {
13757 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13758 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13759 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13760 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13761 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13762 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13763 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13764 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13765 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13766 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13767 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13768 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
13769 { } /* end */
13770};
13771
60db6b53
KY
13772static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13773 /* output mixer control */
13774 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13775 {
13776 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13777 .name = "Master Playback Switch",
5e26dfd0 13778 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
13779 .info = snd_hda_mixer_amp_switch_info,
13780 .get = snd_hda_mixer_amp_switch_get,
13781 .put = alc268_acer_master_sw_put,
13782 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13783 },
13784 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13785 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13786 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13787 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13788 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13789 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
60db6b53
KY
13790 { }
13791};
13792
64154835
TV
13793static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13794 /* output mixer control */
13795 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13796 {
13797 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13798 .name = "Master Playback Switch",
5e26dfd0 13799 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
13800 .info = snd_hda_mixer_amp_switch_info,
13801 .get = snd_hda_mixer_amp_switch_get,
13802 .put = alc268_acer_master_sw_put,
13803 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13804 },
13805 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13806 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13807 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13808 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13809 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13810 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13811 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13812 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
13813 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
64154835
TV
13814 { }
13815};
13816
84898e87 13817static struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 13818 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 13819 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 13820 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 13821 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
13822 { } /* end */
13823};
13824
84898e87
KY
13825static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13826 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13827 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13828 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13829 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13830 { } /* end */
13831};
13832
f53281e6 13833/* capture mixer elements */
84898e87
KY
13834static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13835 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13836 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13837 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13838 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13839 { } /* end */
13840};
13841
13842static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
13843 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13844 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
26f5df26
TI
13845 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13846 { } /* end */
13847};
13848
84898e87
KY
13849static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13850 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13851 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13852 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13853 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13854 { } /* end */
13855};
13856
13857static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13858 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13859 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13860 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13861 { } /* end */
13862};
13863
26f5df26 13864/* FSC amilo */
84898e87 13865#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 13866
60db6b53
KY
13867static struct hda_verb alc269_quanta_fl1_verbs[] = {
13868 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13869 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13870 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13871 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13872 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13873 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13874 { }
13875};
f6a92248 13876
64154835
TV
13877static struct hda_verb alc269_lifebook_verbs[] = {
13878 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13879 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13880 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13881 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13882 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13883 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13884 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13885 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13886 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13887 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13888 { }
13889};
13890
60db6b53
KY
13891/* toggle speaker-output according to the hp-jack state */
13892static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13893{
13894 unsigned int present;
13895 unsigned char bits;
f6a92248 13896
864f92be 13897 present = snd_hda_jack_detect(codec, 0x15);
5dbd5ec6 13898 bits = present ? HDA_AMP_MUTE : 0;
60db6b53 13899 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 13900 HDA_AMP_MUTE, bits);
60db6b53 13901 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 13902 HDA_AMP_MUTE, bits);
f6a92248 13903
60db6b53
KY
13904 snd_hda_codec_write(codec, 0x20, 0,
13905 AC_VERB_SET_COEF_INDEX, 0x0c);
13906 snd_hda_codec_write(codec, 0x20, 0,
13907 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 13908
60db6b53
KY
13909 snd_hda_codec_write(codec, 0x20, 0,
13910 AC_VERB_SET_COEF_INDEX, 0x0c);
13911 snd_hda_codec_write(codec, 0x20, 0,
13912 AC_VERB_SET_PROC_COEF, 0x480);
13913}
f6a92248 13914
64154835
TV
13915/* toggle speaker-output according to the hp-jacks state */
13916static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
13917{
13918 unsigned int present;
13919 unsigned char bits;
13920
13921 /* Check laptop headphone socket */
864f92be 13922 present = snd_hda_jack_detect(codec, 0x15);
64154835
TV
13923
13924 /* Check port replicator headphone socket */
864f92be 13925 present |= snd_hda_jack_detect(codec, 0x1a);
64154835 13926
5dbd5ec6 13927 bits = present ? HDA_AMP_MUTE : 0;
64154835 13928 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 13929 HDA_AMP_MUTE, bits);
64154835 13930 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 13931 HDA_AMP_MUTE, bits);
64154835
TV
13932
13933 snd_hda_codec_write(codec, 0x20, 0,
13934 AC_VERB_SET_COEF_INDEX, 0x0c);
13935 snd_hda_codec_write(codec, 0x20, 0,
13936 AC_VERB_SET_PROC_COEF, 0x680);
13937
13938 snd_hda_codec_write(codec, 0x20, 0,
13939 AC_VERB_SET_COEF_INDEX, 0x0c);
13940 snd_hda_codec_write(codec, 0x20, 0,
13941 AC_VERB_SET_PROC_COEF, 0x480);
13942}
13943
64154835
TV
13944static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13945{
13946 unsigned int present_laptop;
13947 unsigned int present_dock;
13948
864f92be
WF
13949 present_laptop = snd_hda_jack_detect(codec, 0x18);
13950 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
13951
13952 /* Laptop mic port overrides dock mic port, design decision */
13953 if (present_dock)
13954 snd_hda_codec_write(codec, 0x23, 0,
13955 AC_VERB_SET_CONNECT_SEL, 0x3);
13956 if (present_laptop)
13957 snd_hda_codec_write(codec, 0x23, 0,
13958 AC_VERB_SET_CONNECT_SEL, 0x0);
13959 if (!present_dock && !present_laptop)
13960 snd_hda_codec_write(codec, 0x23, 0,
13961 AC_VERB_SET_CONNECT_SEL, 0x1);
13962}
13963
60db6b53
KY
13964static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13965 unsigned int res)
13966{
4f5d1706
TI
13967 switch (res >> 26) {
13968 case ALC880_HP_EVENT:
60db6b53 13969 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
13970 break;
13971 case ALC880_MIC_EVENT:
13972 alc_mic_automute(codec);
13973 break;
13974 }
60db6b53 13975}
f6a92248 13976
64154835
TV
13977static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13978 unsigned int res)
13979{
13980 if ((res >> 26) == ALC880_HP_EVENT)
13981 alc269_lifebook_speaker_automute(codec);
13982 if ((res >> 26) == ALC880_MIC_EVENT)
13983 alc269_lifebook_mic_autoswitch(codec);
13984}
13985
4f5d1706
TI
13986static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13987{
13988 struct alc_spec *spec = codec->spec;
20645d70
TI
13989 spec->autocfg.hp_pins[0] = 0x15;
13990 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13991 spec->ext_mic.pin = 0x18;
13992 spec->ext_mic.mux_idx = 0;
13993 spec->int_mic.pin = 0x19;
13994 spec->int_mic.mux_idx = 1;
13995 spec->auto_mic = 1;
13996}
13997
60db6b53
KY
13998static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13999{
14000 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14001 alc_mic_automute(codec);
60db6b53 14002}
f6a92248 14003
64154835
TV
14004static void alc269_lifebook_init_hook(struct hda_codec *codec)
14005{
14006 alc269_lifebook_speaker_automute(codec);
14007 alc269_lifebook_mic_autoswitch(codec);
14008}
14009
84898e87 14010static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14011 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14012 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14013 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14014 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14015 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14016 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14017 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14018 {}
14019};
14020
84898e87 14021static struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14022 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14023 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14024 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14025 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14026 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14027 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14028 {}
14029};
14030
84898e87
KY
14031static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14032 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14033 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14034 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14035 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14036 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14037 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14038 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14039 {}
14040};
14041
14042static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14043 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14044 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14045 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14046 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14047 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14048 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14049 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14050 {}
14051};
14052
f53281e6
KY
14053/* toggle speaker-output according to the hp-jack state */
14054static void alc269_speaker_automute(struct hda_codec *codec)
14055{
ebb83eeb
KY
14056 struct alc_spec *spec = codec->spec;
14057 unsigned int nid = spec->autocfg.hp_pins[0];
f53281e6 14058 unsigned int present;
60db6b53 14059 unsigned char bits;
f53281e6 14060
ebb83eeb 14061 present = snd_hda_jack_detect(codec, nid);
5dbd5ec6 14062 bits = present ? HDA_AMP_MUTE : 0;
f53281e6 14063 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 14064 HDA_AMP_MUTE, bits);
f53281e6 14065 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 14066 HDA_AMP_MUTE, bits);
f53281e6
KY
14067}
14068
f53281e6 14069/* unsolicited event for HP jack sensing */
84898e87 14070static void alc269_laptop_unsol_event(struct hda_codec *codec,
60db6b53 14071 unsigned int res)
f53281e6 14072{
4f5d1706
TI
14073 switch (res >> 26) {
14074 case ALC880_HP_EVENT:
f53281e6 14075 alc269_speaker_automute(codec);
4f5d1706
TI
14076 break;
14077 case ALC880_MIC_EVENT:
14078 alc_mic_automute(codec);
14079 break;
14080 }
f53281e6
KY
14081}
14082
226b1ec8 14083static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14084{
4f5d1706 14085 struct alc_spec *spec = codec->spec;
20645d70
TI
14086 spec->autocfg.hp_pins[0] = 0x15;
14087 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14088 spec->ext_mic.pin = 0x18;
14089 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14090 spec->int_mic.pin = 0x19;
14091 spec->int_mic.mux_idx = 1;
4f5d1706 14092 spec->auto_mic = 1;
f53281e6
KY
14093}
14094
226b1ec8 14095static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14096{
14097 struct alc_spec *spec = codec->spec;
20645d70
TI
14098 spec->autocfg.hp_pins[0] = 0x15;
14099 spec->autocfg.speaker_pins[0] = 0x14;
84898e87
KY
14100 spec->ext_mic.pin = 0x18;
14101 spec->ext_mic.mux_idx = 0;
14102 spec->int_mic.pin = 0x12;
226b1ec8 14103 spec->int_mic.mux_idx = 5;
84898e87
KY
14104 spec->auto_mic = 1;
14105}
14106
226b1ec8 14107static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14108{
4f5d1706 14109 struct alc_spec *spec = codec->spec;
226b1ec8 14110 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14111 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
14112 spec->ext_mic.pin = 0x18;
14113 spec->ext_mic.mux_idx = 0;
14114 spec->int_mic.pin = 0x19;
14115 spec->int_mic.mux_idx = 1;
14116 spec->auto_mic = 1;
f53281e6
KY
14117}
14118
226b1ec8
KY
14119static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14120{
14121 struct alc_spec *spec = codec->spec;
14122 spec->autocfg.hp_pins[0] = 0x21;
14123 spec->autocfg.speaker_pins[0] = 0x14;
14124 spec->ext_mic.pin = 0x18;
14125 spec->ext_mic.mux_idx = 0;
14126 spec->int_mic.pin = 0x12;
14127 spec->int_mic.mux_idx = 6;
14128 spec->auto_mic = 1;
14129}
14130
84898e87 14131static void alc269_laptop_inithook(struct hda_codec *codec)
f53281e6
KY
14132{
14133 alc269_speaker_automute(codec);
4f5d1706 14134 alc_mic_automute(codec);
f53281e6
KY
14135}
14136
60db6b53
KY
14137/*
14138 * generic initialization of ADC, input mixers and output mixers
14139 */
14140static struct hda_verb alc269_init_verbs[] = {
14141 /*
14142 * Unmute ADC0 and set the default input to mic-in
14143 */
84898e87 14144 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14145
14146 /*
84898e87 14147 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14148 */
14149 /* set vol=0 to output mixers */
14150 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14151 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14152
14153 /* set up input amps for analog loopback */
14154 /* Amp Indices: DAC = 0, mixer = 1 */
14155 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14156 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14157 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14158 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14159 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14160 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14161
14162 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14163 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14164 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14165 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14166 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14167 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14168 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14169
14170 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14171 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14172
84898e87
KY
14173 /* FIXME: use Mux-type input source selection */
14174 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14175 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14176 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14177
84898e87
KY
14178 /* set EAPD */
14179 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14180 { }
14181};
14182
14183static struct hda_verb alc269vb_init_verbs[] = {
14184 /*
14185 * Unmute ADC0 and set the default input to mic-in
14186 */
14187 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14188
14189 /*
14190 * Set up output mixers (0x02 - 0x03)
14191 */
14192 /* set vol=0 to output mixers */
14193 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14194 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14195
14196 /* set up input amps for analog loopback */
14197 /* Amp Indices: DAC = 0, mixer = 1 */
14198 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14199 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14200 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14201 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14202 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14203 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14204
14205 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14206 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14207 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14208 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14209 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14210 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14211 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14212
14213 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14214 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14215
14216 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14217 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14218 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14219 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14220
14221 /* set EAPD */
14222 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14223 { }
14224};
14225
9d0b71b1
TI
14226#define alc269_auto_create_multi_out_ctls \
14227 alc268_auto_create_multi_out_ctls
05f5f477
TI
14228#define alc269_auto_create_input_ctls \
14229 alc268_auto_create_input_ctls
f6a92248
KY
14230
14231#ifdef CONFIG_SND_HDA_POWER_SAVE
14232#define alc269_loopbacks alc880_loopbacks
14233#endif
14234
def319f9 14235/* pcm configuration: identical with ALC880 */
f6a92248
KY
14236#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14237#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14238#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14239#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14240
f03d3115
TI
14241static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14242 .substreams = 1,
14243 .channels_min = 2,
14244 .channels_max = 8,
14245 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14246 /* NID is set in alc_build_pcms */
14247 .ops = {
14248 .open = alc880_playback_pcm_open,
14249 .prepare = alc880_playback_pcm_prepare,
14250 .cleanup = alc880_playback_pcm_cleanup
14251 },
14252};
14253
14254static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14255 .substreams = 1,
14256 .channels_min = 2,
14257 .channels_max = 2,
14258 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14259 /* NID is set in alc_build_pcms */
14260};
14261
ad35879a
TI
14262#ifdef CONFIG_SND_HDA_POWER_SAVE
14263static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14264{
14265 switch (codec->subsystem_id) {
14266 case 0x103c1586:
14267 return 1;
14268 }
14269 return 0;
14270}
14271
14272static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14273{
14274 /* update mute-LED according to the speaker mute state */
14275 if (nid == 0x01 || nid == 0x14) {
14276 int pinval;
14277 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14278 HDA_AMP_MUTE)
14279 pinval = 0x24;
14280 else
14281 pinval = 0x20;
14282 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14283 snd_hda_codec_update_cache(codec, 0x19, 0,
14284 AC_VERB_SET_PIN_WIDGET_CONTROL,
14285 pinval);
ad35879a
TI
14286 }
14287 return alc_check_power_status(codec, nid);
14288}
14289#endif /* CONFIG_SND_HDA_POWER_SAVE */
14290
840b64c0
TI
14291static int alc275_setup_dual_adc(struct hda_codec *codec)
14292{
14293 struct alc_spec *spec = codec->spec;
14294
14295 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14296 return 0;
14297 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14298 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14299 if (spec->ext_mic.pin <= 0x12) {
14300 spec->private_adc_nids[0] = 0x08;
14301 spec->private_adc_nids[1] = 0x11;
14302 spec->private_capsrc_nids[0] = 0x23;
14303 spec->private_capsrc_nids[1] = 0x22;
14304 } else {
14305 spec->private_adc_nids[0] = 0x11;
14306 spec->private_adc_nids[1] = 0x08;
14307 spec->private_capsrc_nids[0] = 0x22;
14308 spec->private_capsrc_nids[1] = 0x23;
14309 }
14310 spec->adc_nids = spec->private_adc_nids;
14311 spec->capsrc_nids = spec->private_capsrc_nids;
14312 spec->num_adc_nids = 2;
14313 spec->dual_adc_switch = 1;
14314 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14315 spec->adc_nids[0], spec->adc_nids[1]);
14316 return 1;
14317 }
14318 return 0;
14319}
14320
f6a92248
KY
14321/*
14322 * BIOS auto configuration
14323 */
14324static int alc269_parse_auto_config(struct hda_codec *codec)
14325{
14326 struct alc_spec *spec = codec->spec;
cfb9fb55 14327 int err;
f6a92248
KY
14328 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14329
14330 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14331 alc269_ignore);
14332 if (err < 0)
14333 return err;
14334
14335 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14336 if (err < 0)
14337 return err;
05f5f477 14338 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
f6a92248
KY
14339 if (err < 0)
14340 return err;
14341
14342 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14343
757899ac 14344 alc_auto_parse_digital(codec);
f6a92248 14345
603c4019 14346 if (spec->kctls.list)
d88897ea 14347 add_mixer(spec, spec->kctls.list);
f6a92248 14348
84898e87
KY
14349 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
14350 add_verb(spec, alc269vb_init_verbs);
6227cdce 14351 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14352 } else {
14353 add_verb(spec, alc269_init_verbs);
6227cdce 14354 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14355 }
14356
f6a92248 14357 spec->num_mux_defs = 1;
61b9b9b1 14358 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14359
14360 if (!alc275_setup_dual_adc(codec))
14361 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14362 sizeof(alc269_adc_candidates));
6694635d 14363
e01bf509 14364 /* set default input source */
840b64c0
TI
14365 if (!spec->dual_adc_switch)
14366 snd_hda_codec_write_cache(codec, spec->capsrc_nids[0],
e01bf509
TI
14367 0, AC_VERB_SET_CONNECT_SEL,
14368 spec->input_mux->items[0].index);
f6a92248
KY
14369
14370 err = alc_auto_add_mic_boost(codec);
14371 if (err < 0)
14372 return err;
14373
7e0e44d4 14374 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14375 set_capture_mixer(codec);
f53281e6 14376
f6a92248
KY
14377 return 1;
14378}
14379
e9af4f36
TI
14380#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14381#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14382#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14383
14384
14385/* init callback for auto-configuration model -- overriding the default init */
14386static void alc269_auto_init(struct hda_codec *codec)
14387{
f6c7e546 14388 struct alc_spec *spec = codec->spec;
f6a92248
KY
14389 alc269_auto_init_multi_out(codec);
14390 alc269_auto_init_hp_out(codec);
14391 alc269_auto_init_analog_input(codec);
757899ac 14392 alc_auto_init_digital(codec);
f6c7e546 14393 if (spec->unsol_event)
7fb0d78f 14394 alc_inithook(codec);
f6a92248
KY
14395}
14396
ff818c24
TI
14397enum {
14398 ALC269_FIXUP_SONY_VAIO,
14399};
14400
fbc25669 14401static const struct hda_verb alc269_sony_vaio_fixup_verbs[] = {
ff818c24
TI
14402 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14403 {}
14404};
14405
14406static const struct alc_fixup alc269_fixups[] = {
14407 [ALC269_FIXUP_SONY_VAIO] = {
14408 .verbs = alc269_sony_vaio_fixup_verbs
14409 },
14410};
14411
14412static struct snd_pci_quirk alc269_fixup_tbl[] = {
14413 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14414 {}
14415};
14416
14417
f6a92248
KY
14418/*
14419 * configuration and preset
14420 */
14421static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14422 [ALC269_BASIC] = "basic",
2922c9af 14423 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14424 [ALC269_AMIC] = "laptop-amic",
14425 [ALC269_DMIC] = "laptop-dmic",
64154835 14426 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14427 [ALC269_LIFEBOOK] = "lifebook",
14428 [ALC269_AUTO] = "auto",
f6a92248
KY
14429};
14430
14431static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14432 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
f53281e6 14433 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14434 ALC269_AMIC),
14435 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14436 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14437 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14438 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14439 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14440 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14441 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14442 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14443 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14444 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14445 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14446 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14447 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14448 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14449 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14450 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14451 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14452 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14453 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14454 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14455 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14456 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14457 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14458 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14459 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14460 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14461 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14462 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14463 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14464 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14465 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14466 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14467 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14468 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14469 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14470 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14471 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14472 ALC269_DMIC),
60db6b53 14473 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14474 ALC269_DMIC),
14475 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14476 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14477 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14478 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14479 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14480 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14481 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14482 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14483 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14484 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14485 {}
14486};
14487
14488static struct alc_config_preset alc269_presets[] = {
14489 [ALC269_BASIC] = {
f9e336f6 14490 .mixers = { alc269_base_mixer },
f6a92248
KY
14491 .init_verbs = { alc269_init_verbs },
14492 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14493 .dac_nids = alc269_dac_nids,
14494 .hp_nid = 0x03,
14495 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14496 .channel_mode = alc269_modes,
14497 .input_mux = &alc269_capture_source,
14498 },
60db6b53
KY
14499 [ALC269_QUANTA_FL1] = {
14500 .mixers = { alc269_quanta_fl1_mixer },
14501 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14502 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14503 .dac_nids = alc269_dac_nids,
14504 .hp_nid = 0x03,
14505 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14506 .channel_mode = alc269_modes,
14507 .input_mux = &alc269_capture_source,
14508 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 14509 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
14510 .init_hook = alc269_quanta_fl1_init_hook,
14511 },
84898e87
KY
14512 [ALC269_AMIC] = {
14513 .mixers = { alc269_laptop_mixer },
14514 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 14515 .init_verbs = { alc269_init_verbs,
84898e87 14516 alc269_laptop_amic_init_verbs },
f53281e6
KY
14517 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14518 .dac_nids = alc269_dac_nids,
14519 .hp_nid = 0x03,
14520 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14521 .channel_mode = alc269_modes,
84898e87
KY
14522 .unsol_event = alc269_laptop_unsol_event,
14523 .setup = alc269_laptop_amic_setup,
14524 .init_hook = alc269_laptop_inithook,
f53281e6 14525 },
84898e87
KY
14526 [ALC269_DMIC] = {
14527 .mixers = { alc269_laptop_mixer },
14528 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 14529 .init_verbs = { alc269_init_verbs,
84898e87
KY
14530 alc269_laptop_dmic_init_verbs },
14531 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14532 .dac_nids = alc269_dac_nids,
14533 .hp_nid = 0x03,
14534 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14535 .channel_mode = alc269_modes,
14536 .unsol_event = alc269_laptop_unsol_event,
14537 .setup = alc269_laptop_dmic_setup,
14538 .init_hook = alc269_laptop_inithook,
14539 },
14540 [ALC269VB_AMIC] = {
14541 .mixers = { alc269vb_laptop_mixer },
14542 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14543 .init_verbs = { alc269vb_init_verbs,
14544 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
14545 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14546 .dac_nids = alc269_dac_nids,
14547 .hp_nid = 0x03,
14548 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14549 .channel_mode = alc269_modes,
84898e87 14550 .unsol_event = alc269_laptop_unsol_event,
226b1ec8 14551 .setup = alc269vb_laptop_amic_setup,
84898e87
KY
14552 .init_hook = alc269_laptop_inithook,
14553 },
14554 [ALC269VB_DMIC] = {
14555 .mixers = { alc269vb_laptop_mixer },
14556 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14557 .init_verbs = { alc269vb_init_verbs,
14558 alc269vb_laptop_dmic_init_verbs },
14559 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14560 .dac_nids = alc269_dac_nids,
14561 .hp_nid = 0x03,
14562 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14563 .channel_mode = alc269_modes,
14564 .unsol_event = alc269_laptop_unsol_event,
14565 .setup = alc269vb_laptop_dmic_setup,
14566 .init_hook = alc269_laptop_inithook,
f53281e6 14567 },
26f5df26 14568 [ALC269_FUJITSU] = {
45bdd1c1 14569 .mixers = { alc269_fujitsu_mixer },
84898e87 14570 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 14571 .init_verbs = { alc269_init_verbs,
84898e87 14572 alc269_laptop_dmic_init_verbs },
26f5df26
TI
14573 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14574 .dac_nids = alc269_dac_nids,
14575 .hp_nid = 0x03,
14576 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14577 .channel_mode = alc269_modes,
84898e87
KY
14578 .unsol_event = alc269_laptop_unsol_event,
14579 .setup = alc269_laptop_dmic_setup,
14580 .init_hook = alc269_laptop_inithook,
26f5df26 14581 },
64154835
TV
14582 [ALC269_LIFEBOOK] = {
14583 .mixers = { alc269_lifebook_mixer },
14584 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14585 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14586 .dac_nids = alc269_dac_nids,
14587 .hp_nid = 0x03,
14588 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14589 .channel_mode = alc269_modes,
14590 .input_mux = &alc269_capture_source,
14591 .unsol_event = alc269_lifebook_unsol_event,
14592 .init_hook = alc269_lifebook_init_hook,
14593 },
f6a92248
KY
14594};
14595
14596static int patch_alc269(struct hda_codec *codec)
14597{
14598 struct alc_spec *spec;
14599 int board_config;
14600 int err;
84898e87 14601 int is_alc269vb = 0;
f6a92248
KY
14602
14603 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14604 if (spec == NULL)
14605 return -ENOMEM;
14606
14607 codec->spec = spec;
14608
da00c244
KY
14609 alc_auto_parse_customize_define(codec);
14610
274693f3 14611 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
c027ddcd
KY
14612 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
14613 spec->cdefine.platform_type == 1)
14614 alc_codec_rename(codec, "ALC271X");
14615 else
14616 alc_codec_rename(codec, "ALC259");
84898e87 14617 is_alc269vb = 1;
c027ddcd
KY
14618 } else
14619 alc_fix_pll_init(codec, 0x20, 0x04, 15);
274693f3 14620
f6a92248
KY
14621 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14622 alc269_models,
14623 alc269_cfg_tbl);
14624
14625 if (board_config < 0) {
9a11f1aa
TI
14626 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14627 codec->chip_name);
f6a92248
KY
14628 board_config = ALC269_AUTO;
14629 }
14630
ff818c24
TI
14631 if (board_config == ALC269_AUTO)
14632 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
14633
f6a92248
KY
14634 if (board_config == ALC269_AUTO) {
14635 /* automatic parse from the BIOS config */
14636 err = alc269_parse_auto_config(codec);
14637 if (err < 0) {
14638 alc_free(codec);
14639 return err;
14640 } else if (!err) {
14641 printk(KERN_INFO
14642 "hda_codec: Cannot set up configuration "
14643 "from BIOS. Using base mode...\n");
14644 board_config = ALC269_BASIC;
14645 }
14646 }
14647
dc1eae25 14648 if (has_cdefine_beep(codec)) {
8af2591d
TI
14649 err = snd_hda_attach_beep_device(codec, 0x1);
14650 if (err < 0) {
14651 alc_free(codec);
14652 return err;
14653 }
680cd536
KK
14654 }
14655
f6a92248 14656 if (board_config != ALC269_AUTO)
e9c364c0 14657 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 14658
84898e87 14659 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
14660 /* Due to a hardware problem on Lenovo Ideadpad, we need to
14661 * fix the sample rate of analog I/O to 44.1kHz
14662 */
14663 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
14664 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
14665 } else if (spec->dual_adc_switch) {
14666 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14667 /* switch ADC dynamically */
14668 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
14669 } else {
14670 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14671 spec->stream_analog_capture = &alc269_pcm_analog_capture;
14672 }
f6a92248
KY
14673 spec->stream_digital_playback = &alc269_pcm_digital_playback;
14674 spec->stream_digital_capture = &alc269_pcm_digital_capture;
14675
6694635d
TI
14676 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
14677 if (!is_alc269vb) {
14678 spec->adc_nids = alc269_adc_nids;
14679 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
14680 spec->capsrc_nids = alc269_capsrc_nids;
14681 } else {
14682 spec->adc_nids = alc269vb_adc_nids;
14683 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
14684 spec->capsrc_nids = alc269vb_capsrc_nids;
14685 }
84898e87
KY
14686 }
14687
f9e336f6 14688 if (!spec->cap_mixer)
b59bdf3b 14689 set_capture_mixer(codec);
dc1eae25 14690 if (has_cdefine_beep(codec))
da00c244 14691 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 14692
ff818c24
TI
14693 if (board_config == ALC269_AUTO)
14694 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
14695
100d5eb3
TI
14696 spec->vmaster_nid = 0x02;
14697
f6a92248
KY
14698 codec->patch_ops = alc_patch_ops;
14699 if (board_config == ALC269_AUTO)
14700 spec->init_hook = alc269_auto_init;
14701#ifdef CONFIG_SND_HDA_POWER_SAVE
14702 if (!spec->loopback.amplist)
14703 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
14704 if (alc269_mic2_for_mute_led(codec))
14705 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
14706#endif
14707
14708 return 0;
14709}
14710
df694daa
KY
14711/*
14712 * ALC861 channel source setting (2/6 channel selection for 3-stack)
14713 */
14714
14715/*
14716 * set the path ways for 2 channel output
14717 * need to set the codec line out and mic 1 pin widgets to inputs
14718 */
14719static struct hda_verb alc861_threestack_ch2_init[] = {
14720 /* set pin widget 1Ah (line in) for input */
14721 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14722 /* set pin widget 18h (mic1/2) for input, for mic also enable
14723 * the vref
14724 */
df694daa
KY
14725 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14726
9c7f852e
TI
14727 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14728#if 0
14729 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14730 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14731#endif
df694daa
KY
14732 { } /* end */
14733};
14734/*
14735 * 6ch mode
14736 * need to set the codec line out and mic 1 pin widgets to outputs
14737 */
14738static struct hda_verb alc861_threestack_ch6_init[] = {
14739 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14740 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14741 /* set pin widget 18h (mic1) for output (CLFE)*/
14742 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14743
14744 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 14745 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 14746
9c7f852e
TI
14747 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14748#if 0
14749 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14750 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14751#endif
df694daa
KY
14752 { } /* end */
14753};
14754
14755static struct hda_channel_mode alc861_threestack_modes[2] = {
14756 { 2, alc861_threestack_ch2_init },
14757 { 6, alc861_threestack_ch6_init },
14758};
22309c3e
TI
14759/* Set mic1 as input and unmute the mixer */
14760static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
14761 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14762 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14763 { } /* end */
14764};
14765/* Set mic1 as output and mute mixer */
14766static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
14767 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14768 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14769 { } /* end */
14770};
14771
14772static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
14773 { 2, alc861_uniwill_m31_ch2_init },
14774 { 4, alc861_uniwill_m31_ch4_init },
14775};
df694daa 14776
7cdbff94
MD
14777/* Set mic1 and line-in as input and unmute the mixer */
14778static struct hda_verb alc861_asus_ch2_init[] = {
14779 /* set pin widget 1Ah (line in) for input */
14780 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14781 /* set pin widget 18h (mic1/2) for input, for mic also enable
14782 * the vref
14783 */
7cdbff94
MD
14784 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14785
14786 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14787#if 0
14788 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14789 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14790#endif
14791 { } /* end */
14792};
14793/* Set mic1 nad line-in as output and mute mixer */
14794static struct hda_verb alc861_asus_ch6_init[] = {
14795 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14796 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14797 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14798 /* set pin widget 18h (mic1) for output (CLFE)*/
14799 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14800 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14801 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14802 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14803
14804 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14805#if 0
14806 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14807 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14808#endif
14809 { } /* end */
14810};
14811
14812static struct hda_channel_mode alc861_asus_modes[2] = {
14813 { 2, alc861_asus_ch2_init },
14814 { 6, alc861_asus_ch6_init },
14815};
14816
df694daa
KY
14817/* patch-ALC861 */
14818
14819static struct snd_kcontrol_new alc861_base_mixer[] = {
14820 /* output mixer control */
14821 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14822 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14823 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14824 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14825 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14826
14827 /*Input mixer control */
14828 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14829 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14830 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14831 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14832 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14833 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14834 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14835 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14836 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14837 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14838
df694daa
KY
14839 { } /* end */
14840};
14841
14842static struct snd_kcontrol_new alc861_3ST_mixer[] = {
14843 /* output mixer control */
14844 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14845 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14846 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14847 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14848 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14849
14850 /* Input mixer control */
14851 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14852 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14853 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14854 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14855 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14856 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14857 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14858 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14859 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14860 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14861
df694daa
KY
14862 {
14863 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14864 .name = "Channel Mode",
14865 .info = alc_ch_mode_info,
14866 .get = alc_ch_mode_get,
14867 .put = alc_ch_mode_put,
14868 .private_value = ARRAY_SIZE(alc861_threestack_modes),
14869 },
14870 { } /* end */
a53d1aec
TD
14871};
14872
d1d985f0 14873static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
14874 /* output mixer control */
14875 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14876 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14877 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 14878
a53d1aec 14879 { } /* end */
f12ab1e0 14880};
a53d1aec 14881
22309c3e
TI
14882static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
14883 /* output mixer control */
14884 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14885 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14886 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14887 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14888 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14889
14890 /* Input mixer control */
14891 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14892 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14893 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14894 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14895 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14896 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14897 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14898 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14899 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14900 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14901
22309c3e
TI
14902 {
14903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14904 .name = "Channel Mode",
14905 .info = alc_ch_mode_info,
14906 .get = alc_ch_mode_get,
14907 .put = alc_ch_mode_put,
14908 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
14909 },
14910 { } /* end */
f12ab1e0 14911};
7cdbff94
MD
14912
14913static struct snd_kcontrol_new alc861_asus_mixer[] = {
14914 /* output mixer control */
14915 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14916 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14917 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14918 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14919 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14920
14921 /* Input mixer control */
14922 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14923 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14924 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14925 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14926 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14927 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14928 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14929 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14930 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
14931 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
14932
7cdbff94
MD
14933 {
14934 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14935 .name = "Channel Mode",
14936 .info = alc_ch_mode_info,
14937 .get = alc_ch_mode_get,
14938 .put = alc_ch_mode_put,
14939 .private_value = ARRAY_SIZE(alc861_asus_modes),
14940 },
14941 { }
56bb0cab
TI
14942};
14943
14944/* additional mixer */
d1d985f0 14945static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
14946 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14947 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
14948 { }
14949};
7cdbff94 14950
df694daa
KY
14951/*
14952 * generic initialization of ADC, input mixers and output mixers
14953 */
14954static struct hda_verb alc861_base_init_verbs[] = {
14955 /*
14956 * Unmute ADC0 and set the default input to mic-in
14957 */
14958 /* port-A for surround (rear panel) */
14959 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14960 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
14961 /* port-B for mic-in (rear panel) with vref */
14962 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14963 /* port-C for line-in (rear panel) */
14964 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14965 /* port-D for Front */
14966 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14967 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14968 /* port-E for HP out (front panel) */
14969 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
14970 /* route front PCM to HP */
9dece1d7 14971 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
14972 /* port-F for mic-in (front panel) with vref */
14973 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14974 /* port-G for CLFE (rear panel) */
14975 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14976 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14977 /* port-H for side (rear panel) */
14978 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14979 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
14980 /* CD-in */
14981 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14982 /* route front mic to ADC1*/
14983 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14984 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 14985
df694daa
KY
14986 /* Unmute DAC0~3 & spdif out*/
14987 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14988 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14989 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14990 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14991 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 14992
df694daa
KY
14993 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14994 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14995 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14996 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14997 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 14998
df694daa
KY
14999 /* Unmute Stereo Mixer 15 */
15000 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15001 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15002 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15003 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15004
15005 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15006 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15007 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15008 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15009 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15010 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15011 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15012 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15013 /* hp used DAC 3 (Front) */
15014 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15015 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15016
15017 { }
15018};
15019
15020static struct hda_verb alc861_threestack_init_verbs[] = {
15021 /*
15022 * Unmute ADC0 and set the default input to mic-in
15023 */
15024 /* port-A for surround (rear panel) */
15025 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15026 /* port-B for mic-in (rear panel) with vref */
15027 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15028 /* port-C for line-in (rear panel) */
15029 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15030 /* port-D for Front */
15031 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15032 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15033 /* port-E for HP out (front panel) */
15034 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15035 /* route front PCM to HP */
9dece1d7 15036 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15037 /* port-F for mic-in (front panel) with vref */
15038 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15039 /* port-G for CLFE (rear panel) */
15040 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15041 /* port-H for side (rear panel) */
15042 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15043 /* CD-in */
15044 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15045 /* route front mic to ADC1*/
15046 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15047 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15048 /* Unmute DAC0~3 & spdif out*/
15049 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15050 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15051 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15052 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15053 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15054
df694daa
KY
15055 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15056 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15057 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15058 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15059 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15060
df694daa
KY
15061 /* Unmute Stereo Mixer 15 */
15062 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15063 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15064 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15065 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15066
15067 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15068 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15069 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15070 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15071 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15072 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15073 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15074 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15075 /* hp used DAC 3 (Front) */
15076 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15077 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15078 { }
15079};
22309c3e
TI
15080
15081static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15082 /*
15083 * Unmute ADC0 and set the default input to mic-in
15084 */
15085 /* port-A for surround (rear panel) */
15086 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15087 /* port-B for mic-in (rear panel) with vref */
15088 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15089 /* port-C for line-in (rear panel) */
15090 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15091 /* port-D for Front */
15092 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15093 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15094 /* port-E for HP out (front panel) */
f12ab1e0
TI
15095 /* this has to be set to VREF80 */
15096 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15097 /* route front PCM to HP */
9dece1d7 15098 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15099 /* port-F for mic-in (front panel) with vref */
15100 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15101 /* port-G for CLFE (rear panel) */
15102 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15103 /* port-H for side (rear panel) */
15104 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15105 /* CD-in */
15106 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15107 /* route front mic to ADC1*/
15108 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15109 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15110 /* Unmute DAC0~3 & spdif out*/
15111 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15112 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15113 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15114 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15115 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15116
22309c3e
TI
15117 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15118 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15119 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15120 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15121 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15122
22309c3e
TI
15123 /* Unmute Stereo Mixer 15 */
15124 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15125 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15126 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15127 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15128
15129 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15130 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15131 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15132 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15133 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15134 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15135 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15136 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15137 /* hp used DAC 3 (Front) */
15138 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15139 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15140 { }
15141};
15142
7cdbff94
MD
15143static struct hda_verb alc861_asus_init_verbs[] = {
15144 /*
15145 * Unmute ADC0 and set the default input to mic-in
15146 */
f12ab1e0
TI
15147 /* port-A for surround (rear panel)
15148 * according to codec#0 this is the HP jack
15149 */
7cdbff94
MD
15150 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15151 /* route front PCM to HP */
15152 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15153 /* port-B for mic-in (rear panel) with vref */
15154 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15155 /* port-C for line-in (rear panel) */
15156 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15157 /* port-D for Front */
15158 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15159 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15160 /* port-E for HP out (front panel) */
f12ab1e0
TI
15161 /* this has to be set to VREF80 */
15162 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15163 /* route front PCM to HP */
9dece1d7 15164 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15165 /* port-F for mic-in (front panel) with vref */
15166 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15167 /* port-G for CLFE (rear panel) */
15168 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15169 /* port-H for side (rear panel) */
15170 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15171 /* CD-in */
15172 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15173 /* route front mic to ADC1*/
15174 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15175 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15176 /* Unmute DAC0~3 & spdif out*/
15177 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15178 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15179 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15180 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15181 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15182 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15183 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15184 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15185 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15186 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15187
7cdbff94
MD
15188 /* Unmute Stereo Mixer 15 */
15189 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15190 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15191 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15192 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15193
15194 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15195 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15196 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15197 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15198 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15199 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15200 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15201 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15202 /* hp used DAC 3 (Front) */
15203 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15204 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15205 { }
15206};
15207
56bb0cab
TI
15208/* additional init verbs for ASUS laptops */
15209static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15210 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15211 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15212 { }
15213};
7cdbff94 15214
df694daa
KY
15215/*
15216 * generic initialization of ADC, input mixers and output mixers
15217 */
15218static struct hda_verb alc861_auto_init_verbs[] = {
15219 /*
15220 * Unmute ADC0 and set the default input to mic-in
15221 */
f12ab1e0 15222 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15223 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15224
df694daa
KY
15225 /* Unmute DAC0~3 & spdif out*/
15226 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15227 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15228 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15229 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15230 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15231
df694daa
KY
15232 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15233 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15234 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15235 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15236 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15237
df694daa
KY
15238 /* Unmute Stereo Mixer 15 */
15239 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15240 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15241 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15242 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15243
1c20930a
TI
15244 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15245 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15246 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15247 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15248 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15249 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15250 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15251 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15252
15253 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15254 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15255 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15256 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15257 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15258 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15259 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15260 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15261
f12ab1e0 15262 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15263
15264 { }
15265};
15266
a53d1aec
TD
15267static struct hda_verb alc861_toshiba_init_verbs[] = {
15268 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15269
a53d1aec
TD
15270 { }
15271};
15272
15273/* toggle speaker-output according to the hp-jack state */
15274static void alc861_toshiba_automute(struct hda_codec *codec)
15275{
864f92be 15276 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15277
47fd830a
TI
15278 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15279 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15280 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15281 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15282}
15283
15284static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15285 unsigned int res)
15286{
a53d1aec
TD
15287 if ((res >> 26) == ALC880_HP_EVENT)
15288 alc861_toshiba_automute(codec);
15289}
15290
def319f9 15291/* pcm configuration: identical with ALC880 */
df694daa
KY
15292#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15293#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15294#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15295#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15296
15297
15298#define ALC861_DIGOUT_NID 0x07
15299
15300static struct hda_channel_mode alc861_8ch_modes[1] = {
15301 { 8, NULL }
15302};
15303
15304static hda_nid_t alc861_dac_nids[4] = {
15305 /* front, surround, clfe, side */
15306 0x03, 0x06, 0x05, 0x04
15307};
15308
9c7f852e
TI
15309static hda_nid_t alc660_dac_nids[3] = {
15310 /* front, clfe, surround */
15311 0x03, 0x05, 0x06
15312};
15313
df694daa
KY
15314static hda_nid_t alc861_adc_nids[1] = {
15315 /* ADC0-2 */
15316 0x08,
15317};
15318
15319static struct hda_input_mux alc861_capture_source = {
15320 .num_items = 5,
15321 .items = {
15322 { "Mic", 0x0 },
15323 { "Front Mic", 0x3 },
15324 { "Line", 0x1 },
15325 { "CD", 0x4 },
15326 { "Mixer", 0x5 },
15327 },
15328};
15329
1c20930a
TI
15330static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15331{
15332 struct alc_spec *spec = codec->spec;
15333 hda_nid_t mix, srcs[5];
15334 int i, j, num;
15335
15336 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15337 return 0;
15338 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15339 if (num < 0)
15340 return 0;
15341 for (i = 0; i < num; i++) {
15342 unsigned int type;
a22d543a 15343 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15344 if (type != AC_WID_AUD_OUT)
15345 continue;
15346 for (j = 0; j < spec->multiout.num_dacs; j++)
15347 if (spec->multiout.dac_nids[j] == srcs[i])
15348 break;
15349 if (j >= spec->multiout.num_dacs)
15350 return srcs[i];
15351 }
15352 return 0;
15353}
15354
df694daa 15355/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15356static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15357 const struct auto_pin_cfg *cfg)
df694daa 15358{
1c20930a 15359 struct alc_spec *spec = codec->spec;
df694daa 15360 int i;
1c20930a 15361 hda_nid_t nid, dac;
df694daa
KY
15362
15363 spec->multiout.dac_nids = spec->private_dac_nids;
15364 for (i = 0; i < cfg->line_outs; i++) {
15365 nid = cfg->line_out_pins[i];
1c20930a
TI
15366 dac = alc861_look_for_dac(codec, nid);
15367 if (!dac)
15368 continue;
15369 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15370 }
df694daa
KY
15371 return 0;
15372}
15373
1c20930a
TI
15374static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15375 hda_nid_t nid, unsigned int chs)
15376{
0afe5f89 15377 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
1c20930a
TI
15378 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15379}
15380
df694daa 15381/* add playback controls from the parsed DAC table */
1c20930a 15382static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15383 const struct auto_pin_cfg *cfg)
15384{
1c20930a 15385 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
15386 static const char *chname[4] = {
15387 "Front", "Surround", NULL /*CLFE*/, "Side"
15388 };
df694daa 15389 hda_nid_t nid;
1c20930a
TI
15390 int i, err;
15391
15392 if (cfg->line_outs == 1) {
15393 const char *pfx = NULL;
15394 if (!cfg->hp_outs)
15395 pfx = "Master";
15396 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15397 pfx = "Speaker";
15398 if (pfx) {
15399 nid = spec->multiout.dac_nids[0];
15400 return alc861_create_out_sw(codec, pfx, nid, 3);
15401 }
15402 }
df694daa
KY
15403
15404 for (i = 0; i < cfg->line_outs; i++) {
15405 nid = spec->multiout.dac_nids[i];
f12ab1e0 15406 if (!nid)
df694daa 15407 continue;
1c20930a 15408 if (i == 2) {
df694daa 15409 /* Center/LFE */
1c20930a 15410 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15411 if (err < 0)
df694daa 15412 return err;
1c20930a 15413 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15414 if (err < 0)
df694daa
KY
15415 return err;
15416 } else {
1c20930a 15417 err = alc861_create_out_sw(codec, chname[i], nid, 3);
f12ab1e0 15418 if (err < 0)
df694daa
KY
15419 return err;
15420 }
15421 }
15422 return 0;
15423}
15424
1c20930a 15425static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 15426{
1c20930a 15427 struct alc_spec *spec = codec->spec;
df694daa
KY
15428 int err;
15429 hda_nid_t nid;
15430
f12ab1e0 15431 if (!pin)
df694daa
KY
15432 return 0;
15433
15434 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
15435 nid = alc861_look_for_dac(codec, pin);
15436 if (nid) {
15437 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15438 if (err < 0)
15439 return err;
15440 spec->multiout.hp_nid = nid;
15441 }
df694daa
KY
15442 }
15443 return 0;
15444}
15445
15446/* create playback/capture controls for input pins */
05f5f477 15447static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 15448 const struct auto_pin_cfg *cfg)
df694daa 15449{
05f5f477 15450 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
15451}
15452
f12ab1e0
TI
15453static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15454 hda_nid_t nid,
1c20930a 15455 int pin_type, hda_nid_t dac)
df694daa 15456{
1c20930a
TI
15457 hda_nid_t mix, srcs[5];
15458 int i, num;
15459
564c5bea
JL
15460 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15461 pin_type);
1c20930a 15462 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 15463 AMP_OUT_UNMUTE);
1c20930a
TI
15464 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15465 return;
15466 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15467 if (num < 0)
15468 return;
15469 for (i = 0; i < num; i++) {
15470 unsigned int mute;
15471 if (srcs[i] == dac || srcs[i] == 0x15)
15472 mute = AMP_IN_UNMUTE(i);
15473 else
15474 mute = AMP_IN_MUTE(i);
15475 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15476 mute);
15477 }
df694daa
KY
15478}
15479
15480static void alc861_auto_init_multi_out(struct hda_codec *codec)
15481{
15482 struct alc_spec *spec = codec->spec;
15483 int i;
15484
15485 for (i = 0; i < spec->autocfg.line_outs; i++) {
15486 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 15487 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 15488 if (nid)
baba8ee9 15489 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 15490 spec->multiout.dac_nids[i]);
df694daa
KY
15491 }
15492}
15493
15494static void alc861_auto_init_hp_out(struct hda_codec *codec)
15495{
15496 struct alc_spec *spec = codec->spec;
df694daa 15497
15870f05
TI
15498 if (spec->autocfg.hp_outs)
15499 alc861_auto_set_output_and_unmute(codec,
15500 spec->autocfg.hp_pins[0],
15501 PIN_HP,
1c20930a 15502 spec->multiout.hp_nid);
15870f05
TI
15503 if (spec->autocfg.speaker_outs)
15504 alc861_auto_set_output_and_unmute(codec,
15505 spec->autocfg.speaker_pins[0],
15506 PIN_OUT,
1c20930a 15507 spec->multiout.dac_nids[0]);
df694daa
KY
15508}
15509
15510static void alc861_auto_init_analog_input(struct hda_codec *codec)
15511{
15512 struct alc_spec *spec = codec->spec;
15513 int i;
15514
15515 for (i = 0; i < AUTO_PIN_LAST; i++) {
15516 hda_nid_t nid = spec->autocfg.input_pins[i];
23f0c048
TI
15517 if (nid >= 0x0c && nid <= 0x11)
15518 alc_set_input_pin(codec, nid, i);
df694daa
KY
15519 }
15520}
15521
15522/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
15523/* return 1 if successful, 0 if the proper config is not found,
15524 * or a negative error code
15525 */
df694daa
KY
15526static int alc861_parse_auto_config(struct hda_codec *codec)
15527{
15528 struct alc_spec *spec = codec->spec;
15529 int err;
15530 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
15531
f12ab1e0
TI
15532 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15533 alc861_ignore);
15534 if (err < 0)
df694daa 15535 return err;
f12ab1e0 15536 if (!spec->autocfg.line_outs)
df694daa
KY
15537 return 0; /* can't find valid BIOS pin config */
15538
1c20930a 15539 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
15540 if (err < 0)
15541 return err;
1c20930a 15542 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
15543 if (err < 0)
15544 return err;
1c20930a 15545 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
15546 if (err < 0)
15547 return err;
05f5f477 15548 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 15549 if (err < 0)
df694daa
KY
15550 return err;
15551
15552 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15553
757899ac 15554 alc_auto_parse_digital(codec);
df694daa 15555
603c4019 15556 if (spec->kctls.list)
d88897ea 15557 add_mixer(spec, spec->kctls.list);
df694daa 15558
d88897ea 15559 add_verb(spec, alc861_auto_init_verbs);
df694daa 15560
a1e8d2da 15561 spec->num_mux_defs = 1;
61b9b9b1 15562 spec->input_mux = &spec->private_imux[0];
df694daa
KY
15563
15564 spec->adc_nids = alc861_adc_nids;
15565 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 15566 set_capture_mixer(codec);
df694daa 15567
6227cdce 15568 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 15569
df694daa
KY
15570 return 1;
15571}
15572
ae6b813a
TI
15573/* additional initialization for auto-configuration model */
15574static void alc861_auto_init(struct hda_codec *codec)
df694daa 15575{
f6c7e546 15576 struct alc_spec *spec = codec->spec;
df694daa
KY
15577 alc861_auto_init_multi_out(codec);
15578 alc861_auto_init_hp_out(codec);
15579 alc861_auto_init_analog_input(codec);
757899ac 15580 alc_auto_init_digital(codec);
f6c7e546 15581 if (spec->unsol_event)
7fb0d78f 15582 alc_inithook(codec);
df694daa
KY
15583}
15584
cb53c626
TI
15585#ifdef CONFIG_SND_HDA_POWER_SAVE
15586static struct hda_amp_list alc861_loopbacks[] = {
15587 { 0x15, HDA_INPUT, 0 },
15588 { 0x15, HDA_INPUT, 1 },
15589 { 0x15, HDA_INPUT, 2 },
15590 { 0x15, HDA_INPUT, 3 },
15591 { } /* end */
15592};
15593#endif
15594
df694daa
KY
15595
15596/*
15597 * configuration and preset
15598 */
f5fcc13c
TI
15599static const char *alc861_models[ALC861_MODEL_LAST] = {
15600 [ALC861_3ST] = "3stack",
15601 [ALC660_3ST] = "3stack-660",
15602 [ALC861_3ST_DIG] = "3stack-dig",
15603 [ALC861_6ST_DIG] = "6stack-dig",
15604 [ALC861_UNIWILL_M31] = "uniwill-m31",
15605 [ALC861_TOSHIBA] = "toshiba",
15606 [ALC861_ASUS] = "asus",
15607 [ALC861_ASUS_LAPTOP] = "asus-laptop",
15608 [ALC861_AUTO] = "auto",
15609};
15610
15611static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 15612 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
15613 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15614 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15615 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 15616 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 15617 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 15618 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
15619 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
15620 * Any other models that need this preset?
15621 */
15622 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
15623 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
15624 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 15625 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
15626 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
15627 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
15628 /* FIXME: the below seems conflict */
15629 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 15630 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 15631 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
15632 {}
15633};
15634
15635static struct alc_config_preset alc861_presets[] = {
15636 [ALC861_3ST] = {
15637 .mixers = { alc861_3ST_mixer },
15638 .init_verbs = { alc861_threestack_init_verbs },
15639 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15640 .dac_nids = alc861_dac_nids,
15641 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15642 .channel_mode = alc861_threestack_modes,
4e195a7b 15643 .need_dac_fix = 1,
df694daa
KY
15644 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15645 .adc_nids = alc861_adc_nids,
15646 .input_mux = &alc861_capture_source,
15647 },
15648 [ALC861_3ST_DIG] = {
15649 .mixers = { alc861_base_mixer },
15650 .init_verbs = { alc861_threestack_init_verbs },
15651 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15652 .dac_nids = alc861_dac_nids,
15653 .dig_out_nid = ALC861_DIGOUT_NID,
15654 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15655 .channel_mode = alc861_threestack_modes,
4e195a7b 15656 .need_dac_fix = 1,
df694daa
KY
15657 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15658 .adc_nids = alc861_adc_nids,
15659 .input_mux = &alc861_capture_source,
15660 },
15661 [ALC861_6ST_DIG] = {
15662 .mixers = { alc861_base_mixer },
15663 .init_verbs = { alc861_base_init_verbs },
15664 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15665 .dac_nids = alc861_dac_nids,
15666 .dig_out_nid = ALC861_DIGOUT_NID,
15667 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
15668 .channel_mode = alc861_8ch_modes,
15669 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15670 .adc_nids = alc861_adc_nids,
15671 .input_mux = &alc861_capture_source,
15672 },
9c7f852e
TI
15673 [ALC660_3ST] = {
15674 .mixers = { alc861_3ST_mixer },
15675 .init_verbs = { alc861_threestack_init_verbs },
15676 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
15677 .dac_nids = alc660_dac_nids,
15678 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15679 .channel_mode = alc861_threestack_modes,
4e195a7b 15680 .need_dac_fix = 1,
9c7f852e
TI
15681 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15682 .adc_nids = alc861_adc_nids,
15683 .input_mux = &alc861_capture_source,
15684 },
22309c3e
TI
15685 [ALC861_UNIWILL_M31] = {
15686 .mixers = { alc861_uniwill_m31_mixer },
15687 .init_verbs = { alc861_uniwill_m31_init_verbs },
15688 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15689 .dac_nids = alc861_dac_nids,
15690 .dig_out_nid = ALC861_DIGOUT_NID,
15691 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
15692 .channel_mode = alc861_uniwill_m31_modes,
15693 .need_dac_fix = 1,
15694 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15695 .adc_nids = alc861_adc_nids,
15696 .input_mux = &alc861_capture_source,
15697 },
a53d1aec
TD
15698 [ALC861_TOSHIBA] = {
15699 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
15700 .init_verbs = { alc861_base_init_verbs,
15701 alc861_toshiba_init_verbs },
a53d1aec
TD
15702 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15703 .dac_nids = alc861_dac_nids,
15704 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15705 .channel_mode = alc883_3ST_2ch_modes,
15706 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15707 .adc_nids = alc861_adc_nids,
15708 .input_mux = &alc861_capture_source,
15709 .unsol_event = alc861_toshiba_unsol_event,
15710 .init_hook = alc861_toshiba_automute,
15711 },
7cdbff94
MD
15712 [ALC861_ASUS] = {
15713 .mixers = { alc861_asus_mixer },
15714 .init_verbs = { alc861_asus_init_verbs },
15715 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15716 .dac_nids = alc861_dac_nids,
15717 .dig_out_nid = ALC861_DIGOUT_NID,
15718 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
15719 .channel_mode = alc861_asus_modes,
15720 .need_dac_fix = 1,
15721 .hp_nid = 0x06,
15722 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15723 .adc_nids = alc861_adc_nids,
15724 .input_mux = &alc861_capture_source,
15725 },
56bb0cab
TI
15726 [ALC861_ASUS_LAPTOP] = {
15727 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
15728 .init_verbs = { alc861_asus_init_verbs,
15729 alc861_asus_laptop_init_verbs },
15730 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15731 .dac_nids = alc861_dac_nids,
15732 .dig_out_nid = ALC861_DIGOUT_NID,
15733 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15734 .channel_mode = alc883_3ST_2ch_modes,
15735 .need_dac_fix = 1,
15736 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15737 .adc_nids = alc861_adc_nids,
15738 .input_mux = &alc861_capture_source,
15739 },
15740};
df694daa 15741
cfc9b06f
TI
15742/* Pin config fixes */
15743enum {
15744 PINFIX_FSC_AMILO_PI1505,
15745};
15746
15747static struct alc_pincfg alc861_fsc_amilo_pi1505_pinfix[] = {
15748 { 0x0b, 0x0221101f }, /* HP */
15749 { 0x0f, 0x90170310 }, /* speaker */
15750 { }
15751};
15752
15753static const struct alc_fixup alc861_fixups[] = {
15754 [PINFIX_FSC_AMILO_PI1505] = {
15755 .pins = alc861_fsc_amilo_pi1505_pinfix
15756 },
15757};
15758
15759static struct snd_pci_quirk alc861_fixup_tbl[] = {
15760 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
15761 {}
15762};
df694daa
KY
15763
15764static int patch_alc861(struct hda_codec *codec)
15765{
15766 struct alc_spec *spec;
15767 int board_config;
15768 int err;
15769
dc041e0b 15770 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
15771 if (spec == NULL)
15772 return -ENOMEM;
15773
f12ab1e0 15774 codec->spec = spec;
df694daa 15775
f5fcc13c
TI
15776 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
15777 alc861_models,
15778 alc861_cfg_tbl);
9c7f852e 15779
f5fcc13c 15780 if (board_config < 0) {
9a11f1aa
TI
15781 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15782 codec->chip_name);
df694daa
KY
15783 board_config = ALC861_AUTO;
15784 }
15785
7fa90e87
TI
15786 if (board_config == ALC861_AUTO)
15787 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
cfc9b06f 15788
df694daa
KY
15789 if (board_config == ALC861_AUTO) {
15790 /* automatic parse from the BIOS config */
15791 err = alc861_parse_auto_config(codec);
15792 if (err < 0) {
15793 alc_free(codec);
15794 return err;
f12ab1e0 15795 } else if (!err) {
9c7f852e
TI
15796 printk(KERN_INFO
15797 "hda_codec: Cannot set up configuration "
15798 "from BIOS. Using base mode...\n");
df694daa
KY
15799 board_config = ALC861_3ST_DIG;
15800 }
15801 }
15802
680cd536
KK
15803 err = snd_hda_attach_beep_device(codec, 0x23);
15804 if (err < 0) {
15805 alc_free(codec);
15806 return err;
15807 }
15808
df694daa 15809 if (board_config != ALC861_AUTO)
e9c364c0 15810 setup_preset(codec, &alc861_presets[board_config]);
df694daa 15811
df694daa
KY
15812 spec->stream_analog_playback = &alc861_pcm_analog_playback;
15813 spec->stream_analog_capture = &alc861_pcm_analog_capture;
15814
df694daa
KY
15815 spec->stream_digital_playback = &alc861_pcm_digital_playback;
15816 spec->stream_digital_capture = &alc861_pcm_digital_capture;
15817
c7a8eb10
TI
15818 if (!spec->cap_mixer)
15819 set_capture_mixer(codec);
45bdd1c1
TI
15820 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
15821
2134ea4f
TI
15822 spec->vmaster_nid = 0x03;
15823
7fa90e87
TI
15824 if (board_config == ALC861_AUTO)
15825 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
15826
df694daa 15827 codec->patch_ops = alc_patch_ops;
c97259df 15828 if (board_config == ALC861_AUTO) {
ae6b813a 15829 spec->init_hook = alc861_auto_init;
c97259df
DC
15830#ifdef CONFIG_SND_HDA_POWER_SAVE
15831 spec->power_hook = alc_power_eapd;
15832#endif
15833 }
cb53c626
TI
15834#ifdef CONFIG_SND_HDA_POWER_SAVE
15835 if (!spec->loopback.amplist)
15836 spec->loopback.amplist = alc861_loopbacks;
15837#endif
ea1fb29a 15838
1da177e4
LT
15839 return 0;
15840}
15841
f32610ed
JS
15842/*
15843 * ALC861-VD support
15844 *
15845 * Based on ALC882
15846 *
15847 * In addition, an independent DAC
15848 */
15849#define ALC861VD_DIGOUT_NID 0x06
15850
15851static hda_nid_t alc861vd_dac_nids[4] = {
15852 /* front, surr, clfe, side surr */
15853 0x02, 0x03, 0x04, 0x05
15854};
15855
15856/* dac_nids for ALC660vd are in a different order - according to
15857 * Realtek's driver.
def319f9 15858 * This should probably result in a different mixer for 6stack models
f32610ed
JS
15859 * of ALC660vd codecs, but for now there is only 3stack mixer
15860 * - and it is the same as in 861vd.
15861 * adc_nids in ALC660vd are (is) the same as in 861vd
15862 */
15863static hda_nid_t alc660vd_dac_nids[3] = {
15864 /* front, rear, clfe, rear_surr */
15865 0x02, 0x04, 0x03
15866};
15867
15868static hda_nid_t alc861vd_adc_nids[1] = {
15869 /* ADC0 */
15870 0x09,
15871};
15872
e1406348
TI
15873static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
15874
f32610ed
JS
15875/* input MUX */
15876/* FIXME: should be a matrix-type input source selection */
15877static struct hda_input_mux alc861vd_capture_source = {
15878 .num_items = 4,
15879 .items = {
15880 { "Mic", 0x0 },
15881 { "Front Mic", 0x1 },
15882 { "Line", 0x2 },
15883 { "CD", 0x4 },
15884 },
15885};
15886
272a527c 15887static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 15888 .num_items = 2,
272a527c 15889 .items = {
b419f346
TD
15890 { "Ext Mic", 0x0 },
15891 { "Int Mic", 0x1 },
272a527c
KY
15892 },
15893};
15894
d1a991a6
KY
15895static struct hda_input_mux alc861vd_hp_capture_source = {
15896 .num_items = 2,
15897 .items = {
15898 { "Front Mic", 0x0 },
15899 { "ATAPI Mic", 0x1 },
15900 },
15901};
15902
f32610ed
JS
15903/*
15904 * 2ch mode
15905 */
15906static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
15907 { 2, NULL }
15908};
15909
15910/*
15911 * 6ch mode
15912 */
15913static struct hda_verb alc861vd_6stack_ch6_init[] = {
15914 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15915 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15916 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15917 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15918 { } /* end */
15919};
15920
15921/*
15922 * 8ch mode
15923 */
15924static struct hda_verb alc861vd_6stack_ch8_init[] = {
15925 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15926 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15927 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15928 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15929 { } /* end */
15930};
15931
15932static struct hda_channel_mode alc861vd_6stack_modes[2] = {
15933 { 6, alc861vd_6stack_ch6_init },
15934 { 8, alc861vd_6stack_ch8_init },
15935};
15936
15937static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
15938 {
15939 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15940 .name = "Channel Mode",
15941 .info = alc_ch_mode_info,
15942 .get = alc_ch_mode_get,
15943 .put = alc_ch_mode_put,
15944 },
15945 { } /* end */
15946};
15947
f32610ed
JS
15948/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15949 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15950 */
15951static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
15952 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15953 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15954
15955 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15956 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
15957
15958 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
15959 HDA_OUTPUT),
15960 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
15961 HDA_OUTPUT),
15962 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
15963 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
15964
15965 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
15966 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
15967
15968 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15969
15970 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15972 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15973
15974 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15975 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15976 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15977
15978 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15979 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15980
15981 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15982 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15983
f32610ed
JS
15984 { } /* end */
15985};
15986
15987static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
15988 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15989 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15990
15991 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15992
15993 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15994 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15995 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15996
15997 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15998 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15999 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16000
16001 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16002 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16003
16004 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16005 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16006
f32610ed
JS
16007 { } /* end */
16008};
16009
bdd148a3
KY
16010static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16011 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16012 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16013 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16014
16015 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16016
16017 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
16018 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16019 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16020
16021 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
16022 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16023 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16024
16025 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16026 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16027
16028 { } /* end */
16029};
16030
b419f346
TD
16031/* Pin assignment: Speaker=0x14, HP = 0x15,
16032 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
16033 */
16034static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16035 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16036 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16037 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16038 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
16039 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16040 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16041 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16042 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16043 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16044 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16045 { } /* end */
16046};
16047
d1a991a6
KY
16048/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16049 * Front Mic=0x18, ATAPI Mic = 0x19,
16050 */
16051static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16052 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16053 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16054 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16055 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16056 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16057 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16058 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16059 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16060
d1a991a6
KY
16061 { } /* end */
16062};
16063
f32610ed
JS
16064/*
16065 * generic initialization of ADC, input mixers and output mixers
16066 */
16067static struct hda_verb alc861vd_volume_init_verbs[] = {
16068 /*
16069 * Unmute ADC0 and set the default input to mic-in
16070 */
16071 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16072 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16073
16074 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16075 * the analog-loopback mixer widget
16076 */
16077 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16078 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16079 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16080 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16081 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16082 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16083
16084 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16085 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16087 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16088 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16089
16090 /*
16091 * Set up output mixers (0x02 - 0x05)
16092 */
16093 /* set vol=0 to output mixers */
16094 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16095 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16096 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16097 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16098
16099 /* set up input amps for analog loopback */
16100 /* Amp Indices: DAC = 0, mixer = 1 */
16101 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16102 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16103 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16104 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16105 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16106 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16107 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16108 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16109
16110 { }
16111};
16112
16113/*
16114 * 3-stack pin configuration:
16115 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16116 */
16117static struct hda_verb alc861vd_3stack_init_verbs[] = {
16118 /*
16119 * Set pin mode and muting
16120 */
16121 /* set front pin widgets 0x14 for output */
16122 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16123 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16124 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16125
16126 /* Mic (rear) pin: input vref at 80% */
16127 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16128 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16129 /* Front Mic pin: input vref at 80% */
16130 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16131 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16132 /* Line In pin: input */
16133 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16134 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16135 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16136 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16137 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16138 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16139 /* CD pin widget for input */
16140 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16141
16142 { }
16143};
16144
16145/*
16146 * 6-stack pin configuration:
16147 */
16148static struct hda_verb alc861vd_6stack_init_verbs[] = {
16149 /*
16150 * Set pin mode and muting
16151 */
16152 /* set front pin widgets 0x14 for output */
16153 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16154 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16155 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16156
16157 /* Rear Pin: output 1 (0x0d) */
16158 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16159 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16160 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16161 /* CLFE Pin: output 2 (0x0e) */
16162 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16163 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16164 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16165 /* Side Pin: output 3 (0x0f) */
16166 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16167 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16168 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16169
16170 /* Mic (rear) pin: input vref at 80% */
16171 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16172 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16173 /* Front Mic pin: input vref at 80% */
16174 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16175 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16176 /* Line In pin: input */
16177 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16178 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16179 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16180 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16181 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16182 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16183 /* CD pin widget for input */
16184 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16185
16186 { }
16187};
16188
bdd148a3
KY
16189static struct hda_verb alc861vd_eapd_verbs[] = {
16190 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16191 { }
16192};
16193
f9423e7a
KY
16194static struct hda_verb alc660vd_eapd_verbs[] = {
16195 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16196 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16197 { }
16198};
16199
bdd148a3
KY
16200static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16201 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16202 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16203 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16204 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16205 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16206 {}
16207};
16208
bdd148a3
KY
16209static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
16210{
16211 unsigned int present;
16212 unsigned char bits;
16213
864f92be 16214 present = snd_hda_jack_detect(codec, 0x18);
47fd830a 16215 bits = present ? HDA_AMP_MUTE : 0;
864f92be 16216
47fd830a
TI
16217 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
16218 HDA_AMP_MUTE, bits);
bdd148a3
KY
16219}
16220
4f5d1706 16221static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16222{
a9fd4f3f 16223 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16224 spec->autocfg.hp_pins[0] = 0x1b;
16225 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
16226}
16227
16228static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16229{
a9fd4f3f 16230 alc_automute_amp(codec);
bdd148a3
KY
16231 alc861vd_lenovo_mic_automute(codec);
16232}
16233
16234static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16235 unsigned int res)
16236{
16237 switch (res >> 26) {
bdd148a3
KY
16238 case ALC880_MIC_EVENT:
16239 alc861vd_lenovo_mic_automute(codec);
16240 break;
a9fd4f3f
TI
16241 default:
16242 alc_automute_amp_unsol_event(codec, res);
16243 break;
bdd148a3
KY
16244 }
16245}
16246
272a527c
KY
16247static struct hda_verb alc861vd_dallas_verbs[] = {
16248 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16249 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16250 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16251 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16252
16253 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16254 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16255 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16256 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16257 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16258 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16259 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16260 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16261
272a527c
KY
16262 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16263 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16264 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16265 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16266 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16267 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16268 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16269 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16270
16271 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16272 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16273 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16274 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16275 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16276 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16277 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16278 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16279
16280 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16281 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16282 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16283 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16284
16285 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16286 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16287 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16288
16289 { } /* end */
16290};
16291
16292/* toggle speaker-output according to the hp-jack state */
4f5d1706 16293static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16294{
a9fd4f3f 16295 struct alc_spec *spec = codec->spec;
272a527c 16296
a9fd4f3f
TI
16297 spec->autocfg.hp_pins[0] = 0x15;
16298 spec->autocfg.speaker_pins[0] = 0x14;
272a527c
KY
16299}
16300
cb53c626
TI
16301#ifdef CONFIG_SND_HDA_POWER_SAVE
16302#define alc861vd_loopbacks alc880_loopbacks
16303#endif
16304
def319f9 16305/* pcm configuration: identical with ALC880 */
f32610ed
JS
16306#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16307#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16308#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16309#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16310
16311/*
16312 * configuration and preset
16313 */
16314static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
16315 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16316 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16317 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16318 [ALC861VD_3ST] = "3stack",
16319 [ALC861VD_3ST_DIG] = "3stack-digout",
16320 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16321 [ALC861VD_LENOVO] = "lenovo",
272a527c 16322 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16323 [ALC861VD_HP] = "hp",
f32610ed
JS
16324 [ALC861VD_AUTO] = "auto",
16325};
16326
16327static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16328 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16329 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16330 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16331 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16332 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16333 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16334 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16335 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16336 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16337 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16338 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16339 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16340 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16341 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16342 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16343 {}
16344};
16345
16346static struct alc_config_preset alc861vd_presets[] = {
16347 [ALC660VD_3ST] = {
16348 .mixers = { alc861vd_3st_mixer },
16349 .init_verbs = { alc861vd_volume_init_verbs,
16350 alc861vd_3stack_init_verbs },
16351 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16352 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16353 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16354 .channel_mode = alc861vd_3stack_2ch_modes,
16355 .input_mux = &alc861vd_capture_source,
16356 },
6963f84c
MC
16357 [ALC660VD_3ST_DIG] = {
16358 .mixers = { alc861vd_3st_mixer },
16359 .init_verbs = { alc861vd_volume_init_verbs,
16360 alc861vd_3stack_init_verbs },
16361 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16362 .dac_nids = alc660vd_dac_nids,
16363 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16364 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16365 .channel_mode = alc861vd_3stack_2ch_modes,
16366 .input_mux = &alc861vd_capture_source,
16367 },
f32610ed
JS
16368 [ALC861VD_3ST] = {
16369 .mixers = { alc861vd_3st_mixer },
16370 .init_verbs = { alc861vd_volume_init_verbs,
16371 alc861vd_3stack_init_verbs },
16372 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16373 .dac_nids = alc861vd_dac_nids,
16374 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16375 .channel_mode = alc861vd_3stack_2ch_modes,
16376 .input_mux = &alc861vd_capture_source,
16377 },
16378 [ALC861VD_3ST_DIG] = {
16379 .mixers = { alc861vd_3st_mixer },
16380 .init_verbs = { alc861vd_volume_init_verbs,
16381 alc861vd_3stack_init_verbs },
16382 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16383 .dac_nids = alc861vd_dac_nids,
16384 .dig_out_nid = ALC861VD_DIGOUT_NID,
16385 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16386 .channel_mode = alc861vd_3stack_2ch_modes,
16387 .input_mux = &alc861vd_capture_source,
16388 },
16389 [ALC861VD_6ST_DIG] = {
16390 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16391 .init_verbs = { alc861vd_volume_init_verbs,
16392 alc861vd_6stack_init_verbs },
16393 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16394 .dac_nids = alc861vd_dac_nids,
16395 .dig_out_nid = ALC861VD_DIGOUT_NID,
16396 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16397 .channel_mode = alc861vd_6stack_modes,
16398 .input_mux = &alc861vd_capture_source,
16399 },
bdd148a3
KY
16400 [ALC861VD_LENOVO] = {
16401 .mixers = { alc861vd_lenovo_mixer },
16402 .init_verbs = { alc861vd_volume_init_verbs,
16403 alc861vd_3stack_init_verbs,
16404 alc861vd_eapd_verbs,
16405 alc861vd_lenovo_unsol_verbs },
16406 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16407 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16408 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16409 .channel_mode = alc861vd_3stack_2ch_modes,
16410 .input_mux = &alc861vd_capture_source,
16411 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16412 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16413 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16414 },
272a527c
KY
16415 [ALC861VD_DALLAS] = {
16416 .mixers = { alc861vd_dallas_mixer },
16417 .init_verbs = { alc861vd_dallas_verbs },
16418 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16419 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16420 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16421 .channel_mode = alc861vd_3stack_2ch_modes,
16422 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f 16423 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16424 .setup = alc861vd_dallas_setup,
16425 .init_hook = alc_automute_amp,
d1a991a6
KY
16426 },
16427 [ALC861VD_HP] = {
16428 .mixers = { alc861vd_hp_mixer },
16429 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16430 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16431 .dac_nids = alc861vd_dac_nids,
d1a991a6 16432 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
16433 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16434 .channel_mode = alc861vd_3stack_2ch_modes,
16435 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f 16436 .unsol_event = alc_automute_amp_unsol_event,
4f5d1706
TI
16437 .setup = alc861vd_dallas_setup,
16438 .init_hook = alc_automute_amp,
ea1fb29a 16439 },
13c94744
TI
16440 [ALC660VD_ASUS_V1S] = {
16441 .mixers = { alc861vd_lenovo_mixer },
16442 .init_verbs = { alc861vd_volume_init_verbs,
16443 alc861vd_3stack_init_verbs,
16444 alc861vd_eapd_verbs,
16445 alc861vd_lenovo_unsol_verbs },
16446 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16447 .dac_nids = alc660vd_dac_nids,
16448 .dig_out_nid = ALC861VD_DIGOUT_NID,
16449 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16450 .channel_mode = alc861vd_3stack_2ch_modes,
16451 .input_mux = &alc861vd_capture_source,
16452 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16453 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16454 .init_hook = alc861vd_lenovo_init_hook,
13c94744 16455 },
f32610ed
JS
16456};
16457
16458/*
16459 * BIOS auto configuration
16460 */
05f5f477
TI
16461static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16462 const struct auto_pin_cfg *cfg)
16463{
6227cdce 16464 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
05f5f477
TI
16465}
16466
16467
f32610ed
JS
16468static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
16469 hda_nid_t nid, int pin_type, int dac_idx)
16470{
f6c7e546 16471 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
16472}
16473
16474static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
16475{
16476 struct alc_spec *spec = codec->spec;
16477 int i;
16478
16479 for (i = 0; i <= HDA_SIDE; i++) {
16480 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16481 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
16482 if (nid)
16483 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 16484 pin_type, i);
f32610ed
JS
16485 }
16486}
16487
16488
16489static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
16490{
16491 struct alc_spec *spec = codec->spec;
16492 hda_nid_t pin;
16493
16494 pin = spec->autocfg.hp_pins[0];
def319f9 16495 if (pin) /* connect to front and use dac 0 */
f32610ed 16496 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
16497 pin = spec->autocfg.speaker_pins[0];
16498 if (pin)
16499 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
16500}
16501
f32610ed
JS
16502#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
16503
16504static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
16505{
16506 struct alc_spec *spec = codec->spec;
16507 int i;
16508
16509 for (i = 0; i < AUTO_PIN_LAST; i++) {
16510 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 16511 if (alc_is_input_pin(codec, nid)) {
23f0c048 16512 alc_set_input_pin(codec, nid, i);
e82c025b
TI
16513 if (nid != ALC861VD_PIN_CD_NID &&
16514 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
16515 snd_hda_codec_write(codec, nid, 0,
16516 AC_VERB_SET_AMP_GAIN_MUTE,
16517 AMP_OUT_MUTE);
16518 }
16519 }
16520}
16521
f511b01c
TI
16522#define alc861vd_auto_init_input_src alc882_auto_init_input_src
16523
f32610ed
JS
16524#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16525#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16526
16527/* add playback controls from the parsed DAC table */
16528/* Based on ALC880 version. But ALC861VD has separate,
16529 * different NIDs for mute/unmute switch and volume control */
16530static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16531 const struct auto_pin_cfg *cfg)
16532{
f32610ed
JS
16533 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
16534 hda_nid_t nid_v, nid_s;
16535 int i, err;
16536
16537 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 16538 if (!spec->multiout.dac_nids[i])
f32610ed
JS
16539 continue;
16540 nid_v = alc861vd_idx_to_mixer_vol(
16541 alc880_dac_to_idx(
16542 spec->multiout.dac_nids[i]));
16543 nid_s = alc861vd_idx_to_mixer_switch(
16544 alc880_dac_to_idx(
16545 spec->multiout.dac_nids[i]));
16546
16547 if (i == 2) {
16548 /* Center/LFE */
0afe5f89
TI
16549 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16550 "Center",
f12ab1e0
TI
16551 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16552 HDA_OUTPUT));
16553 if (err < 0)
f32610ed 16554 return err;
0afe5f89
TI
16555 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16556 "LFE",
f12ab1e0
TI
16557 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16558 HDA_OUTPUT));
16559 if (err < 0)
f32610ed 16560 return err;
0afe5f89
TI
16561 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16562 "Center",
f12ab1e0
TI
16563 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
16564 HDA_INPUT));
16565 if (err < 0)
f32610ed 16566 return err;
0afe5f89
TI
16567 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16568 "LFE",
f12ab1e0
TI
16569 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
16570 HDA_INPUT));
16571 if (err < 0)
f32610ed
JS
16572 return err;
16573 } else {
a4fcd491
TI
16574 const char *pfx;
16575 if (cfg->line_outs == 1 &&
16576 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
16577 if (!cfg->hp_pins)
16578 pfx = "Speaker";
16579 else
16580 pfx = "PCM";
16581 } else
16582 pfx = chname[i];
0afe5f89 16583 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16584 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16585 HDA_OUTPUT));
16586 if (err < 0)
f32610ed 16587 return err;
a4fcd491
TI
16588 if (cfg->line_outs == 1 &&
16589 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
16590 pfx = "Speaker";
0afe5f89 16591 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
bdd148a3 16592 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
16593 HDA_INPUT));
16594 if (err < 0)
f32610ed
JS
16595 return err;
16596 }
16597 }
16598 return 0;
16599}
16600
16601/* add playback controls for speaker and HP outputs */
16602/* Based on ALC880 version. But ALC861VD has separate,
16603 * different NIDs for mute/unmute switch and volume control */
16604static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16605 hda_nid_t pin, const char *pfx)
16606{
16607 hda_nid_t nid_v, nid_s;
16608 int err;
f32610ed 16609
f12ab1e0 16610 if (!pin)
f32610ed
JS
16611 return 0;
16612
16613 if (alc880_is_fixed_pin(pin)) {
16614 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16615 /* specify the DAC as the extra output */
f12ab1e0 16616 if (!spec->multiout.hp_nid)
f32610ed
JS
16617 spec->multiout.hp_nid = nid_v;
16618 else
16619 spec->multiout.extra_out_nid[0] = nid_v;
16620 /* control HP volume/switch on the output mixer amp */
16621 nid_v = alc861vd_idx_to_mixer_vol(
16622 alc880_fixed_pin_idx(pin));
16623 nid_s = alc861vd_idx_to_mixer_switch(
16624 alc880_fixed_pin_idx(pin));
16625
0afe5f89 16626 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16627 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
16628 if (err < 0)
f32610ed 16629 return err;
0afe5f89 16630 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
16631 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
16632 if (err < 0)
f32610ed
JS
16633 return err;
16634 } else if (alc880_is_multi_pin(pin)) {
16635 /* set manual connection */
16636 /* we have only a switch on HP-out PIN */
0afe5f89 16637 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
16638 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16639 if (err < 0)
f32610ed
JS
16640 return err;
16641 }
16642 return 0;
16643}
16644
16645/* parse the BIOS configuration and set up the alc_spec
16646 * return 1 if successful, 0 if the proper config is not found,
16647 * or a negative error code
16648 * Based on ALC880 version - had to change it to override
16649 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
16650static int alc861vd_parse_auto_config(struct hda_codec *codec)
16651{
16652 struct alc_spec *spec = codec->spec;
16653 int err;
16654 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
16655
f12ab1e0
TI
16656 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16657 alc861vd_ignore);
16658 if (err < 0)
f32610ed 16659 return err;
f12ab1e0 16660 if (!spec->autocfg.line_outs)
f32610ed
JS
16661 return 0; /* can't find valid BIOS pin config */
16662
f12ab1e0
TI
16663 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16664 if (err < 0)
16665 return err;
16666 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
16667 if (err < 0)
16668 return err;
16669 err = alc861vd_auto_create_extra_out(spec,
16670 spec->autocfg.speaker_pins[0],
16671 "Speaker");
16672 if (err < 0)
16673 return err;
16674 err = alc861vd_auto_create_extra_out(spec,
16675 spec->autocfg.hp_pins[0],
16676 "Headphone");
16677 if (err < 0)
16678 return err;
05f5f477 16679 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16680 if (err < 0)
f32610ed
JS
16681 return err;
16682
16683 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16684
757899ac 16685 alc_auto_parse_digital(codec);
f32610ed 16686
603c4019 16687 if (spec->kctls.list)
d88897ea 16688 add_mixer(spec, spec->kctls.list);
f32610ed 16689
d88897ea 16690 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
16691
16692 spec->num_mux_defs = 1;
61b9b9b1 16693 spec->input_mux = &spec->private_imux[0];
f32610ed 16694
776e184e
TI
16695 err = alc_auto_add_mic_boost(codec);
16696 if (err < 0)
16697 return err;
16698
6227cdce 16699 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 16700
f32610ed
JS
16701 return 1;
16702}
16703
16704/* additional initialization for auto-configuration model */
16705static void alc861vd_auto_init(struct hda_codec *codec)
16706{
f6c7e546 16707 struct alc_spec *spec = codec->spec;
f32610ed
JS
16708 alc861vd_auto_init_multi_out(codec);
16709 alc861vd_auto_init_hp_out(codec);
16710 alc861vd_auto_init_analog_input(codec);
f511b01c 16711 alc861vd_auto_init_input_src(codec);
757899ac 16712 alc_auto_init_digital(codec);
f6c7e546 16713 if (spec->unsol_event)
7fb0d78f 16714 alc_inithook(codec);
f32610ed
JS
16715}
16716
f8f25ba3
TI
16717enum {
16718 ALC660VD_FIX_ASUS_GPIO1
16719};
16720
16721/* reset GPIO1 */
16722static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
16723 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
16724 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
16725 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
16726 { }
16727};
16728
16729static const struct alc_fixup alc861vd_fixups[] = {
16730 [ALC660VD_FIX_ASUS_GPIO1] = {
16731 .verbs = alc660vd_fix_asus_gpio1_verbs,
16732 },
16733};
16734
16735static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
16736 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
16737 {}
16738};
16739
f32610ed
JS
16740static int patch_alc861vd(struct hda_codec *codec)
16741{
16742 struct alc_spec *spec;
16743 int err, board_config;
16744
16745 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16746 if (spec == NULL)
16747 return -ENOMEM;
16748
16749 codec->spec = spec;
16750
16751 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
16752 alc861vd_models,
16753 alc861vd_cfg_tbl);
16754
16755 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
16756 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16757 codec->chip_name);
f32610ed
JS
16758 board_config = ALC861VD_AUTO;
16759 }
16760
7fa90e87
TI
16761 if (board_config == ALC861VD_AUTO)
16762 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
f8f25ba3 16763
f32610ed
JS
16764 if (board_config == ALC861VD_AUTO) {
16765 /* automatic parse from the BIOS config */
16766 err = alc861vd_parse_auto_config(codec);
16767 if (err < 0) {
16768 alc_free(codec);
16769 return err;
f12ab1e0 16770 } else if (!err) {
f32610ed
JS
16771 printk(KERN_INFO
16772 "hda_codec: Cannot set up configuration "
16773 "from BIOS. Using base mode...\n");
16774 board_config = ALC861VD_3ST;
16775 }
16776 }
16777
680cd536
KK
16778 err = snd_hda_attach_beep_device(codec, 0x23);
16779 if (err < 0) {
16780 alc_free(codec);
16781 return err;
16782 }
16783
f32610ed 16784 if (board_config != ALC861VD_AUTO)
e9c364c0 16785 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 16786
2f893286 16787 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 16788 /* always turn on EAPD */
d88897ea 16789 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
16790 }
16791
f32610ed
JS
16792 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
16793 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
16794
f32610ed
JS
16795 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
16796 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
16797
dd704698
TI
16798 if (!spec->adc_nids) {
16799 spec->adc_nids = alc861vd_adc_nids;
16800 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
16801 }
16802 if (!spec->capsrc_nids)
16803 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 16804
b59bdf3b 16805 set_capture_mixer(codec);
45bdd1c1 16806 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 16807
2134ea4f
TI
16808 spec->vmaster_nid = 0x02;
16809
7fa90e87
TI
16810 if (board_config == ALC861VD_AUTO)
16811 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
16812
f32610ed
JS
16813 codec->patch_ops = alc_patch_ops;
16814
16815 if (board_config == ALC861VD_AUTO)
16816 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
16817#ifdef CONFIG_SND_HDA_POWER_SAVE
16818 if (!spec->loopback.amplist)
16819 spec->loopback.amplist = alc861vd_loopbacks;
16820#endif
f32610ed
JS
16821
16822 return 0;
16823}
16824
bc9f98a9
KY
16825/*
16826 * ALC662 support
16827 *
16828 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
16829 * configuration. Each pin widget can choose any input DACs and a mixer.
16830 * Each ADC is connected from a mixer of all inputs. This makes possible
16831 * 6-channel independent captures.
16832 *
16833 * In addition, an independent DAC for the multi-playback (not used in this
16834 * driver yet).
16835 */
16836#define ALC662_DIGOUT_NID 0x06
16837#define ALC662_DIGIN_NID 0x0a
16838
16839static hda_nid_t alc662_dac_nids[4] = {
16840 /* front, rear, clfe, rear_surr */
16841 0x02, 0x03, 0x04
16842};
16843
622e84cd
KY
16844static hda_nid_t alc272_dac_nids[2] = {
16845 0x02, 0x03
16846};
16847
b59bdf3b 16848static hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 16849 /* ADC1-2 */
b59bdf3b 16850 0x09, 0x08
bc9f98a9 16851};
e1406348 16852
622e84cd
KY
16853static hda_nid_t alc272_adc_nids[1] = {
16854 /* ADC1-2 */
16855 0x08,
16856};
16857
b59bdf3b 16858static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
622e84cd
KY
16859static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
16860
e1406348 16861
bc9f98a9
KY
16862/* input MUX */
16863/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
16864static struct hda_input_mux alc662_capture_source = {
16865 .num_items = 4,
16866 .items = {
16867 { "Mic", 0x0 },
16868 { "Front Mic", 0x1 },
16869 { "Line", 0x2 },
16870 { "CD", 0x4 },
16871 },
16872};
16873
16874static struct hda_input_mux alc662_lenovo_101e_capture_source = {
16875 .num_items = 2,
16876 .items = {
16877 { "Mic", 0x1 },
16878 { "Line", 0x2 },
16879 },
16880};
291702f0 16881
6dda9f4a
KY
16882static struct hda_input_mux alc663_capture_source = {
16883 .num_items = 3,
16884 .items = {
16885 { "Mic", 0x0 },
16886 { "Front Mic", 0x1 },
16887 { "Line", 0x2 },
16888 },
16889};
16890
4f5d1706 16891#if 0 /* set to 1 for testing other input sources below */
9541ba1d
CP
16892static struct hda_input_mux alc272_nc10_capture_source = {
16893 .num_items = 16,
16894 .items = {
16895 { "Autoselect Mic", 0x0 },
16896 { "Internal Mic", 0x1 },
16897 { "In-0x02", 0x2 },
16898 { "In-0x03", 0x3 },
16899 { "In-0x04", 0x4 },
16900 { "In-0x05", 0x5 },
16901 { "In-0x06", 0x6 },
16902 { "In-0x07", 0x7 },
16903 { "In-0x08", 0x8 },
16904 { "In-0x09", 0x9 },
16905 { "In-0x0a", 0x0a },
16906 { "In-0x0b", 0x0b },
16907 { "In-0x0c", 0x0c },
16908 { "In-0x0d", 0x0d },
16909 { "In-0x0e", 0x0e },
16910 { "In-0x0f", 0x0f },
16911 },
16912};
16913#endif
16914
bc9f98a9
KY
16915/*
16916 * 2ch mode
16917 */
16918static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
16919 { 2, NULL }
16920};
16921
16922/*
16923 * 2ch mode
16924 */
16925static struct hda_verb alc662_3ST_ch2_init[] = {
16926 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
16927 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16928 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
16929 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16930 { } /* end */
16931};
16932
16933/*
16934 * 6ch mode
16935 */
16936static struct hda_verb alc662_3ST_ch6_init[] = {
16937 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16938 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16939 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
16940 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16941 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16942 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
16943 { } /* end */
16944};
16945
16946static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
16947 { 2, alc662_3ST_ch2_init },
16948 { 6, alc662_3ST_ch6_init },
16949};
16950
16951/*
16952 * 2ch mode
16953 */
16954static struct hda_verb alc662_sixstack_ch6_init[] = {
16955 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16956 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16957 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16958 { } /* end */
16959};
16960
16961/*
16962 * 6ch mode
16963 */
16964static struct hda_verb alc662_sixstack_ch8_init[] = {
16965 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16966 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16967 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16968 { } /* end */
16969};
16970
16971static struct hda_channel_mode alc662_5stack_modes[2] = {
16972 { 2, alc662_sixstack_ch6_init },
16973 { 6, alc662_sixstack_ch8_init },
16974};
16975
16976/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16977 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16978 */
16979
16980static struct snd_kcontrol_new alc662_base_mixer[] = {
16981 /* output mixer control */
16982 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 16983 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 16984 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 16985 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
16986 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16987 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
16988 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16989 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
16990 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16991
16992 /*Input mixer control */
16993 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
16994 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
16995 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
16996 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
16997 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
16998 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
16999 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17000 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17001 { } /* end */
17002};
17003
17004static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17005 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17006 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17007 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17008 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17009 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17010 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17011 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17012 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17013 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17014 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17015 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17016 { } /* end */
17017};
17018
17019static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17020 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17021 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17022 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17023 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17024 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17025 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17026 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17027 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17028 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17029 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17030 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17031 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17032 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17033 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17034 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17035 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17036 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17037 { } /* end */
17038};
17039
17040static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17041 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17042 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17043 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17044 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17045 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17046 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17047 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17048 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17049 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17050 { } /* end */
17051};
17052
291702f0 17053static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17054 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17055 ALC262_HIPPO_MASTER_SWITCH,
291702f0
KY
17056
17057 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
17058 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17059 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17060
17061 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
17062 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17063 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17064 { } /* end */
17065};
17066
8c427226 17067static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17068 ALC262_HIPPO_MASTER_SWITCH,
17069 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17070 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17071 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17072 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17073 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17074 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17075 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17076 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17077 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17078 { } /* end */
17079};
17080
f1d4e28b
KY
17081static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17082 .ops = &snd_hda_bind_vol,
17083 .values = {
17084 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17085 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17086 0
17087 },
17088};
17089
17090static struct hda_bind_ctls alc663_asus_one_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(0x21, 3, 0, HDA_OUTPUT),
17095 0
17096 },
17097};
17098
6dda9f4a 17099static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17100 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17101 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17102 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17103 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17104 { } /* end */
17105};
17106
17107static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17108 .ops = &snd_hda_bind_sw,
17109 .values = {
17110 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17111 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17112 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17113 0
17114 },
17115};
17116
17117static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17118 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17119 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17120 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17121 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17122 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17123 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17124
17125 { } /* end */
17126};
17127
17128static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17129 .ops = &snd_hda_bind_sw,
17130 .values = {
17131 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17132 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17133 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17134 0
17135 },
17136};
17137
17138static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17139 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17140 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17141 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17142 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17143 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17144 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17145 { } /* end */
17146};
17147
17148static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17149 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17150 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17151 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17152 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17153 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17154 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17155 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17156 { } /* end */
17157};
17158
17159static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17160 .ops = &snd_hda_bind_vol,
17161 .values = {
17162 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17163 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17164 0
17165 },
17166};
17167
17168static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17169 .ops = &snd_hda_bind_sw,
17170 .values = {
17171 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17172 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17173 0
17174 },
17175};
17176
17177static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17178 HDA_BIND_VOL("Master Playback Volume",
17179 &alc663_asus_two_bind_master_vol),
17180 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17181 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17182 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17183 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17184 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17185 { } /* end */
17186};
17187
17188static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17189 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17190 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17191 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17192 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17193 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17194 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17195 { } /* end */
17196};
17197
17198static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17199 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17200 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17201 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17202 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17203 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17204
17205 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17206 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17207 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17208 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17209 { } /* end */
17210};
17211
17212static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17213 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17214 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17215 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17216
17217 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17218 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17219 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17220 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17221 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17222 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17223 { } /* end */
17224};
17225
ebb83eeb
KY
17226static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17227 .ops = &snd_hda_bind_sw,
17228 .values = {
17229 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17230 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17231 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17232 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17233 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17234 0
17235 },
17236};
17237
17238static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17239 .ops = &snd_hda_bind_sw,
17240 .values = {
17241 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17242 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17243 0
17244 },
17245};
17246
17247static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17248 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17249 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17250 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17251 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17252 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17253 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17254 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17255 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17256 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17257 { } /* end */
17258};
17259
17260static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17261 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17262 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17263 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17264 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17265 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17266 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17267 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17268 { } /* end */
17269};
17270
17271
bc9f98a9
KY
17272static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17273 {
17274 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17275 .name = "Channel Mode",
17276 .info = alc_ch_mode_info,
17277 .get = alc_ch_mode_get,
17278 .put = alc_ch_mode_put,
17279 },
17280 { } /* end */
17281};
17282
17283static struct hda_verb alc662_init_verbs[] = {
17284 /* ADC: mute amp left and right */
17285 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17286 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17287
b60dd394
KY
17288 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17289 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17290 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17291 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17292 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17293 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17294
17295 /* Front Pin: output 0 (0x0c) */
17296 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17297 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17298
17299 /* Rear Pin: output 1 (0x0d) */
17300 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17301 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17302
17303 /* CLFE Pin: output 2 (0x0e) */
17304 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17305 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17306
17307 /* Mic (rear) pin: input vref at 80% */
17308 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17309 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17310 /* Front Mic pin: input vref at 80% */
17311 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17312 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17313 /* Line In pin: input */
17314 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17315 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17316 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17317 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17318 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17319 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17320 /* CD pin widget for input */
17321 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17322
17323 /* FIXME: use matrix-type input source selection */
17324 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17325 /* Input mixer */
17326 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17327 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
17328
17329 /* always trun on EAPD */
17330 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17331 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17332
bc9f98a9
KY
17333 { }
17334};
17335
cec27c89
KY
17336static struct hda_verb alc663_init_verbs[] = {
17337 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17338 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17339 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17340 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17341 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17342 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17343 { }
17344};
17345
17346static struct hda_verb alc272_init_verbs[] = {
17347 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17348 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17349 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17350 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17351 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17352 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17353 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17354 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17355 { }
17356};
17357
bc9f98a9
KY
17358static struct hda_verb alc662_sue_init_verbs[] = {
17359 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17360 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17361 {}
17362};
17363
17364static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17365 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17366 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17367 {}
bc9f98a9
KY
17368};
17369
8c427226
KY
17370/* Set Unsolicited Event*/
17371static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17372 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17373 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17374 {}
17375};
17376
6dda9f4a 17377static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17378 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17379 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17380 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17381 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17382 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17383 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17384 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17385 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17386 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17387 {}
17388};
17389
17390static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17391 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17392 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17393 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17394 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17395 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17396 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17397 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17398 {}
17399};
17400
17401static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17402 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17403 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17404 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17405 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17406 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17407 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17408 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17409 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17410 {}
17411};
6dda9f4a 17412
f1d4e28b
KY
17413static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17414 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17415 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17416 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17417 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17418 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17419 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17420 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17421 {}
17422};
6dda9f4a 17423
f1d4e28b
KY
17424static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17425 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17426 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17427 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17428 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17429 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17430 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17431 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17432 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17433 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
17434 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17435 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
17436 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17437 {}
17438};
17439
17440static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17441 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17442 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17443 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17444 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17445 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17446 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17447 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17448 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17449 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17450 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17451 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17452 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
17453 {}
17454};
17455
17456static struct hda_verb alc663_g71v_init_verbs[] = {
17457 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17458 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17459 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17460
17461 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17462 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17463 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17464
17465 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17466 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17467 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17468 {}
17469};
17470
17471static struct hda_verb alc663_g50v_init_verbs[] = {
17472 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17473 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17474 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17475
17476 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17477 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17478 {}
17479};
17480
f1d4e28b
KY
17481static struct hda_verb alc662_ecs_init_verbs[] = {
17482 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17483 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17484 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17485 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17486 {}
17487};
17488
622e84cd
KY
17489static struct hda_verb alc272_dell_zm1_init_verbs[] = {
17490 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17491 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17492 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17493 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17494 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17495 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17496 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17497 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17498 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17499 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17500 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17501 {}
17502};
17503
17504static struct hda_verb alc272_dell_init_verbs[] = {
17505 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17506 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17507 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17508 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17509 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17510 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17511 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17512 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17513 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17514 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17515 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17516 {}
17517};
17518
ebb83eeb
KY
17519static struct hda_verb alc663_mode7_init_verbs[] = {
17520 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17521 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17522 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17523 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17524 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17525 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17526 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17527 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17528 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17529 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17530 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17531 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17532 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17533 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17534 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17535 {}
17536};
17537
17538static struct hda_verb alc663_mode8_init_verbs[] = {
17539 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17540 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17541 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17542 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17543 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17544 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17545 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17546 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17547 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17548 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17549 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17550 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17551 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17552 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17553 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17554 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17555 {}
17556};
17557
f1d4e28b
KY
17558static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17559 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17560 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17561 { } /* end */
17562};
17563
622e84cd
KY
17564static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17565 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17566 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17567 { } /* end */
17568};
17569
bc9f98a9
KY
17570static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
17571{
17572 unsigned int present;
f12ab1e0 17573 unsigned char bits;
bc9f98a9 17574
864f92be 17575 present = snd_hda_jack_detect(codec, 0x14);
47fd830a 17576 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17577
47fd830a
TI
17578 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17579 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17580}
17581
17582static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
17583{
17584 unsigned int present;
f12ab1e0 17585 unsigned char bits;
bc9f98a9 17586
864f92be 17587 present = snd_hda_jack_detect(codec, 0x1b);
47fd830a 17588 bits = present ? HDA_AMP_MUTE : 0;
864f92be 17589
47fd830a
TI
17590 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17591 HDA_AMP_MUTE, bits);
17592 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17593 HDA_AMP_MUTE, bits);
bc9f98a9
KY
17594}
17595
17596static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
17597 unsigned int res)
17598{
17599 if ((res >> 26) == ALC880_HP_EVENT)
17600 alc662_lenovo_101e_all_automute(codec);
17601 if ((res >> 26) == ALC880_FRONT_EVENT)
17602 alc662_lenovo_101e_ispeaker_automute(codec);
17603}
17604
291702f0
KY
17605/* unsolicited event for HP jack sensing */
17606static void alc662_eeepc_unsol_event(struct hda_codec *codec,
17607 unsigned int res)
17608{
291702f0 17609 if ((res >> 26) == ALC880_MIC_EVENT)
4f5d1706 17610 alc_mic_automute(codec);
42171c17
TI
17611 else
17612 alc262_hippo_unsol_event(codec, res);
291702f0
KY
17613}
17614
4f5d1706
TI
17615static void alc662_eeepc_setup(struct hda_codec *codec)
17616{
17617 struct alc_spec *spec = codec->spec;
17618
17619 alc262_hippo1_setup(codec);
17620 spec->ext_mic.pin = 0x18;
17621 spec->ext_mic.mux_idx = 0;
17622 spec->int_mic.pin = 0x19;
17623 spec->int_mic.mux_idx = 1;
17624 spec->auto_mic = 1;
17625}
17626
291702f0
KY
17627static void alc662_eeepc_inithook(struct hda_codec *codec)
17628{
4f5d1706
TI
17629 alc262_hippo_automute(codec);
17630 alc_mic_automute(codec);
291702f0
KY
17631}
17632
4f5d1706 17633static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 17634{
42171c17
TI
17635 struct alc_spec *spec = codec->spec;
17636
17637 spec->autocfg.hp_pins[0] = 0x14;
17638 spec->autocfg.speaker_pins[0] = 0x1b;
8c427226
KY
17639}
17640
4f5d1706
TI
17641#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
17642
6dda9f4a
KY
17643static void alc663_m51va_speaker_automute(struct hda_codec *codec)
17644{
17645 unsigned int present;
17646 unsigned char bits;
17647
864f92be 17648 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a 17649 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b 17650 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17651 HDA_AMP_MUTE, bits);
f1d4e28b 17652 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17653 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17654}
17655
17656static void alc663_21jd_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, 0x21);
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 alc663_15jd_two_speaker_automute(struct hda_codec *codec)
17674{
17675 unsigned int present;
17676 unsigned char bits;
17677
864f92be 17678 present = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17679 bits = present ? HDA_AMP_MUTE : 0;
17680 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17681 HDA_AMP_MUTE, bits);
f1d4e28b 17682 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17683 HDA_AMP_MUTE, bits);
f1d4e28b 17684 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
5dbd5ec6 17685 HDA_AMP_MUTE, bits);
f1d4e28b 17686 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
5dbd5ec6 17687 HDA_AMP_MUTE, bits);
f1d4e28b
KY
17688}
17689
17690static void alc662_f5z_speaker_automute(struct hda_codec *codec)
17691{
17692 unsigned int present;
17693 unsigned char bits;
17694
864f92be 17695 present = snd_hda_jack_detect(codec, 0x1b);
f1d4e28b
KY
17696 bits = present ? 0 : PIN_OUT;
17697 snd_hda_codec_write(codec, 0x14, 0,
17698 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
17699}
17700
17701static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
17702{
17703 unsigned int present1, present2;
17704
864f92be
WF
17705 present1 = snd_hda_jack_detect(codec, 0x21);
17706 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17707
17708 if (present1 || present2) {
17709 snd_hda_codec_write_cache(codec, 0x14, 0,
17710 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17711 } else {
17712 snd_hda_codec_write_cache(codec, 0x14, 0,
17713 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17714 }
17715}
17716
17717static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
17718{
17719 unsigned int present1, present2;
17720
864f92be
WF
17721 present1 = snd_hda_jack_detect(codec, 0x1b);
17722 present2 = snd_hda_jack_detect(codec, 0x15);
f1d4e28b
KY
17723
17724 if (present1 || present2) {
17725 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17726 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b 17727 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17728 HDA_AMP_MUTE, HDA_AMP_MUTE);
f1d4e28b
KY
17729 } else {
17730 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
5dbd5ec6 17731 HDA_AMP_MUTE, 0);
f1d4e28b 17732 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
5dbd5ec6 17733 HDA_AMP_MUTE, 0);
f1d4e28b 17734 }
6dda9f4a
KY
17735}
17736
ebb83eeb
KY
17737static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
17738{
17739 unsigned int present1, present2;
17740
17741 present1 = snd_hda_codec_read(codec, 0x1b, 0,
17742 AC_VERB_GET_PIN_SENSE, 0)
17743 & AC_PINSENSE_PRESENCE;
17744 present2 = snd_hda_codec_read(codec, 0x21, 0,
17745 AC_VERB_GET_PIN_SENSE, 0)
17746 & AC_PINSENSE_PRESENCE;
17747
17748 if (present1 || present2) {
17749 snd_hda_codec_write_cache(codec, 0x14, 0,
17750 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17751 snd_hda_codec_write_cache(codec, 0x17, 0,
17752 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17753 } else {
17754 snd_hda_codec_write_cache(codec, 0x14, 0,
17755 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17756 snd_hda_codec_write_cache(codec, 0x17, 0,
17757 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17758 }
17759}
17760
17761static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
17762{
17763 unsigned int present1, present2;
17764
17765 present1 = snd_hda_codec_read(codec, 0x21, 0,
17766 AC_VERB_GET_PIN_SENSE, 0)
17767 & AC_PINSENSE_PRESENCE;
17768 present2 = snd_hda_codec_read(codec, 0x15, 0,
17769 AC_VERB_GET_PIN_SENSE, 0)
17770 & AC_PINSENSE_PRESENCE;
17771
17772 if (present1 || present2) {
17773 snd_hda_codec_write_cache(codec, 0x14, 0,
17774 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17775 snd_hda_codec_write_cache(codec, 0x17, 0,
17776 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17777 } else {
17778 snd_hda_codec_write_cache(codec, 0x14, 0,
17779 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17780 snd_hda_codec_write_cache(codec, 0x17, 0,
17781 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17782 }
17783}
17784
6dda9f4a
KY
17785static void alc663_m51va_unsol_event(struct hda_codec *codec,
17786 unsigned int res)
17787{
17788 switch (res >> 26) {
17789 case ALC880_HP_EVENT:
17790 alc663_m51va_speaker_automute(codec);
17791 break;
17792 case ALC880_MIC_EVENT:
4f5d1706 17793 alc_mic_automute(codec);
6dda9f4a
KY
17794 break;
17795 }
17796}
17797
4f5d1706
TI
17798static void alc663_m51va_setup(struct hda_codec *codec)
17799{
17800 struct alc_spec *spec = codec->spec;
17801 spec->ext_mic.pin = 0x18;
17802 spec->ext_mic.mux_idx = 0;
17803 spec->int_mic.pin = 0x12;
ebb83eeb 17804 spec->int_mic.mux_idx = 9;
4f5d1706
TI
17805 spec->auto_mic = 1;
17806}
17807
6dda9f4a
KY
17808static void alc663_m51va_inithook(struct hda_codec *codec)
17809{
17810 alc663_m51va_speaker_automute(codec);
4f5d1706 17811 alc_mic_automute(codec);
6dda9f4a
KY
17812}
17813
f1d4e28b 17814/* ***************** Mode1 ******************************/
4f5d1706 17815#define alc663_mode1_unsol_event alc663_m51va_unsol_event
ebb83eeb
KY
17816
17817static void alc663_mode1_setup(struct hda_codec *codec)
17818{
17819 struct alc_spec *spec = codec->spec;
17820 spec->ext_mic.pin = 0x18;
17821 spec->ext_mic.mux_idx = 0;
17822 spec->int_mic.pin = 0x19;
17823 spec->int_mic.mux_idx = 1;
17824 spec->auto_mic = 1;
17825}
17826
4f5d1706 17827#define alc663_mode1_inithook alc663_m51va_inithook
f1d4e28b 17828
f1d4e28b
KY
17829/* ***************** Mode2 ******************************/
17830static void alc662_mode2_unsol_event(struct hda_codec *codec,
17831 unsigned int res)
17832{
17833 switch (res >> 26) {
17834 case ALC880_HP_EVENT:
17835 alc662_f5z_speaker_automute(codec);
17836 break;
17837 case ALC880_MIC_EVENT:
4f5d1706 17838 alc_mic_automute(codec);
f1d4e28b
KY
17839 break;
17840 }
17841}
17842
ebb83eeb 17843#define alc662_mode2_setup alc663_mode1_setup
4f5d1706 17844
f1d4e28b
KY
17845static void alc662_mode2_inithook(struct hda_codec *codec)
17846{
17847 alc662_f5z_speaker_automute(codec);
4f5d1706 17848 alc_mic_automute(codec);
f1d4e28b
KY
17849}
17850/* ***************** Mode3 ******************************/
17851static void alc663_mode3_unsol_event(struct hda_codec *codec,
17852 unsigned int res)
17853{
17854 switch (res >> 26) {
17855 case ALC880_HP_EVENT:
17856 alc663_two_hp_m1_speaker_automute(codec);
17857 break;
17858 case ALC880_MIC_EVENT:
4f5d1706 17859 alc_mic_automute(codec);
f1d4e28b
KY
17860 break;
17861 }
17862}
17863
ebb83eeb 17864#define alc663_mode3_setup alc663_mode1_setup
4f5d1706 17865
f1d4e28b
KY
17866static void alc663_mode3_inithook(struct hda_codec *codec)
17867{
17868 alc663_two_hp_m1_speaker_automute(codec);
4f5d1706 17869 alc_mic_automute(codec);
f1d4e28b
KY
17870}
17871/* ***************** Mode4 ******************************/
17872static void alc663_mode4_unsol_event(struct hda_codec *codec,
17873 unsigned int res)
17874{
17875 switch (res >> 26) {
17876 case ALC880_HP_EVENT:
17877 alc663_21jd_two_speaker_automute(codec);
17878 break;
17879 case ALC880_MIC_EVENT:
4f5d1706 17880 alc_mic_automute(codec);
f1d4e28b
KY
17881 break;
17882 }
17883}
17884
ebb83eeb 17885#define alc663_mode4_setup alc663_mode1_setup
4f5d1706 17886
f1d4e28b
KY
17887static void alc663_mode4_inithook(struct hda_codec *codec)
17888{
17889 alc663_21jd_two_speaker_automute(codec);
4f5d1706 17890 alc_mic_automute(codec);
f1d4e28b
KY
17891}
17892/* ***************** Mode5 ******************************/
17893static void alc663_mode5_unsol_event(struct hda_codec *codec,
17894 unsigned int res)
17895{
17896 switch (res >> 26) {
17897 case ALC880_HP_EVENT:
17898 alc663_15jd_two_speaker_automute(codec);
17899 break;
17900 case ALC880_MIC_EVENT:
4f5d1706 17901 alc_mic_automute(codec);
f1d4e28b
KY
17902 break;
17903 }
17904}
17905
ebb83eeb 17906#define alc663_mode5_setup alc663_mode1_setup
4f5d1706 17907
f1d4e28b
KY
17908static void alc663_mode5_inithook(struct hda_codec *codec)
17909{
17910 alc663_15jd_two_speaker_automute(codec);
4f5d1706 17911 alc_mic_automute(codec);
f1d4e28b
KY
17912}
17913/* ***************** Mode6 ******************************/
17914static void alc663_mode6_unsol_event(struct hda_codec *codec,
17915 unsigned int res)
17916{
17917 switch (res >> 26) {
17918 case ALC880_HP_EVENT:
17919 alc663_two_hp_m2_speaker_automute(codec);
17920 break;
17921 case ALC880_MIC_EVENT:
4f5d1706 17922 alc_mic_automute(codec);
f1d4e28b
KY
17923 break;
17924 }
17925}
17926
ebb83eeb 17927#define alc663_mode6_setup alc663_mode1_setup
4f5d1706 17928
f1d4e28b
KY
17929static void alc663_mode6_inithook(struct hda_codec *codec)
17930{
17931 alc663_two_hp_m2_speaker_automute(codec);
4f5d1706 17932 alc_mic_automute(codec);
f1d4e28b
KY
17933}
17934
ebb83eeb
KY
17935/* ***************** Mode7 ******************************/
17936static void alc663_mode7_unsol_event(struct hda_codec *codec,
17937 unsigned int res)
17938{
17939 switch (res >> 26) {
17940 case ALC880_HP_EVENT:
17941 alc663_two_hp_m7_speaker_automute(codec);
17942 break;
17943 case ALC880_MIC_EVENT:
17944 alc_mic_automute(codec);
17945 break;
17946 }
17947}
17948
17949#define alc663_mode7_setup alc663_mode1_setup
17950
17951static void alc663_mode7_inithook(struct hda_codec *codec)
17952{
17953 alc663_two_hp_m7_speaker_automute(codec);
17954 alc_mic_automute(codec);
17955}
17956
17957/* ***************** Mode8 ******************************/
17958static void alc663_mode8_unsol_event(struct hda_codec *codec,
17959 unsigned int res)
17960{
17961 switch (res >> 26) {
17962 case ALC880_HP_EVENT:
17963 alc663_two_hp_m8_speaker_automute(codec);
17964 break;
17965 case ALC880_MIC_EVENT:
17966 alc_mic_automute(codec);
17967 break;
17968 }
17969}
17970
17971#define alc663_mode8_setup alc663_m51va_setup
17972
17973static void alc663_mode8_inithook(struct hda_codec *codec)
17974{
17975 alc663_two_hp_m8_speaker_automute(codec);
17976 alc_mic_automute(codec);
17977}
17978
6dda9f4a
KY
17979static void alc663_g71v_hp_automute(struct hda_codec *codec)
17980{
17981 unsigned int present;
17982 unsigned char bits;
17983
864f92be 17984 present = snd_hda_jack_detect(codec, 0x21);
6dda9f4a
KY
17985 bits = present ? HDA_AMP_MUTE : 0;
17986 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17987 HDA_AMP_MUTE, bits);
17988 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17989 HDA_AMP_MUTE, bits);
17990}
17991
17992static void alc663_g71v_front_automute(struct hda_codec *codec)
17993{
17994 unsigned int present;
17995 unsigned char bits;
17996
864f92be 17997 present = snd_hda_jack_detect(codec, 0x15);
6dda9f4a
KY
17998 bits = present ? HDA_AMP_MUTE : 0;
17999 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18000 HDA_AMP_MUTE, bits);
18001}
18002
18003static void alc663_g71v_unsol_event(struct hda_codec *codec,
18004 unsigned int res)
18005{
18006 switch (res >> 26) {
18007 case ALC880_HP_EVENT:
18008 alc663_g71v_hp_automute(codec);
18009 break;
18010 case ALC880_FRONT_EVENT:
18011 alc663_g71v_front_automute(codec);
18012 break;
18013 case ALC880_MIC_EVENT:
4f5d1706 18014 alc_mic_automute(codec);
6dda9f4a
KY
18015 break;
18016 }
18017}
18018
4f5d1706
TI
18019#define alc663_g71v_setup alc663_m51va_setup
18020
6dda9f4a
KY
18021static void alc663_g71v_inithook(struct hda_codec *codec)
18022{
18023 alc663_g71v_front_automute(codec);
18024 alc663_g71v_hp_automute(codec);
4f5d1706 18025 alc_mic_automute(codec);
6dda9f4a
KY
18026}
18027
18028static void alc663_g50v_unsol_event(struct hda_codec *codec,
18029 unsigned int res)
18030{
18031 switch (res >> 26) {
18032 case ALC880_HP_EVENT:
18033 alc663_m51va_speaker_automute(codec);
18034 break;
18035 case ALC880_MIC_EVENT:
4f5d1706 18036 alc_mic_automute(codec);
6dda9f4a
KY
18037 break;
18038 }
18039}
18040
4f5d1706
TI
18041#define alc663_g50v_setup alc663_m51va_setup
18042
6dda9f4a
KY
18043static void alc663_g50v_inithook(struct hda_codec *codec)
18044{
18045 alc663_m51va_speaker_automute(codec);
4f5d1706 18046 alc_mic_automute(codec);
6dda9f4a
KY
18047}
18048
f1d4e28b
KY
18049static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18050 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18051 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b
KY
18052
18053 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
18054 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18055 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18056
18057 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
18058 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18059 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18060 { } /* end */
18061};
18062
9541ba1d
CP
18063static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18064 /* Master Playback automatically created from Speaker and Headphone */
18065 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18066 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18067 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18068 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18069
18070 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18071 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18072 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
18073
18074 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18075 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18076 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
18077 { } /* end */
18078};
18079
cb53c626
TI
18080#ifdef CONFIG_SND_HDA_POWER_SAVE
18081#define alc662_loopbacks alc880_loopbacks
18082#endif
18083
bc9f98a9 18084
def319f9 18085/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18086#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18087#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18088#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18089#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18090
18091/*
18092 * configuration and preset
18093 */
18094static const char *alc662_models[ALC662_MODEL_LAST] = {
18095 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18096 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18097 [ALC662_3ST_6ch] = "3stack-6ch",
18098 [ALC662_5ST_DIG] = "6stack-dig",
18099 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18100 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18101 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18102 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18103 [ALC663_ASUS_M51VA] = "m51va",
18104 [ALC663_ASUS_G71V] = "g71v",
18105 [ALC663_ASUS_H13] = "h13",
18106 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18107 [ALC663_ASUS_MODE1] = "asus-mode1",
18108 [ALC662_ASUS_MODE2] = "asus-mode2",
18109 [ALC663_ASUS_MODE3] = "asus-mode3",
18110 [ALC663_ASUS_MODE4] = "asus-mode4",
18111 [ALC663_ASUS_MODE5] = "asus-mode5",
18112 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18113 [ALC663_ASUS_MODE7] = "asus-mode7",
18114 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18115 [ALC272_DELL] = "dell",
18116 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18117 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18118 [ALC662_AUTO] = "auto",
18119};
18120
18121static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18122 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18123 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18124 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18125 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18126 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18127 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18128 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18129 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18130 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18131 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18132 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18133 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18134 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18135 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18136 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18137 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18138 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18139 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18140 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18141 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18142 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18143 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18144 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18145 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18146 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18147 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18148 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18149 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18150 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18151 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18152 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18153 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18154 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18155 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18156 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18157 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18158 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18159 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18160 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18161 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18162 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18163 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18164 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18165 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18166 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18167 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18168 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18169 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18170 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18171 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18172 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18173 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18174 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18175 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18176 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18177 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18178 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18179 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18180 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18181 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18182 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18183 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18184 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18185 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18186 ALC662_3ST_6ch_DIG),
4dee8baa 18187 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18188 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
18189 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18190 ALC662_3ST_6ch_DIG),
6227cdce 18191 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18192 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18193 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18194 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18195 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18196 ALC662_3ST_6ch_DIG),
dea0a509
TI
18197 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18198 ALC663_ASUS_H13),
bc9f98a9
KY
18199 {}
18200};
18201
18202static struct alc_config_preset alc662_presets[] = {
18203 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18204 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
18205 .init_verbs = { alc662_init_verbs },
18206 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18207 .dac_nids = alc662_dac_nids,
18208 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18209 .dig_in_nid = ALC662_DIGIN_NID,
18210 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18211 .channel_mode = alc662_3ST_2ch_modes,
18212 .input_mux = &alc662_capture_source,
18213 },
18214 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18215 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18216 .init_verbs = { alc662_init_verbs },
18217 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18218 .dac_nids = alc662_dac_nids,
18219 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18220 .dig_in_nid = ALC662_DIGIN_NID,
18221 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18222 .channel_mode = alc662_3ST_6ch_modes,
18223 .need_dac_fix = 1,
18224 .input_mux = &alc662_capture_source,
f12ab1e0 18225 },
bc9f98a9 18226 [ALC662_3ST_6ch] = {
f9e336f6 18227 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18228 .init_verbs = { alc662_init_verbs },
18229 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18230 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18231 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18232 .channel_mode = alc662_3ST_6ch_modes,
18233 .need_dac_fix = 1,
18234 .input_mux = &alc662_capture_source,
f12ab1e0 18235 },
bc9f98a9 18236 [ALC662_5ST_DIG] = {
f9e336f6 18237 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
18238 .init_verbs = { alc662_init_verbs },
18239 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18240 .dac_nids = alc662_dac_nids,
18241 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18242 .dig_in_nid = ALC662_DIGIN_NID,
18243 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18244 .channel_mode = alc662_5stack_modes,
18245 .input_mux = &alc662_capture_source,
18246 },
18247 [ALC662_LENOVO_101E] = {
f9e336f6 18248 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
18249 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18250 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18251 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18252 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18253 .channel_mode = alc662_3ST_2ch_modes,
18254 .input_mux = &alc662_lenovo_101e_capture_source,
18255 .unsol_event = alc662_lenovo_101e_unsol_event,
18256 .init_hook = alc662_lenovo_101e_all_automute,
18257 },
291702f0 18258 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18259 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
18260 .init_verbs = { alc662_init_verbs,
18261 alc662_eeepc_sue_init_verbs },
18262 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18263 .dac_nids = alc662_dac_nids,
291702f0
KY
18264 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18265 .channel_mode = alc662_3ST_2ch_modes,
291702f0 18266 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18267 .setup = alc662_eeepc_setup,
291702f0
KY
18268 .init_hook = alc662_eeepc_inithook,
18269 },
8c427226 18270 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18271 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18272 alc662_chmode_mixer },
18273 .init_verbs = { alc662_init_verbs,
18274 alc662_eeepc_ep20_sue_init_verbs },
18275 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18276 .dac_nids = alc662_dac_nids,
8c427226
KY
18277 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18278 .channel_mode = alc662_3ST_6ch_modes,
18279 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 18280 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18281 .setup = alc662_eeepc_ep20_setup,
8c427226
KY
18282 .init_hook = alc662_eeepc_ep20_inithook,
18283 },
f1d4e28b 18284 [ALC662_ECS] = {
f9e336f6 18285 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
18286 .init_verbs = { alc662_init_verbs,
18287 alc662_ecs_init_verbs },
18288 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18289 .dac_nids = alc662_dac_nids,
18290 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18291 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18292 .unsol_event = alc662_eeepc_unsol_event,
4f5d1706 18293 .setup = alc662_eeepc_setup,
f1d4e28b
KY
18294 .init_hook = alc662_eeepc_inithook,
18295 },
6dda9f4a 18296 [ALC663_ASUS_M51VA] = {
f9e336f6 18297 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18298 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18299 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18300 .dac_nids = alc662_dac_nids,
18301 .dig_out_nid = ALC662_DIGOUT_NID,
18302 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18303 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18304 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18305 .setup = alc663_m51va_setup,
6dda9f4a
KY
18306 .init_hook = alc663_m51va_inithook,
18307 },
18308 [ALC663_ASUS_G71V] = {
f9e336f6 18309 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
18310 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18311 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18312 .dac_nids = alc662_dac_nids,
18313 .dig_out_nid = ALC662_DIGOUT_NID,
18314 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18315 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a 18316 .unsol_event = alc663_g71v_unsol_event,
4f5d1706 18317 .setup = alc663_g71v_setup,
6dda9f4a
KY
18318 .init_hook = alc663_g71v_inithook,
18319 },
18320 [ALC663_ASUS_H13] = {
f9e336f6 18321 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
18322 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18323 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18324 .dac_nids = alc662_dac_nids,
18325 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18326 .channel_mode = alc662_3ST_2ch_modes,
6dda9f4a
KY
18327 .unsol_event = alc663_m51va_unsol_event,
18328 .init_hook = alc663_m51va_inithook,
18329 },
18330 [ALC663_ASUS_G50V] = {
f9e336f6 18331 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
18332 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18333 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18334 .dac_nids = alc662_dac_nids,
18335 .dig_out_nid = ALC662_DIGOUT_NID,
18336 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18337 .channel_mode = alc662_3ST_6ch_modes,
18338 .input_mux = &alc663_capture_source,
18339 .unsol_event = alc663_g50v_unsol_event,
4f5d1706 18340 .setup = alc663_g50v_setup,
6dda9f4a
KY
18341 .init_hook = alc663_g50v_inithook,
18342 },
f1d4e28b 18343 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18344 .mixers = { alc663_m51va_mixer },
18345 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18346 .init_verbs = { alc662_init_verbs,
18347 alc663_21jd_amic_init_verbs },
18348 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18349 .hp_nid = 0x03,
18350 .dac_nids = alc662_dac_nids,
18351 .dig_out_nid = ALC662_DIGOUT_NID,
18352 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18353 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18354 .unsol_event = alc663_mode1_unsol_event,
4f5d1706 18355 .setup = alc663_mode1_setup,
f1d4e28b
KY
18356 .init_hook = alc663_mode1_inithook,
18357 },
18358 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18359 .mixers = { alc662_1bjd_mixer },
18360 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18361 .init_verbs = { alc662_init_verbs,
18362 alc662_1bjd_amic_init_verbs },
18363 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18364 .dac_nids = alc662_dac_nids,
18365 .dig_out_nid = ALC662_DIGOUT_NID,
18366 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18367 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18368 .unsol_event = alc662_mode2_unsol_event,
4f5d1706 18369 .setup = alc662_mode2_setup,
f1d4e28b
KY
18370 .init_hook = alc662_mode2_inithook,
18371 },
18372 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18373 .mixers = { alc663_two_hp_m1_mixer },
18374 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18375 .init_verbs = { alc662_init_verbs,
18376 alc663_two_hp_amic_m1_init_verbs },
18377 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18378 .hp_nid = 0x03,
18379 .dac_nids = alc662_dac_nids,
18380 .dig_out_nid = ALC662_DIGOUT_NID,
18381 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18382 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18383 .unsol_event = alc663_mode3_unsol_event,
4f5d1706 18384 .setup = alc663_mode3_setup,
f1d4e28b
KY
18385 .init_hook = alc663_mode3_inithook,
18386 },
18387 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18388 .mixers = { alc663_asus_21jd_clfe_mixer },
18389 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18390 .init_verbs = { alc662_init_verbs,
18391 alc663_21jd_amic_init_verbs},
18392 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18393 .hp_nid = 0x03,
18394 .dac_nids = alc662_dac_nids,
18395 .dig_out_nid = ALC662_DIGOUT_NID,
18396 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18397 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18398 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18399 .setup = alc663_mode4_setup,
f1d4e28b
KY
18400 .init_hook = alc663_mode4_inithook,
18401 },
18402 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18403 .mixers = { alc663_asus_15jd_clfe_mixer },
18404 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18405 .init_verbs = { alc662_init_verbs,
18406 alc663_15jd_amic_init_verbs },
18407 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18408 .hp_nid = 0x03,
18409 .dac_nids = alc662_dac_nids,
18410 .dig_out_nid = ALC662_DIGOUT_NID,
18411 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18412 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18413 .unsol_event = alc663_mode5_unsol_event,
4f5d1706 18414 .setup = alc663_mode5_setup,
f1d4e28b
KY
18415 .init_hook = alc663_mode5_inithook,
18416 },
18417 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18418 .mixers = { alc663_two_hp_m2_mixer },
18419 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
18420 .init_verbs = { alc662_init_verbs,
18421 alc663_two_hp_amic_m2_init_verbs },
18422 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18423 .hp_nid = 0x03,
18424 .dac_nids = alc662_dac_nids,
18425 .dig_out_nid = ALC662_DIGOUT_NID,
18426 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18427 .channel_mode = alc662_3ST_2ch_modes,
f1d4e28b 18428 .unsol_event = alc663_mode6_unsol_event,
4f5d1706 18429 .setup = alc663_mode6_setup,
f1d4e28b
KY
18430 .init_hook = alc663_mode6_inithook,
18431 },
ebb83eeb
KY
18432 [ALC663_ASUS_MODE7] = {
18433 .mixers = { alc663_mode7_mixer },
18434 .cap_mixer = alc662_auto_capture_mixer,
18435 .init_verbs = { alc662_init_verbs,
18436 alc663_mode7_init_verbs },
18437 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18438 .hp_nid = 0x03,
18439 .dac_nids = alc662_dac_nids,
18440 .dig_out_nid = ALC662_DIGOUT_NID,
18441 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18442 .channel_mode = alc662_3ST_2ch_modes,
18443 .unsol_event = alc663_mode7_unsol_event,
18444 .setup = alc663_mode7_setup,
18445 .init_hook = alc663_mode7_inithook,
18446 },
18447 [ALC663_ASUS_MODE8] = {
18448 .mixers = { alc663_mode8_mixer },
18449 .cap_mixer = alc662_auto_capture_mixer,
18450 .init_verbs = { alc662_init_verbs,
18451 alc663_mode8_init_verbs },
18452 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18453 .hp_nid = 0x03,
18454 .dac_nids = alc662_dac_nids,
18455 .dig_out_nid = ALC662_DIGOUT_NID,
18456 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18457 .channel_mode = alc662_3ST_2ch_modes,
18458 .unsol_event = alc663_mode8_unsol_event,
18459 .setup = alc663_mode8_setup,
18460 .init_hook = alc663_mode8_inithook,
18461 },
622e84cd
KY
18462 [ALC272_DELL] = {
18463 .mixers = { alc663_m51va_mixer },
18464 .cap_mixer = alc272_auto_capture_mixer,
18465 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
18466 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18467 .dac_nids = alc662_dac_nids,
18468 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18469 .adc_nids = alc272_adc_nids,
18470 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18471 .capsrc_nids = alc272_capsrc_nids,
18472 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18473 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18474 .setup = alc663_m51va_setup,
622e84cd
KY
18475 .init_hook = alc663_m51va_inithook,
18476 },
18477 [ALC272_DELL_ZM1] = {
18478 .mixers = { alc663_m51va_mixer },
18479 .cap_mixer = alc662_auto_capture_mixer,
18480 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
18481 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18482 .dac_nids = alc662_dac_nids,
18483 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18484 .adc_nids = alc662_adc_nids,
b59bdf3b 18485 .num_adc_nids = 1,
622e84cd
KY
18486 .capsrc_nids = alc662_capsrc_nids,
18487 .channel_mode = alc662_3ST_2ch_modes,
622e84cd 18488 .unsol_event = alc663_m51va_unsol_event,
4f5d1706 18489 .setup = alc663_m51va_setup,
622e84cd
KY
18490 .init_hook = alc663_m51va_inithook,
18491 },
9541ba1d
CP
18492 [ALC272_SAMSUNG_NC10] = {
18493 .mixers = { alc272_nc10_mixer },
18494 .init_verbs = { alc662_init_verbs,
18495 alc663_21jd_amic_init_verbs },
18496 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18497 .dac_nids = alc272_dac_nids,
18498 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18499 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18500 /*.input_mux = &alc272_nc10_capture_source,*/
9541ba1d 18501 .unsol_event = alc663_mode4_unsol_event,
4f5d1706 18502 .setup = alc663_mode4_setup,
9541ba1d
CP
18503 .init_hook = alc663_mode4_inithook,
18504 },
bc9f98a9
KY
18505};
18506
18507
18508/*
18509 * BIOS auto configuration
18510 */
18511
7085ec12
TI
18512/* convert from MIX nid to DAC */
18513static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
18514{
18515 if (nid == 0x0f)
18516 return 0x02;
18517 else if (nid >= 0x0c && nid <= 0x0e)
18518 return nid - 0x0c + 0x02;
18519 else
18520 return 0;
18521}
18522
18523/* get MIX nid connected to the given pin targeted to DAC */
18524static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18525 hda_nid_t dac)
18526{
18527 hda_nid_t mix[4];
18528 int i, num;
18529
18530 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18531 for (i = 0; i < num; i++) {
18532 if (alc662_mix_to_dac(mix[i]) == dac)
18533 return mix[i];
18534 }
18535 return 0;
18536}
18537
18538/* look for an empty DAC slot */
18539static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18540{
18541 struct alc_spec *spec = codec->spec;
18542 hda_nid_t srcs[5];
18543 int i, j, num;
18544
18545 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18546 if (num < 0)
18547 return 0;
18548 for (i = 0; i < num; i++) {
18549 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
18550 if (!nid)
18551 continue;
18552 for (j = 0; j < spec->multiout.num_dacs; j++)
18553 if (spec->multiout.dac_nids[j] == nid)
18554 break;
18555 if (j >= spec->multiout.num_dacs)
18556 return nid;
18557 }
18558 return 0;
18559}
18560
18561/* fill in the dac_nids table from the parsed pin configuration */
18562static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18563 const struct auto_pin_cfg *cfg)
18564{
18565 struct alc_spec *spec = codec->spec;
18566 int i;
18567 hda_nid_t dac;
18568
18569 spec->multiout.dac_nids = spec->private_dac_nids;
18570 for (i = 0; i < cfg->line_outs; i++) {
18571 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
18572 if (!dac)
18573 continue;
18574 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
18575 }
18576 return 0;
18577}
18578
0afe5f89 18579static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18580 hda_nid_t nid, unsigned int chs)
18581{
0afe5f89 18582 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
7085ec12
TI
18583 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18584}
18585
0afe5f89 18586static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
7085ec12
TI
18587 hda_nid_t nid, unsigned int chs)
18588{
0afe5f89 18589 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12
TI
18590 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18591}
18592
18593#define alc662_add_stereo_vol(spec, pfx, nid) \
18594 alc662_add_vol_ctl(spec, pfx, nid, 3)
18595#define alc662_add_stereo_sw(spec, pfx, nid) \
18596 alc662_add_sw_ctl(spec, pfx, nid, 3)
18597
bc9f98a9 18598/* add playback controls from the parsed DAC table */
7085ec12 18599static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
18600 const struct auto_pin_cfg *cfg)
18601{
7085ec12 18602 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18603 static const char *chname[4] = {
18604 "Front", "Surround", NULL /*CLFE*/, "Side"
18605 };
7085ec12 18606 hda_nid_t nid, mix;
bc9f98a9
KY
18607 int i, err;
18608
18609 for (i = 0; i < cfg->line_outs; i++) {
7085ec12
TI
18610 nid = spec->multiout.dac_nids[i];
18611 if (!nid)
18612 continue;
18613 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
18614 if (!mix)
bc9f98a9 18615 continue;
bc9f98a9
KY
18616 if (i == 2) {
18617 /* Center/LFE */
7085ec12 18618 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
18619 if (err < 0)
18620 return err;
7085ec12 18621 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
18622 if (err < 0)
18623 return err;
7085ec12 18624 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
18625 if (err < 0)
18626 return err;
7085ec12 18627 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
18628 if (err < 0)
18629 return err;
18630 } else {
0d884cb9
TI
18631 const char *pfx;
18632 if (cfg->line_outs == 1 &&
18633 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
7085ec12 18634 if (cfg->hp_outs)
0d884cb9
TI
18635 pfx = "Speaker";
18636 else
18637 pfx = "PCM";
18638 } else
18639 pfx = chname[i];
7085ec12 18640 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
bc9f98a9
KY
18641 if (err < 0)
18642 return err;
0d884cb9
TI
18643 if (cfg->line_outs == 1 &&
18644 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
18645 pfx = "Speaker";
7085ec12 18646 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
bc9f98a9
KY
18647 if (err < 0)
18648 return err;
18649 }
18650 }
18651 return 0;
18652}
18653
18654/* add playback controls for speaker and HP outputs */
7085ec12
TI
18655/* return DAC nid if any new DAC is assigned */
18656static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
18657 const char *pfx)
18658{
7085ec12
TI
18659 struct alc_spec *spec = codec->spec;
18660 hda_nid_t nid, mix;
bc9f98a9 18661 int err;
bc9f98a9
KY
18662
18663 if (!pin)
18664 return 0;
7085ec12
TI
18665 nid = alc662_look_for_dac(codec, pin);
18666 if (!nid) {
7085ec12
TI
18667 /* the corresponding DAC is already occupied */
18668 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18669 return 0; /* no way */
18670 /* create a switch only */
0afe5f89 18671 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 18672 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
18673 }
18674
7085ec12
TI
18675 mix = alc662_dac_to_mix(codec, pin, nid);
18676 if (!mix)
18677 return 0;
18678 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
18679 if (err < 0)
18680 return err;
18681 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
18682 if (err < 0)
18683 return err;
18684 return nid;
bc9f98a9
KY
18685}
18686
18687/* create playback/capture controls for input pins */
05f5f477 18688#define alc662_auto_create_input_ctls \
4b7348a1 18689 alc882_auto_create_input_ctls
bc9f98a9
KY
18690
18691static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
18692 hda_nid_t nid, int pin_type,
7085ec12 18693 hda_nid_t dac)
bc9f98a9 18694{
7085ec12 18695 int i, num;
ce503f38 18696 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 18697
f6c7e546 18698 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9 18699 /* need the manual connection? */
7085ec12
TI
18700 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
18701 if (num <= 1)
18702 return;
18703 for (i = 0; i < num; i++) {
18704 if (alc662_mix_to_dac(srcs[i]) != dac)
18705 continue;
18706 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
18707 return;
bc9f98a9
KY
18708 }
18709}
18710
18711static void alc662_auto_init_multi_out(struct hda_codec *codec)
18712{
18713 struct alc_spec *spec = codec->spec;
7085ec12 18714 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
18715 int i;
18716
18717 for (i = 0; i <= HDA_SIDE; i++) {
18718 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18719 if (nid)
baba8ee9 18720 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 18721 spec->multiout.dac_nids[i]);
bc9f98a9
KY
18722 }
18723}
18724
18725static void alc662_auto_init_hp_out(struct hda_codec *codec)
18726{
18727 struct alc_spec *spec = codec->spec;
18728 hda_nid_t pin;
18729
18730 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
18731 if (pin)
18732 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
18733 spec->multiout.hp_nid);
f6c7e546
TI
18734 pin = spec->autocfg.speaker_pins[0];
18735 if (pin)
7085ec12
TI
18736 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
18737 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
18738}
18739
bc9f98a9
KY
18740#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
18741
18742static void alc662_auto_init_analog_input(struct hda_codec *codec)
18743{
18744 struct alc_spec *spec = codec->spec;
18745 int i;
18746
18747 for (i = 0; i < AUTO_PIN_LAST; i++) {
18748 hda_nid_t nid = spec->autocfg.input_pins[i];
05f5f477 18749 if (alc_is_input_pin(codec, nid)) {
23f0c048 18750 alc_set_input_pin(codec, nid, i);
52ca15b7 18751 if (nid != ALC662_PIN_CD_NID &&
e82c025b 18752 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
18753 snd_hda_codec_write(codec, nid, 0,
18754 AC_VERB_SET_AMP_GAIN_MUTE,
18755 AMP_OUT_MUTE);
18756 }
18757 }
18758}
18759
f511b01c
TI
18760#define alc662_auto_init_input_src alc882_auto_init_input_src
18761
bc9f98a9
KY
18762static int alc662_parse_auto_config(struct hda_codec *codec)
18763{
18764 struct alc_spec *spec = codec->spec;
18765 int err;
18766 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
18767
18768 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
18769 alc662_ignore);
18770 if (err < 0)
18771 return err;
18772 if (!spec->autocfg.line_outs)
18773 return 0; /* can't find valid BIOS pin config */
18774
7085ec12 18775 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
f12ab1e0
TI
18776 if (err < 0)
18777 return err;
7085ec12 18778 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
18779 if (err < 0)
18780 return err;
7085ec12 18781 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
18782 spec->autocfg.speaker_pins[0],
18783 "Speaker");
18784 if (err < 0)
18785 return err;
7085ec12
TI
18786 if (err)
18787 spec->multiout.extra_out_nid[0] = err;
18788 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
18789 "Headphone");
18790 if (err < 0)
18791 return err;
7085ec12
TI
18792 if (err)
18793 spec->multiout.hp_nid = err;
05f5f477 18794 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 18795 if (err < 0)
bc9f98a9
KY
18796 return err;
18797
18798 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
18799
757899ac 18800 alc_auto_parse_digital(codec);
bc9f98a9 18801
603c4019 18802 if (spec->kctls.list)
d88897ea 18803 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
18804
18805 spec->num_mux_defs = 1;
61b9b9b1 18806 spec->input_mux = &spec->private_imux[0];
ea1fb29a 18807
cec27c89
KY
18808 add_verb(spec, alc662_init_verbs);
18809 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
d1eb57f4 18810 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
cec27c89
KY
18811 add_verb(spec, alc663_init_verbs);
18812
18813 if (codec->vendor_id == 0x10ec0272)
18814 add_verb(spec, alc272_init_verbs);
ee979a14
TI
18815
18816 err = alc_auto_add_mic_boost(codec);
18817 if (err < 0)
18818 return err;
18819
6227cdce
KY
18820 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18821 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18822 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18823 else
18824 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 18825
8c87286f 18826 return 1;
bc9f98a9
KY
18827}
18828
18829/* additional initialization for auto-configuration model */
18830static void alc662_auto_init(struct hda_codec *codec)
18831{
f6c7e546 18832 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
18833 alc662_auto_init_multi_out(codec);
18834 alc662_auto_init_hp_out(codec);
18835 alc662_auto_init_analog_input(codec);
f511b01c 18836 alc662_auto_init_input_src(codec);
757899ac 18837 alc_auto_init_digital(codec);
f6c7e546 18838 if (spec->unsol_event)
7fb0d78f 18839 alc_inithook(codec);
bc9f98a9
KY
18840}
18841
18842static int patch_alc662(struct hda_codec *codec)
18843{
18844 struct alc_spec *spec;
18845 int err, board_config;
18846
18847 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
18848 if (!spec)
18849 return -ENOMEM;
18850
18851 codec->spec = spec;
18852
da00c244
KY
18853 alc_auto_parse_customize_define(codec);
18854
2c3bf9ab
TI
18855 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18856
c027ddcd
KY
18857 if (alc_read_coef_idx(codec, 0) == 0x8020)
18858 alc_codec_rename(codec, "ALC661");
18859 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) &&
18860 codec->bus->pci->subsystem_vendor == 0x1025 &&
18861 spec->cdefine.platform_type == 1)
18862 alc_codec_rename(codec, "ALC272X");
274693f3 18863
bc9f98a9
KY
18864 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
18865 alc662_models,
18866 alc662_cfg_tbl);
18867 if (board_config < 0) {
9a11f1aa
TI
18868 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
18869 codec->chip_name);
bc9f98a9
KY
18870 board_config = ALC662_AUTO;
18871 }
18872
18873 if (board_config == ALC662_AUTO) {
18874 /* automatic parse from the BIOS config */
18875 err = alc662_parse_auto_config(codec);
18876 if (err < 0) {
18877 alc_free(codec);
18878 return err;
8c87286f 18879 } else if (!err) {
bc9f98a9
KY
18880 printk(KERN_INFO
18881 "hda_codec: Cannot set up configuration "
18882 "from BIOS. Using base mode...\n");
18883 board_config = ALC662_3ST_2ch_DIG;
18884 }
18885 }
18886
dc1eae25 18887 if (has_cdefine_beep(codec)) {
8af2591d
TI
18888 err = snd_hda_attach_beep_device(codec, 0x1);
18889 if (err < 0) {
18890 alc_free(codec);
18891 return err;
18892 }
680cd536
KK
18893 }
18894
bc9f98a9 18895 if (board_config != ALC662_AUTO)
e9c364c0 18896 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 18897
bc9f98a9
KY
18898 spec->stream_analog_playback = &alc662_pcm_analog_playback;
18899 spec->stream_analog_capture = &alc662_pcm_analog_capture;
18900
bc9f98a9
KY
18901 spec->stream_digital_playback = &alc662_pcm_digital_playback;
18902 spec->stream_digital_capture = &alc662_pcm_digital_capture;
18903
dd704698
TI
18904 if (!spec->adc_nids) {
18905 spec->adc_nids = alc662_adc_nids;
18906 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
18907 }
18908 if (!spec->capsrc_nids)
18909 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 18910
f9e336f6 18911 if (!spec->cap_mixer)
b59bdf3b 18912 set_capture_mixer(codec);
cec27c89 18913
dc1eae25 18914 if (has_cdefine_beep(codec)) {
da00c244
KY
18915 switch (codec->vendor_id) {
18916 case 0x10ec0662:
18917 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18918 break;
18919 case 0x10ec0272:
18920 case 0x10ec0663:
18921 case 0x10ec0665:
18922 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18923 break;
18924 case 0x10ec0273:
18925 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18926 break;
18927 }
cec27c89 18928 }
2134ea4f
TI
18929 spec->vmaster_nid = 0x02;
18930
bc9f98a9
KY
18931 codec->patch_ops = alc_patch_ops;
18932 if (board_config == ALC662_AUTO)
18933 spec->init_hook = alc662_auto_init;
cb53c626
TI
18934#ifdef CONFIG_SND_HDA_POWER_SAVE
18935 if (!spec->loopback.amplist)
18936 spec->loopback.amplist = alc662_loopbacks;
18937#endif
bc9f98a9
KY
18938
18939 return 0;
18940}
18941
274693f3
KY
18942static int patch_alc888(struct hda_codec *codec)
18943{
18944 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
18945 kfree(codec->chip_name);
18946 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
18947 if (!codec->chip_name) {
18948 alc_free(codec);
274693f3 18949 return -ENOMEM;
ac2c92e0
TI
18950 }
18951 return patch_alc662(codec);
274693f3 18952 }
ac2c92e0 18953 return patch_alc882(codec);
274693f3
KY
18954}
18955
d1eb57f4
KY
18956/*
18957 * ALC680 support
18958 */
18959#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
18960#define alc680_modes alc260_modes
18961
18962static hda_nid_t alc680_dac_nids[3] = {
18963 /* Lout1, Lout2, hp */
18964 0x02, 0x03, 0x04
18965};
18966
18967static hda_nid_t alc680_adc_nids[3] = {
18968 /* ADC0-2 */
18969 /* DMIC, MIC, Line-in*/
18970 0x07, 0x08, 0x09
18971};
18972
18973static struct snd_kcontrol_new alc680_base_mixer[] = {
18974 /* output mixer control */
18975 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
18976 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18977 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
18978 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
18979 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
18980 { }
18981};
18982
18983static struct snd_kcontrol_new alc680_capture_mixer[] = {
18984 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
18985 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
18986 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
18987 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
18988 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
18989 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
18990 { } /* end */
18991};
18992
18993/*
18994 * generic initialization of ADC, input mixers and output mixers
18995 */
18996static struct hda_verb alc680_init_verbs[] = {
18997 /* Unmute DAC0-1 and set vol = 0 */
18998 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
18999 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
19000 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
19001
19002 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
19003 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
19004 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
19005 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
19006 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
19007
19008 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19009 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19010 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19011 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19012 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19013 { }
19014};
19015
19016/* create input playback/capture controls for the given pin */
19017static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19018 const char *ctlname, int idx)
19019{
19020 hda_nid_t dac;
19021 int err;
19022
19023 switch (nid) {
19024 case 0x14:
19025 dac = 0x02;
19026 break;
19027 case 0x15:
19028 dac = 0x03;
19029 break;
19030 case 0x16:
19031 dac = 0x04;
19032 break;
19033 default:
19034 return 0;
19035 }
19036 if (spec->multiout.dac_nids[0] != dac &&
19037 spec->multiout.dac_nids[1] != dac) {
19038 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19039 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19040 HDA_OUTPUT));
19041 if (err < 0)
19042 return err;
19043
19044 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19045 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19046
19047 if (err < 0)
19048 return err;
19049 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19050 }
19051
19052 return 0;
19053}
19054
19055/* add playback controls from the parsed DAC table */
19056static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19057 const struct auto_pin_cfg *cfg)
19058{
19059 hda_nid_t nid;
19060 int err;
19061
19062 spec->multiout.dac_nids = spec->private_dac_nids;
19063
19064 nid = cfg->line_out_pins[0];
19065 if (nid) {
19066 const char *name;
19067 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19068 name = "Speaker";
19069 else
19070 name = "Front";
19071 err = alc680_new_analog_output(spec, nid, name, 0);
19072 if (err < 0)
19073 return err;
19074 }
19075
19076 nid = cfg->speaker_pins[0];
19077 if (nid) {
19078 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19079 if (err < 0)
19080 return err;
19081 }
19082 nid = cfg->hp_pins[0];
19083 if (nid) {
19084 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19085 if (err < 0)
19086 return err;
19087 }
19088
19089 return 0;
19090}
19091
19092static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19093 hda_nid_t nid, int pin_type)
19094{
19095 alc_set_pin_output(codec, nid, pin_type);
19096}
19097
19098static void alc680_auto_init_multi_out(struct hda_codec *codec)
19099{
19100 struct alc_spec *spec = codec->spec;
19101 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19102 if (nid) {
19103 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19104 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19105 }
19106}
19107
19108static void alc680_auto_init_hp_out(struct hda_codec *codec)
19109{
19110 struct alc_spec *spec = codec->spec;
19111 hda_nid_t pin;
19112
19113 pin = spec->autocfg.hp_pins[0];
19114 if (pin)
19115 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19116 pin = spec->autocfg.speaker_pins[0];
19117 if (pin)
19118 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19119}
19120
19121/* pcm configuration: identical with ALC880 */
19122#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19123#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19124#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19125#define alc680_pcm_digital_playback alc880_pcm_digital_playback
19126
19127static struct hda_input_mux alc680_capture_source = {
19128 .num_items = 1,
19129 .items = {
19130 { "Mic", 0x0 },
19131 },
19132};
19133
19134/*
19135 * BIOS auto configuration
19136 */
19137static int alc680_parse_auto_config(struct hda_codec *codec)
19138{
19139 struct alc_spec *spec = codec->spec;
19140 int err;
19141 static hda_nid_t alc680_ignore[] = { 0 };
19142
19143 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19144 alc680_ignore);
19145 if (err < 0)
19146 return err;
19147 if (!spec->autocfg.line_outs) {
19148 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19149 spec->multiout.max_channels = 2;
19150 spec->no_analog = 1;
19151 goto dig_only;
19152 }
19153 return 0; /* can't find valid BIOS pin config */
19154 }
19155 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19156 if (err < 0)
19157 return err;
19158
19159 spec->multiout.max_channels = 2;
19160
19161 dig_only:
19162 /* digital only support output */
757899ac 19163 alc_auto_parse_digital(codec);
d1eb57f4
KY
19164 if (spec->kctls.list)
19165 add_mixer(spec, spec->kctls.list);
19166
19167 add_verb(spec, alc680_init_verbs);
19168 spec->num_mux_defs = 1;
19169 spec->input_mux = &alc680_capture_source;
19170
19171 err = alc_auto_add_mic_boost(codec);
19172 if (err < 0)
19173 return err;
19174
19175 return 1;
19176}
19177
19178#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19179
19180/* init callback for auto-configuration model -- overriding the default init */
19181static void alc680_auto_init(struct hda_codec *codec)
19182{
19183 struct alc_spec *spec = codec->spec;
19184 alc680_auto_init_multi_out(codec);
19185 alc680_auto_init_hp_out(codec);
19186 alc680_auto_init_analog_input(codec);
757899ac 19187 alc_auto_init_digital(codec);
d1eb57f4
KY
19188 if (spec->unsol_event)
19189 alc_inithook(codec);
19190}
19191
19192/*
19193 * configuration and preset
19194 */
19195static const char *alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19196 [ALC680_BASE] = "base",
19197 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19198};
19199
19200static struct snd_pci_quirk alc680_cfg_tbl[] = {
19201 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19202 {}
19203};
19204
19205static struct alc_config_preset alc680_presets[] = {
19206 [ALC680_BASE] = {
19207 .mixers = { alc680_base_mixer },
19208 .cap_mixer = alc680_capture_mixer,
19209 .init_verbs = { alc680_init_verbs },
19210 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19211 .dac_nids = alc680_dac_nids,
19212 .num_adc_nids = ARRAY_SIZE(alc680_adc_nids),
19213 .adc_nids = alc680_adc_nids,
19214 .hp_nid = 0x04,
19215 .dig_out_nid = ALC680_DIGOUT_NID,
19216 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19217 .channel_mode = alc680_modes,
19218 .input_mux = &alc680_capture_source,
19219 },
19220};
19221
19222static int patch_alc680(struct hda_codec *codec)
19223{
19224 struct alc_spec *spec;
19225 int board_config;
19226 int err;
19227
19228 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19229 if (spec == NULL)
19230 return -ENOMEM;
19231
19232 codec->spec = spec;
19233
19234 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19235 alc680_models,
19236 alc680_cfg_tbl);
19237
19238 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19239 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19240 codec->chip_name);
19241 board_config = ALC680_AUTO;
19242 }
19243
19244 if (board_config == ALC680_AUTO) {
19245 /* automatic parse from the BIOS config */
19246 err = alc680_parse_auto_config(codec);
19247 if (err < 0) {
19248 alc_free(codec);
19249 return err;
19250 } else if (!err) {
19251 printk(KERN_INFO
19252 "hda_codec: Cannot set up configuration "
19253 "from BIOS. Using base mode...\n");
19254 board_config = ALC680_BASE;
19255 }
19256 }
19257
19258 if (board_config != ALC680_AUTO)
19259 setup_preset(codec, &alc680_presets[board_config]);
19260
19261 spec->stream_analog_playback = &alc680_pcm_analog_playback;
19262 spec->stream_analog_capture = &alc680_pcm_analog_capture;
19263 spec->stream_analog_alt_capture = &alc680_pcm_analog_alt_capture;
19264 spec->stream_digital_playback = &alc680_pcm_digital_playback;
19265
19266 if (!spec->adc_nids) {
19267 spec->adc_nids = alc680_adc_nids;
19268 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19269 }
19270
19271 if (!spec->cap_mixer)
19272 set_capture_mixer(codec);
19273
19274 spec->vmaster_nid = 0x02;
19275
19276 codec->patch_ops = alc_patch_ops;
19277 if (board_config == ALC680_AUTO)
19278 spec->init_hook = alc680_auto_init;
19279
19280 return 0;
19281}
19282
1da177e4
LT
19283/*
19284 * patch entries
19285 */
1289e9e8 19286static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 19287 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 19288 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 19289 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 19290 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 19291 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 19292 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 19293 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 19294 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 19295 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 19296 .patch = patch_alc861 },
f32610ed
JS
19297 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19298 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19299 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 19300 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 19301 .patch = patch_alc882 },
bc9f98a9
KY
19302 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19303 .patch = patch_alc662 },
6dda9f4a 19304 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 19305 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 19306 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 19307 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 19308 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 19309 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 19310 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 19311 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 19312 .patch = patch_alc882 },
cb308f97 19313 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 19314 .patch = patch_alc882 },
df694daa 19315 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
4953550a 19316 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
4442608d 19317 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 19318 .patch = patch_alc882 },
274693f3 19319 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 19320 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 19321 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
19322 {} /* terminator */
19323};
1289e9e8
TI
19324
19325MODULE_ALIAS("snd-hda-codec-id:10ec*");
19326
19327MODULE_LICENSE("GPL");
19328MODULE_DESCRIPTION("Realtek HD-audio codec");
19329
19330static struct hda_codec_preset_list realtek_list = {
19331 .preset = snd_hda_preset_realtek,
19332 .owner = THIS_MODULE,
19333};
19334
19335static int __init patch_realtek_init(void)
19336{
19337 return snd_hda_add_codec_preset(&realtek_list);
19338}
19339
19340static void __exit patch_realtek_exit(void)
19341{
19342 snd_hda_delete_codec_preset(&realtek_list);
19343}
19344
19345module_init(patch_realtek_init)
19346module_exit(patch_realtek_exit)