]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Merge patch_alc882() and patch_alc883()
[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,
f53281e6
KY
134 ALC269_ASUS_EEEPC_P703,
135 ALC269_ASUS_EEEPC_P901,
26f5df26 136 ALC269_FUJITSU,
64154835 137 ALC269_LIFEBOOK,
f6a92248
KY
138 ALC269_AUTO,
139 ALC269_MODEL_LAST /* last tag */
140};
141
df694daa
KY
142/* ALC861 models */
143enum {
144 ALC861_3ST,
9c7f852e 145 ALC660_3ST,
df694daa
KY
146 ALC861_3ST_DIG,
147 ALC861_6ST_DIG,
22309c3e 148 ALC861_UNIWILL_M31,
a53d1aec 149 ALC861_TOSHIBA,
7cdbff94 150 ALC861_ASUS,
56bb0cab 151 ALC861_ASUS_LAPTOP,
df694daa
KY
152 ALC861_AUTO,
153 ALC861_MODEL_LAST,
154};
155
f32610ed
JS
156/* ALC861-VD models */
157enum {
158 ALC660VD_3ST,
6963f84c 159 ALC660VD_3ST_DIG,
13c94744 160 ALC660VD_ASUS_V1S,
f32610ed
JS
161 ALC861VD_3ST,
162 ALC861VD_3ST_DIG,
163 ALC861VD_6ST_DIG,
bdd148a3 164 ALC861VD_LENOVO,
272a527c 165 ALC861VD_DALLAS,
d1a991a6 166 ALC861VD_HP,
f32610ed
JS
167 ALC861VD_AUTO,
168 ALC861VD_MODEL_LAST,
169};
170
bc9f98a9
KY
171/* ALC662 models */
172enum {
173 ALC662_3ST_2ch_DIG,
174 ALC662_3ST_6ch_DIG,
175 ALC662_3ST_6ch,
176 ALC662_5ST_DIG,
177 ALC662_LENOVO_101E,
291702f0 178 ALC662_ASUS_EEEPC_P701,
8c427226 179 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
180 ALC663_ASUS_M51VA,
181 ALC663_ASUS_G71V,
182 ALC663_ASUS_H13,
183 ALC663_ASUS_G50V,
f1d4e28b
KY
184 ALC662_ECS,
185 ALC663_ASUS_MODE1,
186 ALC662_ASUS_MODE2,
187 ALC663_ASUS_MODE3,
188 ALC663_ASUS_MODE4,
189 ALC663_ASUS_MODE5,
190 ALC663_ASUS_MODE6,
622e84cd
KY
191 ALC272_DELL,
192 ALC272_DELL_ZM1,
9541ba1d 193 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
194 ALC662_AUTO,
195 ALC662_MODEL_LAST,
196};
197
df694daa
KY
198/* ALC882 models */
199enum {
200 ALC882_3ST_DIG,
201 ALC882_6ST_DIG,
4b146cb0 202 ALC882_ARIMA,
bdd148a3 203 ALC882_W2JC,
272a527c
KY
204 ALC882_TARGA,
205 ALC882_ASUS_A7J,
914759b7 206 ALC882_ASUS_A7M,
9102cd1c 207 ALC885_MACPRO,
87350ad0 208 ALC885_MBP3,
41d5545d 209 ALC885_MB5,
c54728d8 210 ALC885_IMAC24,
9c7f852e
TI
211 ALC883_3ST_2ch_DIG,
212 ALC883_3ST_6ch_DIG,
213 ALC883_3ST_6ch,
214 ALC883_6ST_DIG,
ccc656ce
KY
215 ALC883_TARGA_DIG,
216 ALC883_TARGA_2ch_DIG,
64a8be74 217 ALC883_TARGA_8ch_DIG,
bab282b9 218 ALC883_ACER,
2880a867 219 ALC883_ACER_ASPIRE,
5b2d1eca 220 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 221 ALC888_ACER_ASPIRE_6530G,
3b315d70 222 ALC888_ACER_ASPIRE_8930G,
c07584c8 223 ALC883_MEDION,
ea1fb29a 224 ALC883_MEDION_MD2,
b373bdeb 225 ALC883_LAPTOP_EAPD,
bc9f98a9 226 ALC883_LENOVO_101E_2ch,
272a527c 227 ALC883_LENOVO_NB0763,
189609ae 228 ALC888_LENOVO_MS7195_DIG,
e2757d5e 229 ALC888_LENOVO_SKY,
ea1fb29a 230 ALC883_HAIER_W66,
4723c022 231 ALC888_3ST_HP,
5795b9e6 232 ALC888_6ST_DELL,
a8848bd6 233 ALC883_MITAC,
0c4cc443 234 ALC883_CLEVO_M720,
fb97dc67 235 ALC883_FUJITSU_PI2515,
ef8ef5fb 236 ALC888_FUJITSU_XA3530,
17bba1b7 237 ALC883_3ST_6ch_INTEL,
e2757d5e
KY
238 ALC888_ASUS_M90V,
239 ALC888_ASUS_EEE1601,
eb4c41d3 240 ALC889A_MB31,
3ab90935 241 ALC1200_ASUS_P5Q,
3e1647c5 242 ALC883_SONY_VAIO_TT,
4953550a
TI
243 ALC882_AUTO,
244 ALC882_MODEL_LAST,
9c7f852e
TI
245};
246
df694daa
KY
247/* for GPIO Poll */
248#define GPIO_MASK 0x03
249
4a79ba34
TI
250/* extra amp-initialization sequence types */
251enum {
252 ALC_INIT_NONE,
253 ALC_INIT_DEFAULT,
254 ALC_INIT_GPIO1,
255 ALC_INIT_GPIO2,
256 ALC_INIT_GPIO3,
257};
258
1da177e4
LT
259struct alc_spec {
260 /* codec parameterization */
df694daa 261 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 262 unsigned int num_mixers;
f9e336f6 263 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 264 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 265
df694daa 266 const struct hda_verb *init_verbs[5]; /* initialization verbs
9c7f852e
TI
267 * don't forget NULL
268 * termination!
e9edcee0
TI
269 */
270 unsigned int num_init_verbs;
1da177e4 271
812a2cca 272 char stream_name_analog[16]; /* analog PCM stream */
1da177e4
LT
273 struct hda_pcm_stream *stream_analog_playback;
274 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
275 struct hda_pcm_stream *stream_analog_alt_playback;
276 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 277
812a2cca 278 char stream_name_digital[16]; /* digital PCM stream */
1da177e4
LT
279 struct hda_pcm_stream *stream_digital_playback;
280 struct hda_pcm_stream *stream_digital_capture;
281
282 /* playback */
16ded525
TI
283 struct hda_multi_out multiout; /* playback set-up
284 * max_channels, dacs must be set
285 * dig_out_nid and hp_nid are optional
286 */
6330079f 287 hda_nid_t alt_dac_nid;
6a05ac4a 288 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 289 int dig_out_type;
1da177e4
LT
290
291 /* capture */
292 unsigned int num_adc_nids;
293 hda_nid_t *adc_nids;
e1406348 294 hda_nid_t *capsrc_nids;
16ded525 295 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4
LT
296
297 /* capture source */
a1e8d2da 298 unsigned int num_mux_defs;
1da177e4
LT
299 const struct hda_input_mux *input_mux;
300 unsigned int cur_mux[3];
301
302 /* channel model */
d2a6d7dc 303 const struct hda_channel_mode *channel_mode;
1da177e4 304 int num_channel_mode;
4e195a7b 305 int need_dac_fix;
3b315d70
HM
306 int const_channel_count;
307 int ext_channel_count;
1da177e4
LT
308
309 /* PCM information */
4c5186ed 310 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 311
e9edcee0
TI
312 /* dynamic controls, init_verbs and input_mux */
313 struct auto_pin_cfg autocfg;
603c4019 314 struct snd_array kctls;
61b9b9b1 315 struct hda_input_mux private_imux[3];
41923e44 316 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
317 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
318 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 319
ae6b813a
TI
320 /* hooks */
321 void (*init_hook)(struct hda_codec *codec);
322 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
323
834be88d
TI
324 /* for pin sensing */
325 unsigned int sense_updated: 1;
326 unsigned int jack_present: 1;
bec15c3a 327 unsigned int master_sw: 1;
cb53c626 328
e64f14f4
TI
329 /* other flags */
330 unsigned int no_analog :1; /* digital I/O only */
4a79ba34 331 int init_amp;
e64f14f4 332
2134ea4f
TI
333 /* for virtual master */
334 hda_nid_t vmaster_nid;
cb53c626
TI
335#ifdef CONFIG_SND_HDA_POWER_SAVE
336 struct hda_loopback_check loopback;
337#endif
2c3bf9ab
TI
338
339 /* for PLL fix */
340 hda_nid_t pll_nid;
341 unsigned int pll_coef_idx, pll_coef_bit;
df694daa
KY
342};
343
344/*
345 * configuration template - to be copied to the spec instance
346 */
347struct alc_config_preset {
9c7f852e
TI
348 struct snd_kcontrol_new *mixers[5]; /* should be identical size
349 * with spec
350 */
f9e336f6 351 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
352 const struct hda_verb *init_verbs[5];
353 unsigned int num_dacs;
354 hda_nid_t *dac_nids;
355 hda_nid_t dig_out_nid; /* optional */
356 hda_nid_t hp_nid; /* optional */
b25c9da1 357 hda_nid_t *slave_dig_outs;
df694daa
KY
358 unsigned int num_adc_nids;
359 hda_nid_t *adc_nids;
e1406348 360 hda_nid_t *capsrc_nids;
df694daa
KY
361 hda_nid_t dig_in_nid;
362 unsigned int num_channel_mode;
363 const struct hda_channel_mode *channel_mode;
4e195a7b 364 int need_dac_fix;
3b315d70 365 int const_channel_count;
a1e8d2da 366 unsigned int num_mux_defs;
df694daa 367 const struct hda_input_mux *input_mux;
ae6b813a
TI
368 void (*unsol_event)(struct hda_codec *, unsigned int);
369 void (*init_hook)(struct hda_codec *);
cb53c626
TI
370#ifdef CONFIG_SND_HDA_POWER_SAVE
371 struct hda_amp_list *loopbacks;
372#endif
1da177e4
LT
373};
374
1da177e4
LT
375
376/*
377 * input MUX handling
378 */
9c7f852e
TI
379static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
380 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
381{
382 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
383 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
384 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
385 if (mux_idx >= spec->num_mux_defs)
386 mux_idx = 0;
387 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
388}
389
9c7f852e
TI
390static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
391 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
392{
393 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
394 struct alc_spec *spec = codec->spec;
395 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
396
397 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
398 return 0;
399}
400
9c7f852e
TI
401static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
402 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
403{
404 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
405 struct alc_spec *spec = codec->spec;
cd896c33 406 const struct hda_input_mux *imux;
1da177e4 407 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 408 unsigned int mux_idx;
e1406348
TI
409 hda_nid_t nid = spec->capsrc_nids ?
410 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 411 unsigned int type;
1da177e4 412
cd896c33
TI
413 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
414 imux = &spec->input_mux[mux_idx];
415
0169b6b3
TI
416 type = (get_wcaps(codec, nid) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
417 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
418 /* Matrix-mixer style (e.g. ALC882) */
419 unsigned int *cur_val = &spec->cur_mux[adc_idx];
420 unsigned int i, idx;
421
422 idx = ucontrol->value.enumerated.item[0];
423 if (idx >= imux->num_items)
424 idx = imux->num_items - 1;
425 if (*cur_val == idx)
426 return 0;
427 for (i = 0; i < imux->num_items; i++) {
428 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
429 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
430 imux->items[i].index,
431 HDA_AMP_MUTE, v);
432 }
433 *cur_val = idx;
434 return 1;
435 } else {
436 /* MUX style (e.g. ALC880) */
cd896c33 437 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
438 &spec->cur_mux[adc_idx]);
439 }
440}
e9edcee0 441
1da177e4
LT
442/*
443 * channel mode setting
444 */
9c7f852e
TI
445static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
446 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
447{
448 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
449 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
450 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
451 spec->num_channel_mode);
1da177e4
LT
452}
453
9c7f852e
TI
454static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
455 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
456{
457 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
458 struct alc_spec *spec = codec->spec;
d2a6d7dc 459 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 460 spec->num_channel_mode,
3b315d70 461 spec->ext_channel_count);
1da177e4
LT
462}
463
9c7f852e
TI
464static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
465 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
466{
467 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
468 struct alc_spec *spec = codec->spec;
4e195a7b
TI
469 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
470 spec->num_channel_mode,
3b315d70
HM
471 &spec->ext_channel_count);
472 if (err >= 0 && !spec->const_channel_count) {
473 spec->multiout.max_channels = spec->ext_channel_count;
474 if (spec->need_dac_fix)
475 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
476 }
4e195a7b 477 return err;
1da177e4
LT
478}
479
a9430dd8 480/*
4c5186ed 481 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 482 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
483 * being part of a format specifier. Maximum allowed length of a value is
484 * 63 characters plus NULL terminator.
7cf51e48
JW
485 *
486 * Note: some retasking pin complexes seem to ignore requests for input
487 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
488 * are requested. Therefore order this list so that this behaviour will not
489 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
490 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
491 * March 2006.
4c5186ed
JW
492 */
493static char *alc_pin_mode_names[] = {
7cf51e48
JW
494 "Mic 50pc bias", "Mic 80pc bias",
495 "Line in", "Line out", "Headphone out",
4c5186ed
JW
496};
497static unsigned char alc_pin_mode_values[] = {
7cf51e48 498 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
499};
500/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
501 * in the pin being assumed to be exclusively an input or an output pin. In
502 * addition, "input" pins may or may not process the mic bias option
503 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
504 * accept requests for bias as of chip versions up to March 2006) and/or
505 * wiring in the computer.
a9430dd8 506 */
a1e8d2da
JW
507#define ALC_PIN_DIR_IN 0x00
508#define ALC_PIN_DIR_OUT 0x01
509#define ALC_PIN_DIR_INOUT 0x02
510#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
511#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 512
ea1fb29a 513/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
514 * For each direction the minimum and maximum values are given.
515 */
a1e8d2da 516static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
517 { 0, 2 }, /* ALC_PIN_DIR_IN */
518 { 3, 4 }, /* ALC_PIN_DIR_OUT */
519 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
520 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
521 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
522};
523#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
524#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
525#define alc_pin_mode_n_items(_dir) \
526 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
527
9c7f852e
TI
528static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
529 struct snd_ctl_elem_info *uinfo)
a9430dd8 530{
4c5186ed
JW
531 unsigned int item_num = uinfo->value.enumerated.item;
532 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
533
534 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 535 uinfo->count = 1;
4c5186ed
JW
536 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
537
538 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
539 item_num = alc_pin_mode_min(dir);
540 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
541 return 0;
542}
543
9c7f852e
TI
544static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
545 struct snd_ctl_elem_value *ucontrol)
a9430dd8 546{
4c5186ed 547 unsigned int i;
a9430dd8
JW
548 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
549 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 550 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 551 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
552 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
553 AC_VERB_GET_PIN_WIDGET_CONTROL,
554 0x00);
a9430dd8 555
4c5186ed
JW
556 /* Find enumerated value for current pinctl setting */
557 i = alc_pin_mode_min(dir);
9c7f852e 558 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
4c5186ed 559 i++;
9c7f852e 560 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
561 return 0;
562}
563
9c7f852e
TI
564static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
565 struct snd_ctl_elem_value *ucontrol)
a9430dd8 566{
4c5186ed 567 signed int change;
a9430dd8
JW
568 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
569 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
570 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
571 long val = *ucontrol->value.integer.value;
9c7f852e
TI
572 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
573 AC_VERB_GET_PIN_WIDGET_CONTROL,
574 0x00);
a9430dd8 575
f12ab1e0 576 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
577 val = alc_pin_mode_min(dir);
578
579 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
580 if (change) {
581 /* Set pin mode to that requested */
82beb8fd
TI
582 snd_hda_codec_write_cache(codec, nid, 0,
583 AC_VERB_SET_PIN_WIDGET_CONTROL,
584 alc_pin_mode_values[val]);
cdcd9268 585
ea1fb29a 586 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
587 * for the requested pin mode. Enum values of 2 or less are
588 * input modes.
589 *
590 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
591 * reduces noise slightly (particularly on input) so we'll
592 * do it. However, having both input and output buffers
593 * enabled simultaneously doesn't seem to be problematic if
594 * this turns out to be necessary in the future.
cdcd9268
JW
595 */
596 if (val <= 2) {
47fd830a
TI
597 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
598 HDA_AMP_MUTE, HDA_AMP_MUTE);
599 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
600 HDA_AMP_MUTE, 0);
cdcd9268 601 } else {
47fd830a
TI
602 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
603 HDA_AMP_MUTE, HDA_AMP_MUTE);
604 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
605 HDA_AMP_MUTE, 0);
cdcd9268
JW
606 }
607 }
a9430dd8
JW
608 return change;
609}
610
4c5186ed 611#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 612 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
4c5186ed
JW
613 .info = alc_pin_mode_info, \
614 .get = alc_pin_mode_get, \
615 .put = alc_pin_mode_put, \
616 .private_value = nid | (dir<<16) }
df694daa 617
5c8f858d
JW
618/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
619 * together using a mask with more than one bit set. This control is
620 * currently used only by the ALC260 test model. At this stage they are not
621 * needed for any "production" models.
622 */
623#ifdef CONFIG_SND_DEBUG
a5ce8890 624#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 625
9c7f852e
TI
626static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
627 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
628{
629 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
630 hda_nid_t nid = kcontrol->private_value & 0xffff;
631 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
632 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
633 unsigned int val = snd_hda_codec_read(codec, nid, 0,
634 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
635
636 *valp = (val & mask) != 0;
637 return 0;
638}
9c7f852e
TI
639static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
640 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
641{
642 signed int change;
643 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
644 hda_nid_t nid = kcontrol->private_value & 0xffff;
645 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
646 long val = *ucontrol->value.integer.value;
9c7f852e
TI
647 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
648 AC_VERB_GET_GPIO_DATA,
649 0x00);
5c8f858d
JW
650
651 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
652 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
653 if (val == 0)
5c8f858d
JW
654 gpio_data &= ~mask;
655 else
656 gpio_data |= mask;
82beb8fd
TI
657 snd_hda_codec_write_cache(codec, nid, 0,
658 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
659
660 return change;
661}
662#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
663 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
664 .info = alc_gpio_data_info, \
665 .get = alc_gpio_data_get, \
666 .put = alc_gpio_data_put, \
667 .private_value = nid | (mask<<16) }
668#endif /* CONFIG_SND_DEBUG */
669
92621f13
JW
670/* A switch control to allow the enabling of the digital IO pins on the
671 * ALC260. This is incredibly simplistic; the intention of this control is
672 * to provide something in the test model allowing digital outputs to be
673 * identified if present. If models are found which can utilise these
674 * outputs a more complete mixer control can be devised for those models if
675 * necessary.
676 */
677#ifdef CONFIG_SND_DEBUG
a5ce8890 678#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 679
9c7f852e
TI
680static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
681 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
682{
683 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
684 hda_nid_t nid = kcontrol->private_value & 0xffff;
685 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
686 long *valp = ucontrol->value.integer.value;
9c7f852e 687 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 688 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
689
690 *valp = (val & mask) != 0;
691 return 0;
692}
9c7f852e
TI
693static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
694 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
695{
696 signed int change;
697 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
698 hda_nid_t nid = kcontrol->private_value & 0xffff;
699 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
700 long val = *ucontrol->value.integer.value;
9c7f852e 701 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 702 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 703 0x00);
92621f13
JW
704
705 /* Set/unset the masked control bit(s) as needed */
9c7f852e 706 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
707 if (val==0)
708 ctrl_data &= ~mask;
709 else
710 ctrl_data |= mask;
82beb8fd
TI
711 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
712 ctrl_data);
92621f13
JW
713
714 return change;
715}
716#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
717 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
718 .info = alc_spdif_ctrl_info, \
719 .get = alc_spdif_ctrl_get, \
720 .put = alc_spdif_ctrl_put, \
721 .private_value = nid | (mask<<16) }
722#endif /* CONFIG_SND_DEBUG */
723
f8225f6d
JW
724/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
725 * Again, this is only used in the ALC26x test models to help identify when
726 * the EAPD line must be asserted for features to work.
727 */
728#ifdef CONFIG_SND_DEBUG
729#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
730
731static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
732 struct snd_ctl_elem_value *ucontrol)
733{
734 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
735 hda_nid_t nid = kcontrol->private_value & 0xffff;
736 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
737 long *valp = ucontrol->value.integer.value;
738 unsigned int val = snd_hda_codec_read(codec, nid, 0,
739 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
740
741 *valp = (val & mask) != 0;
742 return 0;
743}
744
745static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
746 struct snd_ctl_elem_value *ucontrol)
747{
748 int change;
749 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
750 hda_nid_t nid = kcontrol->private_value & 0xffff;
751 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
752 long val = *ucontrol->value.integer.value;
753 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
754 AC_VERB_GET_EAPD_BTLENABLE,
755 0x00);
756
757 /* Set/unset the masked control bit(s) as needed */
758 change = (!val ? 0 : mask) != (ctrl_data & mask);
759 if (!val)
760 ctrl_data &= ~mask;
761 else
762 ctrl_data |= mask;
763 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
764 ctrl_data);
765
766 return change;
767}
768
769#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
770 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
771 .info = alc_eapd_ctrl_info, \
772 .get = alc_eapd_ctrl_get, \
773 .put = alc_eapd_ctrl_put, \
774 .private_value = nid | (mask<<16) }
775#endif /* CONFIG_SND_DEBUG */
776
23f0c048
TI
777/*
778 * set up the input pin config (depending on the given auto-pin type)
779 */
780static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
781 int auto_pin_type)
782{
783 unsigned int val = PIN_IN;
784
785 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
786 unsigned int pincap;
1327a32b 787 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048
TI
788 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
789 if (pincap & AC_PINCAP_VREF_80)
790 val = PIN_VREF80;
461c6c3a
TI
791 else if (pincap & AC_PINCAP_VREF_50)
792 val = PIN_VREF50;
793 else if (pincap & AC_PINCAP_VREF_100)
794 val = PIN_VREF100;
795 else if (pincap & AC_PINCAP_VREF_GRD)
796 val = PIN_VREFGRD;
23f0c048
TI
797 }
798 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
799}
800
d88897ea
TI
801/*
802 */
803static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
804{
805 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
806 return;
807 spec->mixers[spec->num_mixers++] = mix;
808}
809
810static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
811{
812 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
813 return;
814 spec->init_verbs[spec->num_init_verbs++] = verb;
815}
816
daead538
TI
817#ifdef CONFIG_PROC_FS
818/*
819 * hook for proc
820 */
821static void print_realtek_coef(struct snd_info_buffer *buffer,
822 struct hda_codec *codec, hda_nid_t nid)
823{
824 int coeff;
825
826 if (nid != 0x20)
827 return;
828 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
829 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
830 coeff = snd_hda_codec_read(codec, nid, 0,
831 AC_VERB_GET_COEF_INDEX, 0);
832 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
833}
834#else
835#define print_realtek_coef NULL
836#endif
837
df694daa
KY
838/*
839 * set up from the preset table
840 */
9c7f852e
TI
841static void setup_preset(struct alc_spec *spec,
842 const struct alc_config_preset *preset)
df694daa
KY
843{
844 int i;
845
846 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 847 add_mixer(spec, preset->mixers[i]);
f9e336f6 848 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
849 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
850 i++)
d88897ea 851 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 852
df694daa
KY
853 spec->channel_mode = preset->channel_mode;
854 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 855 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 856 spec->const_channel_count = preset->const_channel_count;
df694daa 857
3b315d70
HM
858 if (preset->const_channel_count)
859 spec->multiout.max_channels = preset->const_channel_count;
860 else
861 spec->multiout.max_channels = spec->channel_mode[0].channels;
862 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
863
864 spec->multiout.num_dacs = preset->num_dacs;
865 spec->multiout.dac_nids = preset->dac_nids;
866 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 867 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 868 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 869
a1e8d2da 870 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 871 if (!spec->num_mux_defs)
a1e8d2da 872 spec->num_mux_defs = 1;
df694daa
KY
873 spec->input_mux = preset->input_mux;
874
875 spec->num_adc_nids = preset->num_adc_nids;
876 spec->adc_nids = preset->adc_nids;
e1406348 877 spec->capsrc_nids = preset->capsrc_nids;
df694daa 878 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
879
880 spec->unsol_event = preset->unsol_event;
881 spec->init_hook = preset->init_hook;
cb53c626
TI
882#ifdef CONFIG_SND_HDA_POWER_SAVE
883 spec->loopback.amplist = preset->loopbacks;
884#endif
df694daa
KY
885}
886
bc9f98a9
KY
887/* Enable GPIO mask and set output */
888static struct hda_verb alc_gpio1_init_verbs[] = {
889 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
890 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
891 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
892 { }
893};
894
895static struct hda_verb alc_gpio2_init_verbs[] = {
896 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
897 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
898 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
899 { }
900};
901
bdd148a3
KY
902static struct hda_verb alc_gpio3_init_verbs[] = {
903 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
904 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
905 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
906 { }
907};
908
2c3bf9ab
TI
909/*
910 * Fix hardware PLL issue
911 * On some codecs, the analog PLL gating control must be off while
912 * the default value is 1.
913 */
914static void alc_fix_pll(struct hda_codec *codec)
915{
916 struct alc_spec *spec = codec->spec;
917 unsigned int val;
918
919 if (!spec->pll_nid)
920 return;
921 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
922 spec->pll_coef_idx);
923 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
924 AC_VERB_GET_PROC_COEF, 0);
925 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
926 spec->pll_coef_idx);
927 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
928 val & ~(1 << spec->pll_coef_bit));
929}
930
931static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
932 unsigned int coef_idx, unsigned int coef_bit)
933{
934 struct alc_spec *spec = codec->spec;
935 spec->pll_nid = nid;
936 spec->pll_coef_idx = coef_idx;
937 spec->pll_coef_bit = coef_bit;
938 alc_fix_pll(codec);
939}
940
a9fd4f3f 941static void alc_automute_pin(struct hda_codec *codec)
c9b58006
KY
942{
943 struct alc_spec *spec = codec->spec;
261c2407 944 unsigned int present, pincap;
a9fd4f3f
TI
945 unsigned int nid = spec->autocfg.hp_pins[0];
946 int i;
c9b58006 947
261c2407
TI
948 pincap = snd_hda_query_pin_caps(codec, nid);
949 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
950 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
a9fd4f3f 951 present = snd_hda_codec_read(codec, nid, 0,
c9b58006 952 AC_VERB_GET_PIN_SENSE, 0);
a9fd4f3f
TI
953 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
954 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
955 nid = spec->autocfg.speaker_pins[i];
956 if (!nid)
957 break;
958 snd_hda_codec_write(codec, nid, 0,
959 AC_VERB_SET_PIN_WIDGET_CONTROL,
960 spec->jack_present ? 0 : PIN_OUT);
961 }
c9b58006
KY
962}
963
def319f9 964#if 0 /* it's broken in some cases -- temporarily disabled */
7fb0d78f
KY
965static void alc_mic_automute(struct hda_codec *codec)
966{
967 struct alc_spec *spec = codec->spec;
968 unsigned int present;
969 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
970 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
971 unsigned int mix_nid = spec->capsrc_nids[0];
972 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
973
974 capsrc_idx_mic = mic_nid - 0x18;
975 capsrc_idx_fmic = fmic_nid - 0x18;
976 present = snd_hda_codec_read(codec, mic_nid, 0,
977 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
978 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
979 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
980 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
981 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
982 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
983 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
984}
4605b718 985#else
45bdd1c1 986#define alc_mic_automute(codec) do {} while(0) /* NOP */
4605b718 987#endif /* disabled */
7fb0d78f 988
c9b58006
KY
989/* unsolicited event for HP jack sensing */
990static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
991{
992 if (codec->vendor_id == 0x10ec0880)
993 res >>= 28;
994 else
995 res >>= 26;
a9fd4f3f
TI
996 switch (res) {
997 case ALC880_HP_EVENT:
998 alc_automute_pin(codec);
999 break;
1000 case ALC880_MIC_EVENT:
7fb0d78f 1001 alc_mic_automute(codec);
a9fd4f3f
TI
1002 break;
1003 }
7fb0d78f
KY
1004}
1005
1006static void alc_inithook(struct hda_codec *codec)
1007{
a9fd4f3f 1008 alc_automute_pin(codec);
7fb0d78f 1009 alc_mic_automute(codec);
c9b58006
KY
1010}
1011
f9423e7a
KY
1012/* additional initialization for ALC888 variants */
1013static void alc888_coef_init(struct hda_codec *codec)
1014{
1015 unsigned int tmp;
1016
1017 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1018 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1019 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1020 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1021 /* alc888S-VC */
1022 snd_hda_codec_read(codec, 0x20, 0,
1023 AC_VERB_SET_PROC_COEF, 0x830);
1024 else
1025 /* alc888-VB */
1026 snd_hda_codec_read(codec, 0x20, 0,
1027 AC_VERB_SET_PROC_COEF, 0x3030);
1028}
1029
4a79ba34 1030static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1031{
4a79ba34 1032 unsigned int tmp;
bc9f98a9 1033
4a79ba34
TI
1034 switch (type) {
1035 case ALC_INIT_GPIO1:
bc9f98a9
KY
1036 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1037 break;
4a79ba34 1038 case ALC_INIT_GPIO2:
bc9f98a9
KY
1039 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1040 break;
4a79ba34 1041 case ALC_INIT_GPIO3:
bdd148a3
KY
1042 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1043 break;
4a79ba34 1044 case ALC_INIT_DEFAULT:
bdd148a3 1045 switch (codec->vendor_id) {
c9b58006
KY
1046 case 0x10ec0260:
1047 snd_hda_codec_write(codec, 0x0f, 0,
1048 AC_VERB_SET_EAPD_BTLENABLE, 2);
1049 snd_hda_codec_write(codec, 0x10, 0,
1050 AC_VERB_SET_EAPD_BTLENABLE, 2);
1051 break;
1052 case 0x10ec0262:
bdd148a3
KY
1053 case 0x10ec0267:
1054 case 0x10ec0268:
c9b58006 1055 case 0x10ec0269:
c6e8f2da 1056 case 0x10ec0272:
f9423e7a
KY
1057 case 0x10ec0660:
1058 case 0x10ec0662:
1059 case 0x10ec0663:
c9b58006 1060 case 0x10ec0862:
20a3a05d 1061 case 0x10ec0889:
bdd148a3
KY
1062 snd_hda_codec_write(codec, 0x14, 0,
1063 AC_VERB_SET_EAPD_BTLENABLE, 2);
1064 snd_hda_codec_write(codec, 0x15, 0,
1065 AC_VERB_SET_EAPD_BTLENABLE, 2);
c9b58006 1066 break;
bdd148a3 1067 }
c9b58006
KY
1068 switch (codec->vendor_id) {
1069 case 0x10ec0260:
1070 snd_hda_codec_write(codec, 0x1a, 0,
1071 AC_VERB_SET_COEF_INDEX, 7);
1072 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1073 AC_VERB_GET_PROC_COEF, 0);
1074 snd_hda_codec_write(codec, 0x1a, 0,
1075 AC_VERB_SET_COEF_INDEX, 7);
1076 snd_hda_codec_write(codec, 0x1a, 0,
1077 AC_VERB_SET_PROC_COEF,
1078 tmp | 0x2010);
1079 break;
1080 case 0x10ec0262:
1081 case 0x10ec0880:
1082 case 0x10ec0882:
1083 case 0x10ec0883:
1084 case 0x10ec0885:
4a5a4c56 1085 case 0x10ec0887:
20a3a05d 1086 case 0x10ec0889:
c9b58006
KY
1087 snd_hda_codec_write(codec, 0x20, 0,
1088 AC_VERB_SET_COEF_INDEX, 7);
1089 tmp = snd_hda_codec_read(codec, 0x20, 0,
1090 AC_VERB_GET_PROC_COEF, 0);
1091 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1092 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1093 snd_hda_codec_write(codec, 0x20, 0,
1094 AC_VERB_SET_PROC_COEF,
1095 tmp | 0x2010);
1096 break;
f9423e7a 1097 case 0x10ec0888:
4a79ba34 1098 alc888_coef_init(codec);
f9423e7a 1099 break;
c9b58006
KY
1100 case 0x10ec0267:
1101 case 0x10ec0268:
1102 snd_hda_codec_write(codec, 0x20, 0,
1103 AC_VERB_SET_COEF_INDEX, 7);
1104 tmp = snd_hda_codec_read(codec, 0x20, 0,
1105 AC_VERB_GET_PROC_COEF, 0);
1106 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1107 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1108 snd_hda_codec_write(codec, 0x20, 0,
1109 AC_VERB_SET_PROC_COEF,
1110 tmp | 0x3000);
1111 break;
bc9f98a9 1112 }
4a79ba34
TI
1113 break;
1114 }
1115}
1116
1117static void alc_init_auto_hp(struct hda_codec *codec)
1118{
1119 struct alc_spec *spec = codec->spec;
1120
1121 if (!spec->autocfg.hp_pins[0])
1122 return;
1123
1124 if (!spec->autocfg.speaker_pins[0]) {
2a2ed0df
TI
1125 if (spec->autocfg.line_out_pins[0] &&
1126 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
4a79ba34
TI
1127 spec->autocfg.speaker_pins[0] =
1128 spec->autocfg.line_out_pins[0];
1129 else
1130 return;
1131 }
1132
2a2ed0df
TI
1133 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1134 spec->autocfg.hp_pins[0]);
4a79ba34
TI
1135 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1136 AC_VERB_SET_UNSOLICITED_ENABLE,
1137 AC_USRSP_EN | ALC880_HP_EVENT);
1138 spec->unsol_event = alc_sku_unsol_event;
1139}
1140
1141/* check subsystem ID and set up device-specific initialization;
1142 * return 1 if initialized, 0 if invalid SSID
1143 */
1144/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1145 * 31 ~ 16 : Manufacture ID
1146 * 15 ~ 8 : SKU ID
1147 * 7 ~ 0 : Assembly ID
1148 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1149 */
1150static int alc_subsystem_id(struct hda_codec *codec,
1151 hda_nid_t porta, hda_nid_t porte,
1152 hda_nid_t portd)
1153{
1154 unsigned int ass, tmp, i;
1155 unsigned nid;
1156 struct alc_spec *spec = codec->spec;
1157
1158 ass = codec->subsystem_id & 0xffff;
1159 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1160 goto do_sku;
1161
1162 /* invalid SSID, check the special NID pin defcfg instead */
1163 /*
def319f9 1164 * 31~30 : port connectivity
4a79ba34
TI
1165 * 29~21 : reserve
1166 * 20 : PCBEEP input
1167 * 19~16 : Check sum (15:1)
1168 * 15~1 : Custom
1169 * 0 : override
1170 */
1171 nid = 0x1d;
1172 if (codec->vendor_id == 0x10ec0260)
1173 nid = 0x17;
1174 ass = snd_hda_codec_get_pincfg(codec, nid);
1175 snd_printd("realtek: No valid SSID, "
1176 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1177 ass, nid);
4a79ba34
TI
1178 if (!(ass & 1) && !(ass & 0x100000))
1179 return 0;
1180 if ((ass >> 30) != 1) /* no physical connection */
1181 return 0;
1182
1183 /* check sum */
1184 tmp = 0;
1185 for (i = 1; i < 16; i++) {
1186 if ((ass >> i) & 1)
1187 tmp++;
1188 }
1189 if (((ass >> 16) & 0xf) != tmp)
1190 return 0;
1191do_sku:
1192 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1193 ass & 0xffff, codec->vendor_id);
1194 /*
1195 * 0 : override
1196 * 1 : Swap Jack
1197 * 2 : 0 --> Desktop, 1 --> Laptop
1198 * 3~5 : External Amplifier control
1199 * 7~6 : Reserved
1200 */
1201 tmp = (ass & 0x38) >> 3; /* external Amp control */
1202 switch (tmp) {
1203 case 1:
1204 spec->init_amp = ALC_INIT_GPIO1;
1205 break;
1206 case 3:
1207 spec->init_amp = ALC_INIT_GPIO2;
1208 break;
1209 case 7:
1210 spec->init_amp = ALC_INIT_GPIO3;
1211 break;
1212 case 5:
1213 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1214 break;
1215 }
ea1fb29a 1216
8c427226 1217 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1218 * when the external headphone out jack is plugged"
1219 */
8c427226 1220 if (!(ass & 0x8000))
4a79ba34 1221 return 1;
c9b58006
KY
1222 /*
1223 * 10~8 : Jack location
1224 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1225 * 14~13: Resvered
1226 * 15 : 1 --> enable the function "Mute internal speaker
1227 * when the external headphone out jack is plugged"
1228 */
c9b58006
KY
1229 if (!spec->autocfg.hp_pins[0]) {
1230 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1231 if (tmp == 0)
1232 spec->autocfg.hp_pins[0] = porta;
1233 else if (tmp == 1)
1234 spec->autocfg.hp_pins[0] = porte;
1235 else if (tmp == 2)
1236 spec->autocfg.hp_pins[0] = portd;
1237 else
4a79ba34 1238 return 1;
c9b58006
KY
1239 }
1240
4a79ba34
TI
1241 alc_init_auto_hp(codec);
1242 return 1;
1243}
ea1fb29a 1244
4a79ba34
TI
1245static void alc_ssid_check(struct hda_codec *codec,
1246 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1247{
1248 if (!alc_subsystem_id(codec, porta, porte, portd)) {
1249 struct alc_spec *spec = codec->spec;
1250 snd_printd("realtek: "
1251 "Enable default setup for auto mode as fallback\n");
1252 spec->init_amp = ALC_INIT_DEFAULT;
1253 alc_init_auto_hp(codec);
1254 }
bc9f98a9
KY
1255}
1256
f95474ec
TI
1257/*
1258 * Fix-up pin default configurations
1259 */
1260
1261struct alc_pincfg {
1262 hda_nid_t nid;
1263 u32 val;
1264};
1265
1266static void alc_fix_pincfg(struct hda_codec *codec,
1267 const struct snd_pci_quirk *quirk,
1268 const struct alc_pincfg **pinfix)
1269{
1270 const struct alc_pincfg *cfg;
1271
1272 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1273 if (!quirk)
1274 return;
1275
1276 cfg = pinfix[quirk->value];
0e8a21b5
TI
1277 for (; cfg->nid; cfg++)
1278 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
f95474ec
TI
1279}
1280
ef8ef5fb
VP
1281/*
1282 * ALC888
1283 */
1284
1285/*
1286 * 2ch mode
1287 */
1288static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1289/* Mic-in jack as mic in */
1290 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1291 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1292/* Line-in jack as Line in */
1293 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1294 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1295/* Line-Out as Front */
1296 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1297 { } /* end */
1298};
1299
1300/*
1301 * 4ch mode
1302 */
1303static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1304/* Mic-in jack as mic in */
1305 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1306 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1307/* Line-in jack as Surround */
1308 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1309 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1310/* Line-Out as Front */
1311 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1312 { } /* end */
1313};
1314
1315/*
1316 * 6ch mode
1317 */
1318static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1319/* Mic-in jack as CLFE */
1320 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1321 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1322/* Line-in jack as Surround */
1323 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1324 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1325/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1326 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1327 { } /* end */
1328};
1329
1330/*
1331 * 8ch mode
1332 */
1333static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1334/* Mic-in jack as CLFE */
1335 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1336 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1337/* Line-in jack as Surround */
1338 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1339 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1340/* Line-Out as Side */
1341 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1342 { } /* end */
1343};
1344
1345static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1346 { 2, alc888_4ST_ch2_intel_init },
1347 { 4, alc888_4ST_ch4_intel_init },
1348 { 6, alc888_4ST_ch6_intel_init },
1349 { 8, alc888_4ST_ch8_intel_init },
1350};
1351
1352/*
1353 * ALC888 Fujitsu Siemens Amillo xa3530
1354 */
1355
1356static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1357/* Front Mic: set to PIN_IN (empty by default) */
1358 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1359/* Connect Internal HP to Front */
1360 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1361 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1362 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1363/* Connect Bass HP to Front */
1364 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1365 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1366 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1367/* Connect Line-Out side jack (SPDIF) to Side */
1368 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1369 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1370 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1371/* Connect Mic jack to CLFE */
1372 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1373 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1374 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1375/* Connect Line-in jack to Surround */
1376 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1377 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1378 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1379/* Connect HP out jack to Front */
1380 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1381 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1382 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1383/* Enable unsolicited event for HP jack and Line-out jack */
1384 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1385 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1386 {}
1387};
1388
a9fd4f3f 1389static void alc_automute_amp(struct hda_codec *codec)
ef8ef5fb 1390{
a9fd4f3f 1391 struct alc_spec *spec = codec->spec;
261c2407 1392 unsigned int val, mute, pincap;
a9fd4f3f
TI
1393 hda_nid_t nid;
1394 int i;
1395
1396 spec->jack_present = 0;
1397 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1398 nid = spec->autocfg.hp_pins[i];
1399 if (!nid)
1400 break;
261c2407
TI
1401 pincap = snd_hda_query_pin_caps(codec, nid);
1402 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
1403 snd_hda_codec_read(codec, nid, 0,
1404 AC_VERB_SET_PIN_SENSE, 0);
a9fd4f3f
TI
1405 val = snd_hda_codec_read(codec, nid, 0,
1406 AC_VERB_GET_PIN_SENSE, 0);
1407 if (val & AC_PINSENSE_PRESENCE) {
1408 spec->jack_present = 1;
1409 break;
1410 }
1411 }
1412
1413 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
ef8ef5fb 1414 /* Toggle internal speakers muting */
a9fd4f3f
TI
1415 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1416 nid = spec->autocfg.speaker_pins[i];
1417 if (!nid)
1418 break;
1419 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1420 HDA_AMP_MUTE, mute);
1421 }
ef8ef5fb
VP
1422}
1423
a9fd4f3f
TI
1424static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1425 unsigned int res)
ef8ef5fb 1426{
a9fd4f3f
TI
1427 if (codec->vendor_id == 0x10ec0880)
1428 res >>= 28;
1429 else
1430 res >>= 26;
1431 if (res == ALC880_HP_EVENT)
1432 alc_automute_amp(codec);
ef8ef5fb
VP
1433}
1434
a9fd4f3f
TI
1435static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec)
1436{
1437 struct alc_spec *spec = codec->spec;
1438
1439 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1440 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1441 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1442 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1443 alc_automute_amp(codec);
1444}
ef8ef5fb 1445
5b2d1eca
VP
1446/*
1447 * ALC888 Acer Aspire 4930G model
1448 */
1449
1450static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1451/* Front Mic: set to PIN_IN (empty by default) */
1452 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1453/* Unselect Front Mic by default in input mixer 3 */
1454 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 1455/* Enable unsolicited event for HP jack */
5b2d1eca
VP
1456 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1457/* Connect Internal HP to front */
1458 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1459 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1460 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1461/* Connect HP out to front */
1462 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1463 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1464 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1465 { }
1466};
1467
d2fd4b09
TV
1468/*
1469 * ALC888 Acer Aspire 6530G model
1470 */
1471
1472static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1473/* Bias voltage on for external mic port */
1474 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
1475/* Front Mic: set to PIN_IN (empty by default) */
1476 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1477/* Unselect Front Mic by default in input mixer 3 */
1478 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
1479/* Enable unsolicited event for HP jack */
1480 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1481/* Enable speaker output */
1482 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1483 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1484/* Enable headphone output */
1485 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1486 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1487 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1488 { }
1489};
1490
3b315d70 1491/*
018df418 1492 * ALC889 Acer Aspire 8930G model
3b315d70
HM
1493 */
1494
018df418 1495static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
1496/* Front Mic: set to PIN_IN (empty by default) */
1497 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1498/* Unselect Front Mic by default in input mixer 3 */
1499 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1500/* Enable unsolicited event for HP jack */
1501 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1502/* Connect Internal Front to Front */
1503 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1504 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1505 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1506/* Connect Internal Rear to Rear */
1507 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1508 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1509 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1510/* Connect Internal CLFE to CLFE */
1511 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1512 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1513 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1514/* Connect HP out to Front */
018df418 1515 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
1516 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1517 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1518/* Enable all DACs */
1519/* DAC DISABLE/MUTE 1? */
1520/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1521 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1522 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1523/* DAC DISABLE/MUTE 2? */
1524/* some bit here disables the other DACs. Init=0x4900 */
1525 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1526 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1527/* Enable amplifiers */
1528 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1529 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
018df418
HM
1530/* DMIC fix
1531 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1532 * which makes the stereo useless. However, either the mic or the ALC889
1533 * makes the signal become a difference/sum signal instead of standard
1534 * stereo, which is annoying. So instead we flip this bit which makes the
1535 * codec replicate the sum signal to both channels, turning it into a
1536 * normal mono mic.
1537 */
1538/* DMIC_CONTROL? Init value = 0x0001 */
1539 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1540 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
1541 { }
1542};
1543
ef8ef5fb 1544static struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
1545 /* Front mic only available on one ADC */
1546 {
1547 .num_items = 4,
1548 .items = {
1549 { "Mic", 0x0 },
1550 { "Line", 0x2 },
1551 { "CD", 0x4 },
1552 { "Front Mic", 0xb },
1553 },
1554 },
1555 {
1556 .num_items = 3,
1557 .items = {
1558 { "Mic", 0x0 },
1559 { "Line", 0x2 },
1560 { "CD", 0x4 },
1561 },
1562 }
1563};
1564
d2fd4b09
TV
1565static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1566 /* Interal mic only available on one ADC */
1567 {
684a8842 1568 .num_items = 5,
d2fd4b09
TV
1569 .items = {
1570 { "Ext Mic", 0x0 },
684a8842 1571 { "Line In", 0x2 },
d2fd4b09 1572 { "CD", 0x4 },
684a8842 1573 { "Input Mix", 0xa },
d2fd4b09
TV
1574 { "Int Mic", 0xb },
1575 },
1576 },
1577 {
684a8842 1578 .num_items = 4,
d2fd4b09
TV
1579 .items = {
1580 { "Ext Mic", 0x0 },
684a8842 1581 { "Line In", 0x2 },
d2fd4b09 1582 { "CD", 0x4 },
684a8842 1583 { "Input Mix", 0xa },
d2fd4b09
TV
1584 },
1585 }
1586};
1587
018df418
HM
1588static struct hda_input_mux alc889_capture_sources[3] = {
1589 /* Digital mic only available on first "ADC" */
1590 {
1591 .num_items = 5,
1592 .items = {
1593 { "Mic", 0x0 },
1594 { "Line", 0x2 },
1595 { "CD", 0x4 },
1596 { "Front Mic", 0xb },
1597 { "Input Mix", 0xa },
1598 },
1599 },
1600 {
1601 .num_items = 4,
1602 .items = {
1603 { "Mic", 0x0 },
1604 { "Line", 0x2 },
1605 { "CD", 0x4 },
1606 { "Input Mix", 0xa },
1607 },
1608 },
1609 {
1610 .num_items = 4,
1611 .items = {
1612 { "Mic", 0x0 },
1613 { "Line", 0x2 },
1614 { "CD", 0x4 },
1615 { "Input Mix", 0xa },
1616 },
1617 }
1618};
1619
ef8ef5fb 1620static struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
1621 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1622 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1623 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1624 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1625 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1626 HDA_OUTPUT),
1627 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1628 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1629 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1630 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1631 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1632 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1633 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1634 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1635 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1636 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1637 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1638 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
1639 { } /* end */
1640};
1641
a9fd4f3f 1642static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec)
5b2d1eca 1643{
a9fd4f3f 1644 struct alc_spec *spec = codec->spec;
5b2d1eca 1645
a9fd4f3f
TI
1646 spec->autocfg.hp_pins[0] = 0x15;
1647 spec->autocfg.speaker_pins[0] = 0x14;
1648 alc_automute_amp(codec);
5b2d1eca
VP
1649}
1650
320d5920
EL
1651static void alc888_acer_aspire_6530g_init_hook(struct hda_codec *codec)
1652{
1653 struct alc_spec *spec = codec->spec;
1654
1655 spec->autocfg.hp_pins[0] = 0x15;
1656 spec->autocfg.speaker_pins[0] = 0x14;
1657 spec->autocfg.speaker_pins[1] = 0x16;
1658 spec->autocfg.speaker_pins[2] = 0x17;
1659 alc_automute_amp(codec);
1660}
1661
018df418 1662static void alc889_acer_aspire_8930g_init_hook(struct hda_codec *codec)
3b315d70
HM
1663{
1664 struct alc_spec *spec = codec->spec;
1665
1666 spec->autocfg.hp_pins[0] = 0x15;
1667 spec->autocfg.speaker_pins[0] = 0x14;
1668 spec->autocfg.speaker_pins[1] = 0x16;
1669 spec->autocfg.speaker_pins[2] = 0x1b;
1670 alc_automute_amp(codec);
1671}
1672
1da177e4 1673/*
e9edcee0
TI
1674 * ALC880 3-stack model
1675 *
1676 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
1677 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1678 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
1679 */
1680
e9edcee0
TI
1681static hda_nid_t alc880_dac_nids[4] = {
1682 /* front, rear, clfe, rear_surr */
1683 0x02, 0x05, 0x04, 0x03
1684};
1685
1686static hda_nid_t alc880_adc_nids[3] = {
1687 /* ADC0-2 */
1688 0x07, 0x08, 0x09,
1689};
1690
1691/* The datasheet says the node 0x07 is connected from inputs,
1692 * but it shows zero connection in the real implementation on some devices.
df694daa 1693 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 1694 */
e9edcee0
TI
1695static hda_nid_t alc880_adc_nids_alt[2] = {
1696 /* ADC1-2 */
1697 0x08, 0x09,
1698};
1699
1700#define ALC880_DIGOUT_NID 0x06
1701#define ALC880_DIGIN_NID 0x0a
1702
1703static struct hda_input_mux alc880_capture_source = {
1704 .num_items = 4,
1705 .items = {
1706 { "Mic", 0x0 },
1707 { "Front Mic", 0x3 },
1708 { "Line", 0x2 },
1709 { "CD", 0x4 },
1710 },
1711};
1712
1713/* channel source setting (2/6 channel selection for 3-stack) */
1714/* 2ch mode */
1715static struct hda_verb alc880_threestack_ch2_init[] = {
1716 /* set line-in to input, mute it */
1717 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1718 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1719 /* set mic-in to input vref 80%, mute it */
1720 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1721 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1722 { } /* end */
1723};
1724
1725/* 6ch mode */
1726static struct hda_verb alc880_threestack_ch6_init[] = {
1727 /* set line-in to output, unmute it */
1728 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1729 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1730 /* set mic-in to output, unmute it */
1731 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1732 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1733 { } /* end */
1734};
1735
d2a6d7dc 1736static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
1737 { 2, alc880_threestack_ch2_init },
1738 { 6, alc880_threestack_ch6_init },
1739};
1740
c8b6bf9b 1741static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 1742 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1743 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 1744 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1745 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
1746 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1747 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1748 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1749 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
1750 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1751 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1752 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1753 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1754 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1755 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1756 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1757 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
1758 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1759 {
1760 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1761 .name = "Channel Mode",
df694daa
KY
1762 .info = alc_ch_mode_info,
1763 .get = alc_ch_mode_get,
1764 .put = alc_ch_mode_put,
e9edcee0
TI
1765 },
1766 { } /* end */
1767};
1768
1769/* capture mixer elements */
f9e336f6
TI
1770static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1771 struct snd_ctl_elem_info *uinfo)
1772{
1773 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1774 struct alc_spec *spec = codec->spec;
1775 int err;
1da177e4 1776
5a9e02e9 1777 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1778 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1779 HDA_INPUT);
1780 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 1781 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1782 return err;
1783}
1784
1785static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1786 unsigned int size, unsigned int __user *tlv)
1787{
1788 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1789 struct alc_spec *spec = codec->spec;
1790 int err;
1da177e4 1791
5a9e02e9 1792 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1793 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1794 HDA_INPUT);
1795 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 1796 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1797 return err;
1798}
1799
1800typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1801 struct snd_ctl_elem_value *ucontrol);
1802
1803static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1804 struct snd_ctl_elem_value *ucontrol,
1805 getput_call_t func)
1806{
1807 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1808 struct alc_spec *spec = codec->spec;
1809 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1810 int err;
1811
5a9e02e9 1812 mutex_lock(&codec->control_mutex);
f9e336f6
TI
1813 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1814 3, 0, HDA_INPUT);
1815 err = func(kcontrol, ucontrol);
5a9e02e9 1816 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
1817 return err;
1818}
1819
1820static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1821 struct snd_ctl_elem_value *ucontrol)
1822{
1823 return alc_cap_getput_caller(kcontrol, ucontrol,
1824 snd_hda_mixer_amp_volume_get);
1825}
1826
1827static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1828 struct snd_ctl_elem_value *ucontrol)
1829{
1830 return alc_cap_getput_caller(kcontrol, ucontrol,
1831 snd_hda_mixer_amp_volume_put);
1832}
1833
1834/* capture mixer elements */
1835#define alc_cap_sw_info snd_ctl_boolean_stereo_info
1836
1837static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1838 struct snd_ctl_elem_value *ucontrol)
1839{
1840 return alc_cap_getput_caller(kcontrol, ucontrol,
1841 snd_hda_mixer_amp_switch_get);
1842}
1843
1844static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1845 struct snd_ctl_elem_value *ucontrol)
1846{
1847 return alc_cap_getput_caller(kcontrol, ucontrol,
1848 snd_hda_mixer_amp_switch_put);
1849}
1850
a23b688f 1851#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
1852 { \
1853 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1854 .name = "Capture Switch", \
1855 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1856 .count = num, \
1857 .info = alc_cap_sw_info, \
1858 .get = alc_cap_sw_get, \
1859 .put = alc_cap_sw_put, \
1860 }, \
1861 { \
1862 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1863 .name = "Capture Volume", \
1864 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1865 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1866 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1867 .count = num, \
1868 .info = alc_cap_vol_info, \
1869 .get = alc_cap_vol_get, \
1870 .put = alc_cap_vol_put, \
1871 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
1872 }
1873
1874#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
1875 { \
1876 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1877 /* .name = "Capture Source", */ \
1878 .name = "Input Source", \
1879 .count = num, \
1880 .info = alc_mux_enum_info, \
1881 .get = alc_mux_enum_get, \
1882 .put = alc_mux_enum_put, \
a23b688f
TI
1883 }
1884
1885#define DEFINE_CAPMIX(num) \
1886static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1887 _DEFINE_CAPMIX(num), \
1888 _DEFINE_CAPSRC(num), \
1889 { } /* end */ \
1890}
1891
1892#define DEFINE_CAPMIX_NOSRC(num) \
1893static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
1894 _DEFINE_CAPMIX(num), \
1895 { } /* end */ \
f9e336f6
TI
1896}
1897
1898/* up to three ADCs */
1899DEFINE_CAPMIX(1);
1900DEFINE_CAPMIX(2);
1901DEFINE_CAPMIX(3);
a23b688f
TI
1902DEFINE_CAPMIX_NOSRC(1);
1903DEFINE_CAPMIX_NOSRC(2);
1904DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
1905
1906/*
1907 * ALC880 5-stack model
1908 *
9c7f852e
TI
1909 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1910 * Side = 0x02 (0xd)
e9edcee0
TI
1911 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1912 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1913 */
1914
1915/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 1916static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 1917 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1918 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
1919 { } /* end */
1920};
1921
e9edcee0
TI
1922/* channel source setting (6/8 channel selection for 5-stack) */
1923/* 6ch mode */
1924static struct hda_verb alc880_fivestack_ch6_init[] = {
1925 /* set line-in to input, mute it */
1926 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1927 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
1928 { } /* end */
1929};
1930
e9edcee0
TI
1931/* 8ch mode */
1932static struct hda_verb alc880_fivestack_ch8_init[] = {
1933 /* set line-in to output, unmute it */
1934 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1935 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1936 { } /* end */
1937};
1938
d2a6d7dc 1939static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
1940 { 6, alc880_fivestack_ch6_init },
1941 { 8, alc880_fivestack_ch8_init },
1942};
1943
1944
1945/*
1946 * ALC880 6-stack model
1947 *
9c7f852e
TI
1948 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1949 * Side = 0x05 (0x0f)
e9edcee0
TI
1950 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1951 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1952 */
1953
1954static hda_nid_t alc880_6st_dac_nids[4] = {
1955 /* front, rear, clfe, rear_surr */
1956 0x02, 0x03, 0x04, 0x05
f12ab1e0 1957};
e9edcee0
TI
1958
1959static struct hda_input_mux alc880_6stack_capture_source = {
1960 .num_items = 4,
1961 .items = {
1962 { "Mic", 0x0 },
1963 { "Front Mic", 0x1 },
1964 { "Line", 0x2 },
1965 { "CD", 0x4 },
1966 },
1967};
1968
1969/* fixed 8-channels */
d2a6d7dc 1970static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
1971 { 8, NULL },
1972};
1973
c8b6bf9b 1974static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 1975 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1976 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1977 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1978 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1979 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1980 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1981 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1982 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 1983 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1984 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
1985 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1986 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1987 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1988 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1989 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1990 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1991 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1992 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
1993 {
1994 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1995 .name = "Channel Mode",
df694daa
KY
1996 .info = alc_ch_mode_info,
1997 .get = alc_ch_mode_get,
1998 .put = alc_ch_mode_put,
16ded525
TI
1999 },
2000 { } /* end */
2001};
2002
e9edcee0
TI
2003
2004/*
2005 * ALC880 W810 model
2006 *
2007 * W810 has rear IO for:
2008 * Front (DAC 02)
2009 * Surround (DAC 03)
2010 * Center/LFE (DAC 04)
2011 * Digital out (06)
2012 *
2013 * The system also has a pair of internal speakers, and a headphone jack.
2014 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2015 *
e9edcee0
TI
2016 * There is a variable resistor to control the speaker or headphone
2017 * volume. This is a hardware-only device without a software API.
2018 *
2019 * Plugging headphones in will disable the internal speakers. This is
2020 * implemented in hardware, not via the driver using jack sense. In
2021 * a similar fashion, plugging into the rear socket marked "front" will
2022 * disable both the speakers and headphones.
2023 *
2024 * For input, there's a microphone jack, and an "audio in" jack.
2025 * These may not do anything useful with this driver yet, because I
2026 * haven't setup any initialization verbs for these yet...
2027 */
2028
2029static hda_nid_t alc880_w810_dac_nids[3] = {
2030 /* front, rear/surround, clfe */
2031 0x02, 0x03, 0x04
16ded525
TI
2032};
2033
e9edcee0 2034/* fixed 6 channels */
d2a6d7dc 2035static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2036 { 6, NULL }
2037};
2038
2039/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 2040static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2041 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2042 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2043 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2044 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2045 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2046 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2047 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2048 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2049 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2050 { } /* end */
2051};
2052
2053
2054/*
2055 * Z710V model
2056 *
2057 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2058 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2059 * Line = 0x1a
e9edcee0
TI
2060 */
2061
2062static hda_nid_t alc880_z71v_dac_nids[1] = {
2063 0x02
2064};
2065#define ALC880_Z71V_HP_DAC 0x03
2066
2067/* fixed 2 channels */
d2a6d7dc 2068static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2069 { 2, NULL }
2070};
2071
c8b6bf9b 2072static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2073 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2074 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2075 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2076 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2077 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2078 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2079 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2080 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2081 { } /* end */
2082};
2083
e9edcee0 2084
e9edcee0
TI
2085/*
2086 * ALC880 F1734 model
2087 *
2088 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2089 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2090 */
2091
2092static hda_nid_t alc880_f1734_dac_nids[1] = {
2093 0x03
2094};
2095#define ALC880_F1734_HP_DAC 0x02
2096
c8b6bf9b 2097static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2098 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2099 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2100 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2101 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2102 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2103 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2104 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2105 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2106 { } /* end */
2107};
2108
937b4160
TI
2109static struct hda_input_mux alc880_f1734_capture_source = {
2110 .num_items = 2,
2111 .items = {
2112 { "Mic", 0x1 },
2113 { "CD", 0x4 },
2114 },
2115};
2116
e9edcee0 2117
e9edcee0
TI
2118/*
2119 * ALC880 ASUS model
2120 *
2121 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2122 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2123 * Mic = 0x18, Line = 0x1a
2124 */
2125
2126#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2127#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2128
c8b6bf9b 2129static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2130 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2131 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2132 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2133 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2134 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2135 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2136 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2137 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
2138 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2139 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2140 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2141 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
2142 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2143 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2144 {
2145 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2146 .name = "Channel Mode",
df694daa
KY
2147 .info = alc_ch_mode_info,
2148 .get = alc_ch_mode_get,
2149 .put = alc_ch_mode_put,
16ded525
TI
2150 },
2151 { } /* end */
2152};
e9edcee0 2153
e9edcee0
TI
2154/*
2155 * ALC880 ASUS W1V model
2156 *
2157 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2158 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2159 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2160 */
2161
2162/* additional mixers to alc880_asus_mixer */
c8b6bf9b 2163static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
2164 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2165 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2166 { } /* end */
2167};
2168
df694daa
KY
2169/* TCL S700 */
2170static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2171 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2172 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2173 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2174 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2175 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2176 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2177 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2178 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2179 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
2180 { } /* end */
2181};
2182
ccc656ce
KY
2183/* Uniwill */
2184static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
2185 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2186 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2187 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2188 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2189 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2190 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2191 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2192 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2193 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2194 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2195 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2196 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2197 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2198 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2199 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2200 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
2201 {
2202 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2203 .name = "Channel Mode",
2204 .info = alc_ch_mode_info,
2205 .get = alc_ch_mode_get,
2206 .put = alc_ch_mode_put,
2207 },
2208 { } /* end */
2209};
2210
2cf9f0fc
TD
2211static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2212 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2213 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2214 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2215 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2216 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2217 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2218 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2219 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2220 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2221 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2222 { } /* end */
2223};
2224
ccc656ce 2225static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
2226 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2227 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2228 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2229 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
2230 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2231 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2232 { } /* end */
2233};
2234
2134ea4f
TI
2235/*
2236 * virtual master controls
2237 */
2238
2239/*
2240 * slave controls for virtual master
2241 */
2242static const char *alc_slave_vols[] = {
2243 "Front Playback Volume",
2244 "Surround Playback Volume",
2245 "Center Playback Volume",
2246 "LFE Playback Volume",
2247 "Side Playback Volume",
2248 "Headphone Playback Volume",
2249 "Speaker Playback Volume",
2250 "Mono Playback Volume",
2134ea4f 2251 "Line-Out Playback Volume",
26f5df26 2252 "PCM Playback Volume",
2134ea4f
TI
2253 NULL,
2254};
2255
2256static const char *alc_slave_sws[] = {
2257 "Front Playback Switch",
2258 "Surround Playback Switch",
2259 "Center Playback Switch",
2260 "LFE Playback Switch",
2261 "Side Playback Switch",
2262 "Headphone Playback Switch",
2263 "Speaker Playback Switch",
2264 "Mono Playback Switch",
edb54a55 2265 "IEC958 Playback Switch",
2134ea4f
TI
2266 NULL,
2267};
2268
1da177e4 2269/*
e9edcee0 2270 * build control elements
1da177e4 2271 */
603c4019
TI
2272
2273static void alc_free_kctls(struct hda_codec *codec);
2274
45bdd1c1
TI
2275/* additional beep mixers; the actual parameters are overwritten at build */
2276static struct snd_kcontrol_new alc_beep_mixer[] = {
2277 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2278 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
2279 { } /* end */
2280};
2281
1da177e4
LT
2282static int alc_build_controls(struct hda_codec *codec)
2283{
2284 struct alc_spec *spec = codec->spec;
2285 int err;
2286 int i;
2287
2288 for (i = 0; i < spec->num_mixers; i++) {
2289 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2290 if (err < 0)
2291 return err;
2292 }
f9e336f6
TI
2293 if (spec->cap_mixer) {
2294 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2295 if (err < 0)
2296 return err;
2297 }
1da177e4 2298 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
2299 err = snd_hda_create_spdif_out_ctls(codec,
2300 spec->multiout.dig_out_nid);
1da177e4
LT
2301 if (err < 0)
2302 return err;
e64f14f4
TI
2303 if (!spec->no_analog) {
2304 err = snd_hda_create_spdif_share_sw(codec,
2305 &spec->multiout);
2306 if (err < 0)
2307 return err;
2308 spec->multiout.share_spdif = 1;
2309 }
1da177e4
LT
2310 }
2311 if (spec->dig_in_nid) {
2312 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2313 if (err < 0)
2314 return err;
2315 }
2134ea4f 2316
45bdd1c1
TI
2317 /* create beep controls if needed */
2318 if (spec->beep_amp) {
2319 struct snd_kcontrol_new *knew;
2320 for (knew = alc_beep_mixer; knew->name; knew++) {
2321 struct snd_kcontrol *kctl;
2322 kctl = snd_ctl_new1(knew, codec);
2323 if (!kctl)
2324 return -ENOMEM;
2325 kctl->private_value = spec->beep_amp;
2326 err = snd_hda_ctl_add(codec, kctl);
2327 if (err < 0)
2328 return err;
2329 }
2330 }
2331
2134ea4f 2332 /* if we have no master control, let's create it */
e64f14f4
TI
2333 if (!spec->no_analog &&
2334 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 2335 unsigned int vmaster_tlv[4];
2134ea4f 2336 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 2337 HDA_OUTPUT, vmaster_tlv);
2134ea4f 2338 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 2339 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
2340 if (err < 0)
2341 return err;
2342 }
e64f14f4
TI
2343 if (!spec->no_analog &&
2344 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
2345 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2346 NULL, alc_slave_sws);
2347 if (err < 0)
2348 return err;
2349 }
2350
603c4019 2351 alc_free_kctls(codec); /* no longer needed */
1da177e4
LT
2352 return 0;
2353}
2354
e9edcee0 2355
1da177e4
LT
2356/*
2357 * initialize the codec volumes, etc
2358 */
2359
e9edcee0
TI
2360/*
2361 * generic initialization of ADC, input mixers and output mixers
2362 */
2363static struct hda_verb alc880_volume_init_verbs[] = {
2364 /*
2365 * Unmute ADC0-2 and set the default input to mic-in
2366 */
71fe7b82 2367 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2368 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2369 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2370 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 2371 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 2372 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 2373
e9edcee0
TI
2374 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2375 * mixer widget
9c7f852e
TI
2376 * Note: PASD motherboards uses the Line In 2 as the input for front
2377 * panel mic (mic 2)
1da177e4 2378 */
e9edcee0 2379 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
2380 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2381 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2382 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2383 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2384 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2385 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2386 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 2387
e9edcee0
TI
2388 /*
2389 * Set up output mixers (0x0c - 0x0f)
1da177e4 2390 */
e9edcee0
TI
2391 /* set vol=0 to output mixers */
2392 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2393 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2394 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2395 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2396 /* set up input amps for analog loopback */
2397 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
2398 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2399 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2400 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2401 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2402 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2403 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
2404 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2405 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
2406
2407 { }
2408};
2409
e9edcee0
TI
2410/*
2411 * 3-stack pin configuration:
2412 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2413 */
2414static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2415 /*
2416 * preset connection lists of input pins
2417 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2418 */
2419 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2420 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2421 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2422
2423 /*
2424 * Set pin mode and muting
2425 */
2426 /* set front pin widgets 0x14 for output */
05acb863 2427 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2428 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2429 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2430 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2431 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2432 /* Mic2 (as headphone out) for HP output */
2433 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2434 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2435 /* Line In pin widget for input */
05acb863 2436 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
2437 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2438 /* Line2 (as front mic) pin widget for input and vref at 80% */
2439 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2440 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2441 /* CD pin widget for input */
05acb863 2442 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 2443
e9edcee0
TI
2444 { }
2445};
1da177e4 2446
e9edcee0
TI
2447/*
2448 * 5-stack pin configuration:
2449 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2450 * line-in/side = 0x1a, f-mic = 0x1b
2451 */
2452static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2453 /*
2454 * preset connection lists of input pins
2455 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 2456 */
e9edcee0
TI
2457 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2458 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 2459
e9edcee0
TI
2460 /*
2461 * Set pin mode and muting
1da177e4 2462 */
e9edcee0
TI
2463 /* set pin widgets 0x14-0x17 for output */
2464 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2465 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2466 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2467 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2468 /* unmute pins for output (no gain on this amp) */
2469 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2470 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2471 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2472 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2473
2474 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2475 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2476 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2477 /* Mic2 (as headphone out) for HP output */
2478 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2479 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2480 /* Line In pin widget for input */
2481 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2482 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2483 /* Line2 (as front mic) pin widget for input and vref at 80% */
2484 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2485 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2486 /* CD pin widget for input */
2487 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
2488
2489 { }
2490};
2491
e9edcee0
TI
2492/*
2493 * W810 pin configuration:
2494 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2495 */
2496static struct hda_verb alc880_pin_w810_init_verbs[] = {
2497 /* hphone/speaker input selector: front DAC */
2498 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 2499
05acb863 2500 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2501 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2502 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2503 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2504 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2505 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 2506
e9edcee0 2507 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 2508 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 2509
1da177e4
LT
2510 { }
2511};
2512
e9edcee0
TI
2513/*
2514 * Z71V pin configuration:
2515 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2516 */
2517static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 2518 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2519 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 2520 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2521 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 2522
16ded525 2523 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2524 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 2525 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2526 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
2527
2528 { }
2529};
2530
e9edcee0
TI
2531/*
2532 * 6-stack pin configuration:
9c7f852e
TI
2533 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2534 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
2535 */
2536static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2537 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2538
16ded525 2539 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2540 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2541 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2542 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2543 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2544 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2545 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2546 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2547
16ded525 2548 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2549 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2550 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 2551 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2552 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 2553 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2554 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2555 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2556 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 2557
e9edcee0
TI
2558 { }
2559};
2560
ccc656ce
KY
2561/*
2562 * Uniwill pin configuration:
2563 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2564 * line = 0x1a
2565 */
2566static struct hda_verb alc880_uniwill_init_verbs[] = {
2567 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2568
2569 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2570 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2571 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2572 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2573 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2574 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2575 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2576 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2577 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2578 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2579 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2580 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2581 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2582 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2583
2584 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2585 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2586 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2587 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2588 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2589 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2590 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2591 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2592 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2593
2594 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2595 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2596
2597 { }
2598};
2599
2600/*
2601* Uniwill P53
ea1fb29a 2602* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
2603 */
2604static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2605 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2606
2607 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2608 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2609 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2610 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2611 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2612 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2614 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2615 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2616 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2617 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2618 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2619
2620 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2621 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2622 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2623 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2624 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2625 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2626
2627 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2628 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2629
2630 { }
2631};
2632
2cf9f0fc
TD
2633static struct hda_verb alc880_beep_init_verbs[] = {
2634 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2635 { }
2636};
2637
458a4fab
TI
2638/* auto-toggle front mic */
2639static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2640{
2641 unsigned int present;
2642 unsigned char bits;
ccc656ce
KY
2643
2644 present = snd_hda_codec_read(codec, 0x18, 0,
2645 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2646 bits = present ? HDA_AMP_MUTE : 0;
2647 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
2648}
2649
a9fd4f3f 2650static void alc880_uniwill_init_hook(struct hda_codec *codec)
458a4fab 2651{
a9fd4f3f
TI
2652 struct alc_spec *spec = codec->spec;
2653
2654 spec->autocfg.hp_pins[0] = 0x14;
2655 spec->autocfg.speaker_pins[0] = 0x15;
2656 spec->autocfg.speaker_pins[0] = 0x16;
2657 alc_automute_amp(codec);
458a4fab 2658 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
2659}
2660
2661static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2662 unsigned int res)
2663{
2664 /* Looks like the unsol event is incompatible with the standard
2665 * definition. 4bit tag is placed at 28 bit!
2666 */
458a4fab 2667 switch (res >> 28) {
458a4fab
TI
2668 case ALC880_MIC_EVENT:
2669 alc880_uniwill_mic_automute(codec);
2670 break;
a9fd4f3f
TI
2671 default:
2672 alc_automute_amp_unsol_event(codec, res);
2673 break;
458a4fab 2674 }
ccc656ce
KY
2675}
2676
a9fd4f3f 2677static void alc880_uniwill_p53_init_hook(struct hda_codec *codec)
ccc656ce 2678{
a9fd4f3f 2679 struct alc_spec *spec = codec->spec;
ccc656ce 2680
a9fd4f3f
TI
2681 spec->autocfg.hp_pins[0] = 0x14;
2682 spec->autocfg.speaker_pins[0] = 0x15;
2683 alc_automute_amp(codec);
ccc656ce
KY
2684}
2685
2686static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2687{
2688 unsigned int present;
ea1fb29a 2689
ccc656ce 2690 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
2691 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2692 present &= HDA_AMP_VOLMASK;
2693 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2694 HDA_AMP_VOLMASK, present);
2695 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2696 HDA_AMP_VOLMASK, present);
ccc656ce 2697}
47fd830a 2698
ccc656ce
KY
2699static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2700 unsigned int res)
2701{
2702 /* Looks like the unsol event is incompatible with the standard
2703 * definition. 4bit tag is placed at 28 bit!
2704 */
f12ab1e0 2705 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 2706 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f
TI
2707 else
2708 alc_automute_amp_unsol_event(codec, res);
ccc656ce
KY
2709}
2710
e9edcee0
TI
2711/*
2712 * F1734 pin configuration:
2713 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2714 */
2715static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 2716 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
2717 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2718 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2719 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2720 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2721
e9edcee0 2722 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 2723 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 2724 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 2725 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2726
e9edcee0
TI
2727 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2728 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 2729 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 2730 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2731 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2732 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2733 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2734 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2735 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 2736
937b4160
TI
2737 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2738 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2739
dfc0ff62
TI
2740 { }
2741};
2742
e9edcee0
TI
2743/*
2744 * ASUS pin configuration:
2745 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2746 */
2747static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
2748 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2749 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2750 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2751 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2752
2753 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2754 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2755 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2756 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2757 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2758 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2759 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2760 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2761
2762 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2763 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2764 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2765 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2766 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2767 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2768 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2769 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2770 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 2771
e9edcee0
TI
2772 { }
2773};
16ded525 2774
e9edcee0 2775/* Enable GPIO mask and set output */
bc9f98a9
KY
2776#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2777#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 2778#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
2779
2780/* Clevo m520g init */
2781static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2782 /* headphone output */
2783 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2784 /* line-out */
2785 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2786 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2787 /* Line-in */
2788 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2789 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2790 /* CD */
2791 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2792 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2793 /* Mic1 (rear panel) */
2794 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2795 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2796 /* Mic2 (front panel) */
2797 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2798 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2799 /* headphone */
2800 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2801 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2802 /* change to EAPD mode */
2803 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2804 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2805
2806 { }
16ded525
TI
2807};
2808
df694daa 2809static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
2810 /* change to EAPD mode */
2811 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2812 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2813
df694daa
KY
2814 /* Headphone output */
2815 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2816 /* Front output*/
2817 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2818 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2819
2820 /* Line In pin widget for input */
2821 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2822 /* CD pin widget for input */
2823 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2824 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2825 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2826
2827 /* change to EAPD mode */
2828 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2829 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2830
2831 { }
2832};
16ded525 2833
e9edcee0 2834/*
ae6b813a
TI
2835 * LG m1 express dual
2836 *
2837 * Pin assignment:
2838 * Rear Line-In/Out (blue): 0x14
2839 * Build-in Mic-In: 0x15
2840 * Speaker-out: 0x17
2841 * HP-Out (green): 0x1b
2842 * Mic-In/Out (red): 0x19
2843 * SPDIF-Out: 0x1e
2844 */
2845
2846/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2847static hda_nid_t alc880_lg_dac_nids[3] = {
2848 0x05, 0x02, 0x03
2849};
2850
2851/* seems analog CD is not working */
2852static struct hda_input_mux alc880_lg_capture_source = {
2853 .num_items = 3,
2854 .items = {
2855 { "Mic", 0x1 },
2856 { "Line", 0x5 },
2857 { "Internal Mic", 0x6 },
2858 },
2859};
2860
2861/* 2,4,6 channel modes */
2862static struct hda_verb alc880_lg_ch2_init[] = {
2863 /* set line-in and mic-in to input */
2864 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2865 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2866 { }
2867};
2868
2869static struct hda_verb alc880_lg_ch4_init[] = {
2870 /* set line-in to out and mic-in to input */
2871 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2872 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2873 { }
2874};
2875
2876static struct hda_verb alc880_lg_ch6_init[] = {
2877 /* set line-in and mic-in to output */
2878 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2879 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2880 { }
2881};
2882
2883static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2884 { 2, alc880_lg_ch2_init },
2885 { 4, alc880_lg_ch4_init },
2886 { 6, alc880_lg_ch6_init },
2887};
2888
2889static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
2890 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2891 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
2892 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2893 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2894 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2895 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2896 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2897 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2900 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2901 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2902 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2903 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2904 {
2905 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2906 .name = "Channel Mode",
2907 .info = alc_ch_mode_info,
2908 .get = alc_ch_mode_get,
2909 .put = alc_ch_mode_put,
2910 },
2911 { } /* end */
2912};
2913
2914static struct hda_verb alc880_lg_init_verbs[] = {
2915 /* set capture source to mic-in */
2916 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2917 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2918 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2919 /* mute all amp mixer inputs */
2920 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
2921 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2922 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
2923 /* line-in to input */
2924 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2925 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2926 /* built-in mic */
2927 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2928 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2929 /* speaker-out */
2930 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2931 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2932 /* mic-in to input */
2933 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2934 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2935 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2936 /* HP-out */
2937 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2938 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2939 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2940 /* jack sense */
a9fd4f3f 2941 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
2942 { }
2943};
2944
2945/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 2946static void alc880_lg_init_hook(struct hda_codec *codec)
ae6b813a 2947{
a9fd4f3f 2948 struct alc_spec *spec = codec->spec;
ae6b813a 2949
a9fd4f3f
TI
2950 spec->autocfg.hp_pins[0] = 0x1b;
2951 spec->autocfg.speaker_pins[0] = 0x17;
2952 alc_automute_amp(codec);
ae6b813a
TI
2953}
2954
d681518a
TI
2955/*
2956 * LG LW20
2957 *
2958 * Pin assignment:
2959 * Speaker-out: 0x14
2960 * Mic-In: 0x18
e4f41da9
CM
2961 * Built-in Mic-In: 0x19
2962 * Line-In: 0x1b
2963 * HP-Out: 0x1a
d681518a
TI
2964 * SPDIF-Out: 0x1e
2965 */
2966
d681518a 2967static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 2968 .num_items = 3,
d681518a
TI
2969 .items = {
2970 { "Mic", 0x0 },
2971 { "Internal Mic", 0x1 },
e4f41da9 2972 { "Line In", 0x2 },
d681518a
TI
2973 },
2974};
2975
0a8c5da3
CM
2976#define alc880_lg_lw_modes alc880_threestack_modes
2977
d681518a 2978static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
2979 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2980 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2981 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2982 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2983 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2984 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2985 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2986 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2987 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2988 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
2989 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2990 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2991 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2992 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
2993 {
2994 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2995 .name = "Channel Mode",
2996 .info = alc_ch_mode_info,
2997 .get = alc_ch_mode_get,
2998 .put = alc_ch_mode_put,
2999 },
d681518a
TI
3000 { } /* end */
3001};
3002
3003static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3004 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3005 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3006 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3007
d681518a
TI
3008 /* set capture source to mic-in */
3009 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3010 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3011 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3012 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3013 /* speaker-out */
3014 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3015 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3016 /* HP-out */
d681518a
TI
3017 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3018 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3019 /* mic-in to input */
3020 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3021 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3022 /* built-in mic */
3023 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3024 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3025 /* jack sense */
a9fd4f3f 3026 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3027 { }
3028};
3029
3030/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 3031static void alc880_lg_lw_init_hook(struct hda_codec *codec)
d681518a 3032{
a9fd4f3f 3033 struct alc_spec *spec = codec->spec;
d681518a 3034
a9fd4f3f
TI
3035 spec->autocfg.hp_pins[0] = 0x1b;
3036 spec->autocfg.speaker_pins[0] = 0x14;
3037 alc_automute_amp(codec);
d681518a
TI
3038}
3039
df99cd33
TI
3040static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3041 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3042 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3043 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3044 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3045 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3046 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3047 { } /* end */
3048};
3049
3050static struct hda_input_mux alc880_medion_rim_capture_source = {
3051 .num_items = 2,
3052 .items = {
3053 { "Mic", 0x0 },
3054 { "Internal Mic", 0x1 },
3055 },
3056};
3057
3058static struct hda_verb alc880_medion_rim_init_verbs[] = {
3059 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3060
3061 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3062 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3063
3064 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3065 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3066 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3067 /* Mic2 (as headphone out) for HP output */
3068 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3069 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3070 /* Internal Speaker */
3071 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3072 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3073
3074 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3075 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3076
3077 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3078 { }
3079};
3080
3081/* toggle speaker-output according to the hp-jack state */
3082static void alc880_medion_rim_automute(struct hda_codec *codec)
3083{
a9fd4f3f
TI
3084 struct alc_spec *spec = codec->spec;
3085 alc_automute_amp(codec);
3086 /* toggle EAPD */
3087 if (spec->jack_present)
df99cd33
TI
3088 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3089 else
3090 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3091}
3092
3093static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3094 unsigned int res)
3095{
3096 /* Looks like the unsol event is incompatible with the standard
3097 * definition. 4bit tag is placed at 28 bit!
3098 */
3099 if ((res >> 28) == ALC880_HP_EVENT)
3100 alc880_medion_rim_automute(codec);
3101}
3102
a9fd4f3f
TI
3103static void alc880_medion_rim_init_hook(struct hda_codec *codec)
3104{
3105 struct alc_spec *spec = codec->spec;
3106
3107 spec->autocfg.hp_pins[0] = 0x14;
3108 spec->autocfg.speaker_pins[0] = 0x1b;
3109 alc880_medion_rim_automute(codec);
3110}
3111
cb53c626
TI
3112#ifdef CONFIG_SND_HDA_POWER_SAVE
3113static struct hda_amp_list alc880_loopbacks[] = {
3114 { 0x0b, HDA_INPUT, 0 },
3115 { 0x0b, HDA_INPUT, 1 },
3116 { 0x0b, HDA_INPUT, 2 },
3117 { 0x0b, HDA_INPUT, 3 },
3118 { 0x0b, HDA_INPUT, 4 },
3119 { } /* end */
3120};
3121
3122static struct hda_amp_list alc880_lg_loopbacks[] = {
3123 { 0x0b, HDA_INPUT, 1 },
3124 { 0x0b, HDA_INPUT, 6 },
3125 { 0x0b, HDA_INPUT, 7 },
3126 { } /* end */
3127};
3128#endif
3129
ae6b813a
TI
3130/*
3131 * Common callbacks
e9edcee0
TI
3132 */
3133
1da177e4
LT
3134static int alc_init(struct hda_codec *codec)
3135{
3136 struct alc_spec *spec = codec->spec;
e9edcee0
TI
3137 unsigned int i;
3138
2c3bf9ab 3139 alc_fix_pll(codec);
4a79ba34 3140 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 3141
e9edcee0
TI
3142 for (i = 0; i < spec->num_init_verbs; i++)
3143 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
3144
3145 if (spec->init_hook)
3146 spec->init_hook(codec);
3147
1da177e4
LT
3148 return 0;
3149}
3150
ae6b813a
TI
3151static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3152{
3153 struct alc_spec *spec = codec->spec;
3154
3155 if (spec->unsol_event)
3156 spec->unsol_event(codec, res);
3157}
3158
cb53c626
TI
3159#ifdef CONFIG_SND_HDA_POWER_SAVE
3160static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3161{
3162 struct alc_spec *spec = codec->spec;
3163 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3164}
3165#endif
3166
1da177e4
LT
3167/*
3168 * Analog playback callbacks
3169 */
3170static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3171 struct hda_codec *codec,
c8b6bf9b 3172 struct snd_pcm_substream *substream)
1da177e4
LT
3173{
3174 struct alc_spec *spec = codec->spec;
9a08160b
TI
3175 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3176 hinfo);
1da177e4
LT
3177}
3178
3179static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3180 struct hda_codec *codec,
3181 unsigned int stream_tag,
3182 unsigned int format,
c8b6bf9b 3183 struct snd_pcm_substream *substream)
1da177e4
LT
3184{
3185 struct alc_spec *spec = codec->spec;
9c7f852e
TI
3186 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3187 stream_tag, format, substream);
1da177e4
LT
3188}
3189
3190static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3191 struct hda_codec *codec,
c8b6bf9b 3192 struct snd_pcm_substream *substream)
1da177e4
LT
3193{
3194 struct alc_spec *spec = codec->spec;
3195 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3196}
3197
3198/*
3199 * Digital out
3200 */
3201static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3202 struct hda_codec *codec,
c8b6bf9b 3203 struct snd_pcm_substream *substream)
1da177e4
LT
3204{
3205 struct alc_spec *spec = codec->spec;
3206 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3207}
3208
6b97eb45
TI
3209static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3210 struct hda_codec *codec,
3211 unsigned int stream_tag,
3212 unsigned int format,
3213 struct snd_pcm_substream *substream)
3214{
3215 struct alc_spec *spec = codec->spec;
3216 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3217 stream_tag, format, substream);
3218}
3219
9b5f12e5
TI
3220static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3221 struct hda_codec *codec,
3222 struct snd_pcm_substream *substream)
3223{
3224 struct alc_spec *spec = codec->spec;
3225 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3226}
3227
1da177e4
LT
3228static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3229 struct hda_codec *codec,
c8b6bf9b 3230 struct snd_pcm_substream *substream)
1da177e4
LT
3231{
3232 struct alc_spec *spec = codec->spec;
3233 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3234}
3235
3236/*
3237 * Analog capture
3238 */
6330079f 3239static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
3240 struct hda_codec *codec,
3241 unsigned int stream_tag,
3242 unsigned int format,
c8b6bf9b 3243 struct snd_pcm_substream *substream)
1da177e4
LT
3244{
3245 struct alc_spec *spec = codec->spec;
3246
6330079f 3247 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
3248 stream_tag, 0, format);
3249 return 0;
3250}
3251
6330079f 3252static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 3253 struct hda_codec *codec,
c8b6bf9b 3254 struct snd_pcm_substream *substream)
1da177e4
LT
3255{
3256 struct alc_spec *spec = codec->spec;
3257
888afa15
TI
3258 snd_hda_codec_cleanup_stream(codec,
3259 spec->adc_nids[substream->number + 1]);
1da177e4
LT
3260 return 0;
3261}
3262
3263
3264/*
3265 */
3266static struct hda_pcm_stream alc880_pcm_analog_playback = {
3267 .substreams = 1,
3268 .channels_min = 2,
3269 .channels_max = 8,
e9edcee0 3270 /* NID is set in alc_build_pcms */
1da177e4
LT
3271 .ops = {
3272 .open = alc880_playback_pcm_open,
3273 .prepare = alc880_playback_pcm_prepare,
3274 .cleanup = alc880_playback_pcm_cleanup
3275 },
3276};
3277
3278static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
3279 .substreams = 1,
3280 .channels_min = 2,
3281 .channels_max = 2,
3282 /* NID is set in alc_build_pcms */
3283};
3284
3285static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3286 .substreams = 1,
3287 .channels_min = 2,
3288 .channels_max = 2,
3289 /* NID is set in alc_build_pcms */
3290};
3291
3292static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3293 .substreams = 2, /* can be overridden */
1da177e4
LT
3294 .channels_min = 2,
3295 .channels_max = 2,
e9edcee0 3296 /* NID is set in alc_build_pcms */
1da177e4 3297 .ops = {
6330079f
TI
3298 .prepare = alc880_alt_capture_pcm_prepare,
3299 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
3300 },
3301};
3302
3303static struct hda_pcm_stream alc880_pcm_digital_playback = {
3304 .substreams = 1,
3305 .channels_min = 2,
3306 .channels_max = 2,
3307 /* NID is set in alc_build_pcms */
3308 .ops = {
3309 .open = alc880_dig_playback_pcm_open,
6b97eb45 3310 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
3311 .prepare = alc880_dig_playback_pcm_prepare,
3312 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
3313 },
3314};
3315
3316static struct hda_pcm_stream alc880_pcm_digital_capture = {
3317 .substreams = 1,
3318 .channels_min = 2,
3319 .channels_max = 2,
3320 /* NID is set in alc_build_pcms */
3321};
3322
4c5186ed 3323/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 3324static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
3325 .substreams = 0,
3326 .channels_min = 0,
3327 .channels_max = 0,
3328};
3329
1da177e4
LT
3330static int alc_build_pcms(struct hda_codec *codec)
3331{
3332 struct alc_spec *spec = codec->spec;
3333 struct hda_pcm *info = spec->pcm_rec;
3334 int i;
3335
3336 codec->num_pcms = 1;
3337 codec->pcm_info = info;
3338
e64f14f4
TI
3339 if (spec->no_analog)
3340 goto skip_analog;
3341
812a2cca
TI
3342 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3343 "%s Analog", codec->chip_name);
1da177e4 3344 info->name = spec->stream_name_analog;
812a2cca 3345
4a471b7d 3346 if (spec->stream_analog_playback) {
da3cec35
TI
3347 if (snd_BUG_ON(!spec->multiout.dac_nids))
3348 return -EINVAL;
4a471b7d
TI
3349 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3350 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3351 }
3352 if (spec->stream_analog_capture) {
da3cec35
TI
3353 if (snd_BUG_ON(!spec->adc_nids))
3354 return -EINVAL;
4a471b7d
TI
3355 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3356 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3357 }
3358
3359 if (spec->channel_mode) {
3360 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3361 for (i = 0; i < spec->num_channel_mode; i++) {
3362 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3363 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3364 }
1da177e4
LT
3365 }
3366 }
3367
e64f14f4 3368 skip_analog:
e08a007d 3369 /* SPDIF for stream index #1 */
1da177e4 3370 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
3371 snprintf(spec->stream_name_digital,
3372 sizeof(spec->stream_name_digital),
3373 "%s Digital", codec->chip_name);
e08a007d 3374 codec->num_pcms = 2;
b25c9da1 3375 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 3376 info = spec->pcm_rec + 1;
1da177e4 3377 info->name = spec->stream_name_digital;
8c441982
TI
3378 if (spec->dig_out_type)
3379 info->pcm_type = spec->dig_out_type;
3380 else
3381 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
3382 if (spec->multiout.dig_out_nid &&
3383 spec->stream_digital_playback) {
1da177e4
LT
3384 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3385 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3386 }
4a471b7d
TI
3387 if (spec->dig_in_nid &&
3388 spec->stream_digital_capture) {
1da177e4
LT
3389 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3390 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3391 }
963f803f
TI
3392 /* FIXME: do we need this for all Realtek codec models? */
3393 codec->spdif_status_reset = 1;
1da177e4
LT
3394 }
3395
e64f14f4
TI
3396 if (spec->no_analog)
3397 return 0;
3398
e08a007d
TI
3399 /* If the use of more than one ADC is requested for the current
3400 * model, configure a second analog capture-only PCM.
3401 */
3402 /* Additional Analaog capture for index #2 */
6330079f
TI
3403 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3404 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 3405 codec->num_pcms = 3;
c06134d7 3406 info = spec->pcm_rec + 2;
e08a007d 3407 info->name = spec->stream_name_analog;
6330079f
TI
3408 if (spec->alt_dac_nid) {
3409 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3410 *spec->stream_analog_alt_playback;
3411 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3412 spec->alt_dac_nid;
3413 } else {
3414 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3415 alc_pcm_null_stream;
3416 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3417 }
3418 if (spec->num_adc_nids > 1) {
3419 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3420 *spec->stream_analog_alt_capture;
3421 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3422 spec->adc_nids[1];
3423 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3424 spec->num_adc_nids - 1;
3425 } else {
3426 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3427 alc_pcm_null_stream;
3428 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
3429 }
3430 }
3431
1da177e4
LT
3432 return 0;
3433}
3434
603c4019
TI
3435static void alc_free_kctls(struct hda_codec *codec)
3436{
3437 struct alc_spec *spec = codec->spec;
3438
3439 if (spec->kctls.list) {
3440 struct snd_kcontrol_new *kctl = spec->kctls.list;
3441 int i;
3442 for (i = 0; i < spec->kctls.used; i++)
3443 kfree(kctl[i].name);
3444 }
3445 snd_array_free(&spec->kctls);
3446}
3447
1da177e4
LT
3448static void alc_free(struct hda_codec *codec)
3449{
e9edcee0 3450 struct alc_spec *spec = codec->spec;
e9edcee0 3451
f12ab1e0 3452 if (!spec)
e9edcee0
TI
3453 return;
3454
603c4019 3455 alc_free_kctls(codec);
e9edcee0 3456 kfree(spec);
680cd536 3457 snd_hda_detach_beep_device(codec);
1da177e4
LT
3458}
3459
e044c39a 3460#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
3461static int alc_resume(struct hda_codec *codec)
3462{
e044c39a
TI
3463 codec->patch_ops.init(codec);
3464 snd_hda_codec_resume_amp(codec);
3465 snd_hda_codec_resume_cache(codec);
3466 return 0;
3467}
e044c39a
TI
3468#endif
3469
1da177e4
LT
3470/*
3471 */
3472static struct hda_codec_ops alc_patch_ops = {
3473 .build_controls = alc_build_controls,
3474 .build_pcms = alc_build_pcms,
3475 .init = alc_init,
3476 .free = alc_free,
ae6b813a 3477 .unsol_event = alc_unsol_event,
e044c39a
TI
3478#ifdef SND_HDA_NEEDS_RESUME
3479 .resume = alc_resume,
3480#endif
cb53c626
TI
3481#ifdef CONFIG_SND_HDA_POWER_SAVE
3482 .check_power_status = alc_check_power_status,
3483#endif
1da177e4
LT
3484};
3485
2fa522be
TI
3486
3487/*
3488 * Test configuration for debugging
3489 *
3490 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3491 * enum controls.
3492 */
3493#ifdef CONFIG_SND_DEBUG
3494static hda_nid_t alc880_test_dac_nids[4] = {
3495 0x02, 0x03, 0x04, 0x05
3496};
3497
3498static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 3499 .num_items = 7,
2fa522be
TI
3500 .items = {
3501 { "In-1", 0x0 },
3502 { "In-2", 0x1 },
3503 { "In-3", 0x2 },
3504 { "In-4", 0x3 },
3505 { "CD", 0x4 },
ae6b813a
TI
3506 { "Front", 0x5 },
3507 { "Surround", 0x6 },
2fa522be
TI
3508 },
3509};
3510
d2a6d7dc 3511static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 3512 { 2, NULL },
fd2c326d 3513 { 4, NULL },
2fa522be 3514 { 6, NULL },
fd2c326d 3515 { 8, NULL },
2fa522be
TI
3516};
3517
9c7f852e
TI
3518static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3519 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
3520{
3521 static char *texts[] = {
3522 "N/A", "Line Out", "HP Out",
3523 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3524 };
3525 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3526 uinfo->count = 1;
3527 uinfo->value.enumerated.items = 8;
3528 if (uinfo->value.enumerated.item >= 8)
3529 uinfo->value.enumerated.item = 7;
3530 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3531 return 0;
3532}
3533
9c7f852e
TI
3534static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3535 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3536{
3537 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3538 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3539 unsigned int pin_ctl, item = 0;
3540
3541 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3542 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3543 if (pin_ctl & AC_PINCTL_OUT_EN) {
3544 if (pin_ctl & AC_PINCTL_HP_EN)
3545 item = 2;
3546 else
3547 item = 1;
3548 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3549 switch (pin_ctl & AC_PINCTL_VREFEN) {
3550 case AC_PINCTL_VREF_HIZ: item = 3; break;
3551 case AC_PINCTL_VREF_50: item = 4; break;
3552 case AC_PINCTL_VREF_GRD: item = 5; break;
3553 case AC_PINCTL_VREF_80: item = 6; break;
3554 case AC_PINCTL_VREF_100: item = 7; break;
3555 }
3556 }
3557 ucontrol->value.enumerated.item[0] = item;
3558 return 0;
3559}
3560
9c7f852e
TI
3561static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3562 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3563{
3564 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3565 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3566 static unsigned int ctls[] = {
3567 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3568 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3569 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3570 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3571 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3572 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3573 };
3574 unsigned int old_ctl, new_ctl;
3575
3576 old_ctl = snd_hda_codec_read(codec, nid, 0,
3577 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3578 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3579 if (old_ctl != new_ctl) {
82beb8fd
TI
3580 int val;
3581 snd_hda_codec_write_cache(codec, nid, 0,
3582 AC_VERB_SET_PIN_WIDGET_CONTROL,
3583 new_ctl);
47fd830a
TI
3584 val = ucontrol->value.enumerated.item[0] >= 3 ?
3585 HDA_AMP_MUTE : 0;
3586 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3587 HDA_AMP_MUTE, val);
2fa522be
TI
3588 return 1;
3589 }
3590 return 0;
3591}
3592
9c7f852e
TI
3593static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3594 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
3595{
3596 static char *texts[] = {
3597 "Front", "Surround", "CLFE", "Side"
3598 };
3599 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3600 uinfo->count = 1;
3601 uinfo->value.enumerated.items = 4;
3602 if (uinfo->value.enumerated.item >= 4)
3603 uinfo->value.enumerated.item = 3;
3604 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3605 return 0;
3606}
3607
9c7f852e
TI
3608static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3609 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3610{
3611 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3612 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3613 unsigned int sel;
3614
3615 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3616 ucontrol->value.enumerated.item[0] = sel & 3;
3617 return 0;
3618}
3619
9c7f852e
TI
3620static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3621 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3622{
3623 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3624 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3625 unsigned int sel;
3626
3627 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3628 if (ucontrol->value.enumerated.item[0] != sel) {
3629 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
3630 snd_hda_codec_write_cache(codec, nid, 0,
3631 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
3632 return 1;
3633 }
3634 return 0;
3635}
3636
3637#define PIN_CTL_TEST(xname,nid) { \
3638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3639 .name = xname, \
3640 .info = alc_test_pin_ctl_info, \
3641 .get = alc_test_pin_ctl_get, \
3642 .put = alc_test_pin_ctl_put, \
3643 .private_value = nid \
3644 }
3645
3646#define PIN_SRC_TEST(xname,nid) { \
3647 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3648 .name = xname, \
3649 .info = alc_test_pin_src_info, \
3650 .get = alc_test_pin_src_get, \
3651 .put = alc_test_pin_src_put, \
3652 .private_value = nid \
3653 }
3654
c8b6bf9b 3655static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
3656 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3657 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3658 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3659 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
3660 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3661 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3662 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3663 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
3664 PIN_CTL_TEST("Front Pin Mode", 0x14),
3665 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3666 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3667 PIN_CTL_TEST("Side Pin Mode", 0x17),
3668 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3669 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3670 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3671 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3672 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3673 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3674 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3675 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3676 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3677 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3678 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3679 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3680 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3681 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3682 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3683 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3684 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3685 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
3686 {
3687 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3688 .name = "Channel Mode",
df694daa
KY
3689 .info = alc_ch_mode_info,
3690 .get = alc_ch_mode_get,
3691 .put = alc_ch_mode_put,
2fa522be
TI
3692 },
3693 { } /* end */
3694};
3695
3696static struct hda_verb alc880_test_init_verbs[] = {
3697 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
3698 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3699 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3700 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3701 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3702 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3703 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3704 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3705 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 3706 /* Vol output for 0x0c-0x0f */
05acb863
TI
3707 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3708 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3709 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3710 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 3711 /* Set output pins 0x14-0x17 */
05acb863
TI
3712 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3713 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3714 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3715 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 3716 /* Unmute output pins 0x14-0x17 */
05acb863
TI
3717 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3718 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3719 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3720 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 3721 /* Set input pins 0x18-0x1c */
16ded525
TI
3722 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3723 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
3724 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3725 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3726 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 3727 /* Mute input pins 0x18-0x1b */
05acb863
TI
3728 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3729 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3730 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3731 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 3732 /* ADC set up */
05acb863 3733 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3734 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 3735 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3736 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 3737 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3738 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
3739 /* Analog input/passthru */
3740 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3741 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3742 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3743 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3744 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
3745 { }
3746};
3747#endif
3748
1da177e4
LT
3749/*
3750 */
3751
f5fcc13c
TI
3752static const char *alc880_models[ALC880_MODEL_LAST] = {
3753 [ALC880_3ST] = "3stack",
3754 [ALC880_TCL_S700] = "tcl",
3755 [ALC880_3ST_DIG] = "3stack-digout",
3756 [ALC880_CLEVO] = "clevo",
3757 [ALC880_5ST] = "5stack",
3758 [ALC880_5ST_DIG] = "5stack-digout",
3759 [ALC880_W810] = "w810",
3760 [ALC880_Z71V] = "z71v",
3761 [ALC880_6ST] = "6stack",
3762 [ALC880_6ST_DIG] = "6stack-digout",
3763 [ALC880_ASUS] = "asus",
3764 [ALC880_ASUS_W1V] = "asus-w1v",
3765 [ALC880_ASUS_DIG] = "asus-dig",
3766 [ALC880_ASUS_DIG2] = "asus-dig2",
3767 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
3768 [ALC880_UNIWILL_P53] = "uniwill-p53",
3769 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
3770 [ALC880_F1734] = "F1734",
3771 [ALC880_LG] = "lg",
3772 [ALC880_LG_LW] = "lg-lw",
df99cd33 3773 [ALC880_MEDION_RIM] = "medion",
2fa522be 3774#ifdef CONFIG_SND_DEBUG
f5fcc13c 3775 [ALC880_TEST] = "test",
2fa522be 3776#endif
f5fcc13c
TI
3777 [ALC880_AUTO] = "auto",
3778};
3779
3780static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 3781 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
3782 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3783 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3784 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3785 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3786 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3787 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3788 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3789 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
3790 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3791 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
3792 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3793 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3794 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3795 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3796 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3797 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3798 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3799 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3800 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3801 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 3802 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
3803 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3804 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3805 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 3806 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 3807 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
3808 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3809 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
3810 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3811 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
3812 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3813 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3814 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3815 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
3816 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3817 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 3818 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 3819 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 3820 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 3821 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
3822 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3823 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 3824 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 3825 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 3826 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 3827 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 3828 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 3829 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
ac3e3741 3830 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2cf9f0fc 3831 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 3832 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
3833 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3834 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 3835 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
3836 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3837 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3838 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3839 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
3840 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3841 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 3842 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 3843 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
3844 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3845 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
3846 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3847 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3848 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
3849 /* default Intel */
3850 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
3851 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3852 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
3853 {}
3854};
3855
16ded525 3856/*
df694daa 3857 * ALC880 codec presets
16ded525 3858 */
16ded525
TI
3859static struct alc_config_preset alc880_presets[] = {
3860 [ALC880_3ST] = {
e9edcee0 3861 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
3862 .init_verbs = { alc880_volume_init_verbs,
3863 alc880_pin_3stack_init_verbs },
16ded525 3864 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 3865 .dac_nids = alc880_dac_nids,
16ded525
TI
3866 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3867 .channel_mode = alc880_threestack_modes,
4e195a7b 3868 .need_dac_fix = 1,
16ded525
TI
3869 .input_mux = &alc880_capture_source,
3870 },
3871 [ALC880_3ST_DIG] = {
e9edcee0 3872 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
3873 .init_verbs = { alc880_volume_init_verbs,
3874 alc880_pin_3stack_init_verbs },
16ded525 3875 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
3876 .dac_nids = alc880_dac_nids,
3877 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3878 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3879 .channel_mode = alc880_threestack_modes,
4e195a7b 3880 .need_dac_fix = 1,
16ded525
TI
3881 .input_mux = &alc880_capture_source,
3882 },
df694daa
KY
3883 [ALC880_TCL_S700] = {
3884 .mixers = { alc880_tcl_s700_mixer },
3885 .init_verbs = { alc880_volume_init_verbs,
3886 alc880_pin_tcl_S700_init_verbs,
3887 alc880_gpio2_init_verbs },
3888 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3889 .dac_nids = alc880_dac_nids,
f9e336f6
TI
3890 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3891 .num_adc_nids = 1, /* single ADC */
df694daa
KY
3892 .hp_nid = 0x03,
3893 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3894 .channel_mode = alc880_2_jack_modes,
3895 .input_mux = &alc880_capture_source,
3896 },
16ded525 3897 [ALC880_5ST] = {
f12ab1e0
TI
3898 .mixers = { alc880_three_stack_mixer,
3899 alc880_five_stack_mixer},
3900 .init_verbs = { alc880_volume_init_verbs,
3901 alc880_pin_5stack_init_verbs },
16ded525
TI
3902 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3903 .dac_nids = alc880_dac_nids,
16ded525
TI
3904 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3905 .channel_mode = alc880_fivestack_modes,
3906 .input_mux = &alc880_capture_source,
3907 },
3908 [ALC880_5ST_DIG] = {
f12ab1e0
TI
3909 .mixers = { alc880_three_stack_mixer,
3910 alc880_five_stack_mixer },
3911 .init_verbs = { alc880_volume_init_verbs,
3912 alc880_pin_5stack_init_verbs },
16ded525
TI
3913 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3914 .dac_nids = alc880_dac_nids,
3915 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3916 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3917 .channel_mode = alc880_fivestack_modes,
3918 .input_mux = &alc880_capture_source,
3919 },
b6482d48
TI
3920 [ALC880_6ST] = {
3921 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3922 .init_verbs = { alc880_volume_init_verbs,
3923 alc880_pin_6stack_init_verbs },
b6482d48
TI
3924 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3925 .dac_nids = alc880_6st_dac_nids,
3926 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3927 .channel_mode = alc880_sixstack_modes,
3928 .input_mux = &alc880_6stack_capture_source,
3929 },
16ded525 3930 [ALC880_6ST_DIG] = {
e9edcee0 3931 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3932 .init_verbs = { alc880_volume_init_verbs,
3933 alc880_pin_6stack_init_verbs },
16ded525
TI
3934 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3935 .dac_nids = alc880_6st_dac_nids,
3936 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3937 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3938 .channel_mode = alc880_sixstack_modes,
3939 .input_mux = &alc880_6stack_capture_source,
3940 },
3941 [ALC880_W810] = {
e9edcee0 3942 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
3943 .init_verbs = { alc880_volume_init_verbs,
3944 alc880_pin_w810_init_verbs,
b0af0de5 3945 alc880_gpio2_init_verbs },
16ded525
TI
3946 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3947 .dac_nids = alc880_w810_dac_nids,
3948 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3949 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3950 .channel_mode = alc880_w810_modes,
3951 .input_mux = &alc880_capture_source,
3952 },
3953 [ALC880_Z71V] = {
e9edcee0 3954 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
3955 .init_verbs = { alc880_volume_init_verbs,
3956 alc880_pin_z71v_init_verbs },
16ded525
TI
3957 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3958 .dac_nids = alc880_z71v_dac_nids,
3959 .dig_out_nid = ALC880_DIGOUT_NID,
3960 .hp_nid = 0x03,
e9edcee0
TI
3961 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3962 .channel_mode = alc880_2_jack_modes,
16ded525
TI
3963 .input_mux = &alc880_capture_source,
3964 },
3965 [ALC880_F1734] = {
e9edcee0 3966 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
3967 .init_verbs = { alc880_volume_init_verbs,
3968 alc880_pin_f1734_init_verbs },
e9edcee0
TI
3969 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3970 .dac_nids = alc880_f1734_dac_nids,
3971 .hp_nid = 0x02,
3972 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3973 .channel_mode = alc880_2_jack_modes,
937b4160
TI
3974 .input_mux = &alc880_f1734_capture_source,
3975 .unsol_event = alc880_uniwill_p53_unsol_event,
a9fd4f3f 3976 .init_hook = alc880_uniwill_p53_init_hook,
16ded525
TI
3977 },
3978 [ALC880_ASUS] = {
e9edcee0 3979 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3980 .init_verbs = { alc880_volume_init_verbs,
3981 alc880_pin_asus_init_verbs,
e9edcee0
TI
3982 alc880_gpio1_init_verbs },
3983 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3984 .dac_nids = alc880_asus_dac_nids,
3985 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3986 .channel_mode = alc880_asus_modes,
4e195a7b 3987 .need_dac_fix = 1,
16ded525
TI
3988 .input_mux = &alc880_capture_source,
3989 },
3990 [ALC880_ASUS_DIG] = {
e9edcee0 3991 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3992 .init_verbs = { alc880_volume_init_verbs,
3993 alc880_pin_asus_init_verbs,
e9edcee0
TI
3994 alc880_gpio1_init_verbs },
3995 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3996 .dac_nids = alc880_asus_dac_nids,
16ded525 3997 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3998 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3999 .channel_mode = alc880_asus_modes,
4e195a7b 4000 .need_dac_fix = 1,
16ded525
TI
4001 .input_mux = &alc880_capture_source,
4002 },
df694daa
KY
4003 [ALC880_ASUS_DIG2] = {
4004 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
4005 .init_verbs = { alc880_volume_init_verbs,
4006 alc880_pin_asus_init_verbs,
df694daa
KY
4007 alc880_gpio2_init_verbs }, /* use GPIO2 */
4008 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4009 .dac_nids = alc880_asus_dac_nids,
4010 .dig_out_nid = ALC880_DIGOUT_NID,
4011 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4012 .channel_mode = alc880_asus_modes,
4e195a7b 4013 .need_dac_fix = 1,
df694daa
KY
4014 .input_mux = &alc880_capture_source,
4015 },
16ded525 4016 [ALC880_ASUS_W1V] = {
e9edcee0 4017 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
4018 .init_verbs = { alc880_volume_init_verbs,
4019 alc880_pin_asus_init_verbs,
e9edcee0
TI
4020 alc880_gpio1_init_verbs },
4021 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4022 .dac_nids = alc880_asus_dac_nids,
16ded525 4023 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4024 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4025 .channel_mode = alc880_asus_modes,
4e195a7b 4026 .need_dac_fix = 1,
16ded525
TI
4027 .input_mux = &alc880_capture_source,
4028 },
4029 [ALC880_UNIWILL_DIG] = {
45bdd1c1 4030 .mixers = { alc880_asus_mixer },
ccc656ce
KY
4031 .init_verbs = { alc880_volume_init_verbs,
4032 alc880_pin_asus_init_verbs },
e9edcee0
TI
4033 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4034 .dac_nids = alc880_asus_dac_nids,
16ded525 4035 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
4036 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4037 .channel_mode = alc880_asus_modes,
4e195a7b 4038 .need_dac_fix = 1,
16ded525
TI
4039 .input_mux = &alc880_capture_source,
4040 },
ccc656ce
KY
4041 [ALC880_UNIWILL] = {
4042 .mixers = { alc880_uniwill_mixer },
4043 .init_verbs = { alc880_volume_init_verbs,
4044 alc880_uniwill_init_verbs },
4045 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4046 .dac_nids = alc880_asus_dac_nids,
4047 .dig_out_nid = ALC880_DIGOUT_NID,
4048 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4049 .channel_mode = alc880_threestack_modes,
4050 .need_dac_fix = 1,
4051 .input_mux = &alc880_capture_source,
4052 .unsol_event = alc880_uniwill_unsol_event,
a9fd4f3f 4053 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
4054 },
4055 [ALC880_UNIWILL_P53] = {
4056 .mixers = { alc880_uniwill_p53_mixer },
4057 .init_verbs = { alc880_volume_init_verbs,
4058 alc880_uniwill_p53_init_verbs },
4059 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4060 .dac_nids = alc880_asus_dac_nids,
4061 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
4062 .channel_mode = alc880_threestack_modes,
4063 .input_mux = &alc880_capture_source,
4064 .unsol_event = alc880_uniwill_p53_unsol_event,
a9fd4f3f 4065 .init_hook = alc880_uniwill_p53_init_hook,
2cf9f0fc
TD
4066 },
4067 [ALC880_FUJITSU] = {
45bdd1c1 4068 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
4069 .init_verbs = { alc880_volume_init_verbs,
4070 alc880_uniwill_p53_init_verbs,
4071 alc880_beep_init_verbs },
4072 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4073 .dac_nids = alc880_dac_nids,
d53d7d9e 4074 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
4075 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4076 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
4077 .input_mux = &alc880_capture_source,
4078 .unsol_event = alc880_uniwill_p53_unsol_event,
a9fd4f3f 4079 .init_hook = alc880_uniwill_p53_init_hook,
ccc656ce 4080 },
df694daa
KY
4081 [ALC880_CLEVO] = {
4082 .mixers = { alc880_three_stack_mixer },
4083 .init_verbs = { alc880_volume_init_verbs,
4084 alc880_pin_clevo_init_verbs },
4085 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4086 .dac_nids = alc880_dac_nids,
4087 .hp_nid = 0x03,
4088 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4089 .channel_mode = alc880_threestack_modes,
4e195a7b 4090 .need_dac_fix = 1,
df694daa
KY
4091 .input_mux = &alc880_capture_source,
4092 },
ae6b813a
TI
4093 [ALC880_LG] = {
4094 .mixers = { alc880_lg_mixer },
4095 .init_verbs = { alc880_volume_init_verbs,
4096 alc880_lg_init_verbs },
4097 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4098 .dac_nids = alc880_lg_dac_nids,
4099 .dig_out_nid = ALC880_DIGOUT_NID,
4100 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4101 .channel_mode = alc880_lg_ch_modes,
4e195a7b 4102 .need_dac_fix = 1,
ae6b813a 4103 .input_mux = &alc880_lg_capture_source,
a9fd4f3f
TI
4104 .unsol_event = alc_automute_amp_unsol_event,
4105 .init_hook = alc880_lg_init_hook,
cb53c626
TI
4106#ifdef CONFIG_SND_HDA_POWER_SAVE
4107 .loopbacks = alc880_lg_loopbacks,
4108#endif
ae6b813a 4109 },
d681518a
TI
4110 [ALC880_LG_LW] = {
4111 .mixers = { alc880_lg_lw_mixer },
4112 .init_verbs = { alc880_volume_init_verbs,
4113 alc880_lg_lw_init_verbs },
0a8c5da3 4114 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
4115 .dac_nids = alc880_dac_nids,
4116 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
4117 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4118 .channel_mode = alc880_lg_lw_modes,
d681518a 4119 .input_mux = &alc880_lg_lw_capture_source,
a9fd4f3f
TI
4120 .unsol_event = alc_automute_amp_unsol_event,
4121 .init_hook = alc880_lg_lw_init_hook,
d681518a 4122 },
df99cd33
TI
4123 [ALC880_MEDION_RIM] = {
4124 .mixers = { alc880_medion_rim_mixer },
4125 .init_verbs = { alc880_volume_init_verbs,
4126 alc880_medion_rim_init_verbs,
4127 alc_gpio2_init_verbs },
4128 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4129 .dac_nids = alc880_dac_nids,
4130 .dig_out_nid = ALC880_DIGOUT_NID,
4131 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4132 .channel_mode = alc880_2_jack_modes,
4133 .input_mux = &alc880_medion_rim_capture_source,
4134 .unsol_event = alc880_medion_rim_unsol_event,
a9fd4f3f 4135 .init_hook = alc880_medion_rim_init_hook,
df99cd33 4136 },
16ded525
TI
4137#ifdef CONFIG_SND_DEBUG
4138 [ALC880_TEST] = {
e9edcee0
TI
4139 .mixers = { alc880_test_mixer },
4140 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
4141 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4142 .dac_nids = alc880_test_dac_nids,
4143 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4144 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4145 .channel_mode = alc880_test_modes,
4146 .input_mux = &alc880_test_capture_source,
4147 },
4148#endif
4149};
4150
e9edcee0
TI
4151/*
4152 * Automatic parse of I/O pins from the BIOS configuration
4153 */
4154
e9edcee0
TI
4155enum {
4156 ALC_CTL_WIDGET_VOL,
4157 ALC_CTL_WIDGET_MUTE,
4158 ALC_CTL_BIND_MUTE,
4159};
c8b6bf9b 4160static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
4161 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4162 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 4163 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
4164};
4165
4166/* add dynamic controls */
f12ab1e0
TI
4167static int add_control(struct alc_spec *spec, int type, const char *name,
4168 unsigned long val)
e9edcee0 4169{
c8b6bf9b 4170 struct snd_kcontrol_new *knew;
e9edcee0 4171
603c4019
TI
4172 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4173 knew = snd_array_new(&spec->kctls);
4174 if (!knew)
4175 return -ENOMEM;
e9edcee0 4176 *knew = alc880_control_templates[type];
543537bd 4177 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 4178 if (!knew->name)
e9edcee0
TI
4179 return -ENOMEM;
4180 knew->private_value = val;
e9edcee0
TI
4181 return 0;
4182}
4183
4184#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4185#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4186#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4187#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4188#define alc880_is_input_pin(nid) ((nid) >= 0x18)
4189#define alc880_input_pin_idx(nid) ((nid) - 0x18)
4190#define alc880_idx_to_dac(nid) ((nid) + 0x02)
4191#define alc880_dac_to_idx(nid) ((nid) - 0x02)
4192#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4193#define alc880_idx_to_selector(nid) ((nid) + 0x10)
4194#define ALC880_PIN_CD_NID 0x1c
4195
4196/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
4197static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4198 const struct auto_pin_cfg *cfg)
e9edcee0
TI
4199{
4200 hda_nid_t nid;
4201 int assigned[4];
4202 int i, j;
4203
4204 memset(assigned, 0, sizeof(assigned));
b0af0de5 4205 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
4206
4207 /* check the pins hardwired to audio widget */
4208 for (i = 0; i < cfg->line_outs; i++) {
4209 nid = cfg->line_out_pins[i];
4210 if (alc880_is_fixed_pin(nid)) {
4211 int idx = alc880_fixed_pin_idx(nid);
5014f193 4212 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
4213 assigned[idx] = 1;
4214 }
4215 }
4216 /* left pins can be connect to any audio widget */
4217 for (i = 0; i < cfg->line_outs; i++) {
4218 nid = cfg->line_out_pins[i];
4219 if (alc880_is_fixed_pin(nid))
4220 continue;
4221 /* search for an empty channel */
4222 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
4223 if (!assigned[j]) {
4224 spec->multiout.dac_nids[i] =
4225 alc880_idx_to_dac(j);
e9edcee0
TI
4226 assigned[j] = 1;
4227 break;
4228 }
4229 }
4230 }
4231 spec->multiout.num_dacs = cfg->line_outs;
4232 return 0;
4233}
4234
4235/* add playback controls from the parsed DAC table */
df694daa
KY
4236static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4237 const struct auto_pin_cfg *cfg)
e9edcee0
TI
4238{
4239 char name[32];
f12ab1e0
TI
4240 static const char *chname[4] = {
4241 "Front", "Surround", NULL /*CLFE*/, "Side"
4242 };
e9edcee0
TI
4243 hda_nid_t nid;
4244 int i, err;
4245
4246 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 4247 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
4248 continue;
4249 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4250 if (i == 2) {
4251 /* Center/LFE */
f12ab1e0
TI
4252 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4253 "Center Playback Volume",
4254 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4255 HDA_OUTPUT));
4256 if (err < 0)
e9edcee0 4257 return err;
f12ab1e0
TI
4258 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4259 "LFE Playback Volume",
4260 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4261 HDA_OUTPUT));
4262 if (err < 0)
e9edcee0 4263 return err;
f12ab1e0
TI
4264 err = add_control(spec, ALC_CTL_BIND_MUTE,
4265 "Center Playback Switch",
4266 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4267 HDA_INPUT));
4268 if (err < 0)
e9edcee0 4269 return err;
f12ab1e0
TI
4270 err = add_control(spec, ALC_CTL_BIND_MUTE,
4271 "LFE Playback Switch",
4272 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4273 HDA_INPUT));
4274 if (err < 0)
e9edcee0
TI
4275 return err;
4276 } else {
4277 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
4278 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4279 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4280 HDA_OUTPUT));
4281 if (err < 0)
e9edcee0
TI
4282 return err;
4283 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0
TI
4284 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4285 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4286 HDA_INPUT));
4287 if (err < 0)
e9edcee0
TI
4288 return err;
4289 }
4290 }
e9edcee0
TI
4291 return 0;
4292}
4293
8d88bc3d
TI
4294/* add playback controls for speaker and HP outputs */
4295static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4296 const char *pfx)
e9edcee0
TI
4297{
4298 hda_nid_t nid;
4299 int err;
8d88bc3d 4300 char name[32];
e9edcee0 4301
f12ab1e0 4302 if (!pin)
e9edcee0
TI
4303 return 0;
4304
4305 if (alc880_is_fixed_pin(pin)) {
4306 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 4307 /* specify the DAC as the extra output */
f12ab1e0 4308 if (!spec->multiout.hp_nid)
e9edcee0 4309 spec->multiout.hp_nid = nid;
82bc955f
TI
4310 else
4311 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
4312 /* control HP volume/switch on the output mixer amp */
4313 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
8d88bc3d 4314 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
4315 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4316 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4317 if (err < 0)
e9edcee0 4318 return err;
8d88bc3d 4319 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
4320 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4321 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4322 if (err < 0)
e9edcee0
TI
4323 return err;
4324 } else if (alc880_is_multi_pin(pin)) {
4325 /* set manual connection */
e9edcee0 4326 /* we have only a switch on HP-out PIN */
8d88bc3d 4327 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
4328 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4329 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4330 if (err < 0)
e9edcee0
TI
4331 return err;
4332 }
4333 return 0;
4334}
4335
4336/* create input playback/capture controls for the given pin */
f12ab1e0
TI
4337static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4338 const char *ctlname,
df694daa 4339 int idx, hda_nid_t mix_nid)
e9edcee0
TI
4340{
4341 char name[32];
df694daa 4342 int err;
e9edcee0
TI
4343
4344 sprintf(name, "%s Playback Volume", ctlname);
f12ab1e0
TI
4345 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4346 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4347 if (err < 0)
e9edcee0
TI
4348 return err;
4349 sprintf(name, "%s Playback Switch", ctlname);
f12ab1e0
TI
4350 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4351 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4352 if (err < 0)
e9edcee0
TI
4353 return err;
4354 return 0;
4355}
4356
4357/* create playback/capture controls for input pins */
df694daa
KY
4358static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
4359 const struct auto_pin_cfg *cfg)
e9edcee0 4360{
61b9b9b1 4361 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa 4362 int i, err, idx;
e9edcee0
TI
4363
4364 for (i = 0; i < AUTO_PIN_LAST; i++) {
4365 if (alc880_is_input_pin(cfg->input_pins[i])) {
df694daa 4366 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4a471b7d
TI
4367 err = new_analog_input(spec, cfg->input_pins[i],
4368 auto_pin_cfg_labels[i],
df694daa 4369 idx, 0x0b);
e9edcee0
TI
4370 if (err < 0)
4371 return err;
f12ab1e0
TI
4372 imux->items[imux->num_items].label =
4373 auto_pin_cfg_labels[i];
4374 imux->items[imux->num_items].index =
4375 alc880_input_pin_idx(cfg->input_pins[i]);
e9edcee0
TI
4376 imux->num_items++;
4377 }
4378 }
4379 return 0;
4380}
4381
f6c7e546
TI
4382static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4383 unsigned int pin_type)
4384{
4385 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4386 pin_type);
4387 /* unmute pin */
d260cdf6
TI
4388 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4389 AMP_OUT_UNMUTE);
f6c7e546
TI
4390}
4391
df694daa
KY
4392static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4393 hda_nid_t nid, int pin_type,
e9edcee0
TI
4394 int dac_idx)
4395{
f6c7e546 4396 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
4397 /* need the manual connection? */
4398 if (alc880_is_multi_pin(nid)) {
4399 struct alc_spec *spec = codec->spec;
4400 int idx = alc880_multi_pin_idx(nid);
4401 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4402 AC_VERB_SET_CONNECT_SEL,
4403 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4404 }
4405}
4406
baba8ee9
TI
4407static int get_pin_type(int line_out_type)
4408{
4409 if (line_out_type == AUTO_PIN_HP_OUT)
4410 return PIN_HP;
4411 else
4412 return PIN_OUT;
4413}
4414
e9edcee0
TI
4415static void alc880_auto_init_multi_out(struct hda_codec *codec)
4416{
4417 struct alc_spec *spec = codec->spec;
4418 int i;
ea1fb29a 4419
e9edcee0
TI
4420 for (i = 0; i < spec->autocfg.line_outs; i++) {
4421 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
4422 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4423 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
4424 }
4425}
4426
8d88bc3d 4427static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
4428{
4429 struct alc_spec *spec = codec->spec;
4430 hda_nid_t pin;
4431
82bc955f 4432 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
4433 if (pin) /* connect to front */
4434 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 4435 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
4436 if (pin) /* connect to front */
4437 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4438}
4439
4440static void alc880_auto_init_analog_input(struct hda_codec *codec)
4441{
4442 struct alc_spec *spec = codec->spec;
4443 int i;
4444
4445 for (i = 0; i < AUTO_PIN_LAST; i++) {
4446 hda_nid_t nid = spec->autocfg.input_pins[i];
4447 if (alc880_is_input_pin(nid)) {
23f0c048 4448 alc_set_input_pin(codec, nid, i);
e82c025b
TI
4449 if (nid != ALC880_PIN_CD_NID &&
4450 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
4451 snd_hda_codec_write(codec, nid, 0,
4452 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
4453 AMP_OUT_MUTE);
4454 }
4455 }
4456}
4457
4458/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
4459/* return 1 if successful, 0 if the proper config is not found,
4460 * or a negative error code
4461 */
e9edcee0
TI
4462static int alc880_parse_auto_config(struct hda_codec *codec)
4463{
4464 struct alc_spec *spec = codec->spec;
6a05ac4a 4465 int i, err;
df694daa 4466 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 4467
f12ab1e0
TI
4468 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4469 alc880_ignore);
4470 if (err < 0)
e9edcee0 4471 return err;
f12ab1e0 4472 if (!spec->autocfg.line_outs)
e9edcee0 4473 return 0; /* can't find valid BIOS pin config */
df694daa 4474
f12ab1e0
TI
4475 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4476 if (err < 0)
4477 return err;
4478 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4479 if (err < 0)
4480 return err;
4481 err = alc880_auto_create_extra_out(spec,
4482 spec->autocfg.speaker_pins[0],
4483 "Speaker");
4484 if (err < 0)
4485 return err;
4486 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4487 "Headphone");
4488 if (err < 0)
4489 return err;
4490 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4491 if (err < 0)
e9edcee0
TI
4492 return err;
4493
4494 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4495
6a05ac4a
TI
4496 /* check multiple SPDIF-out (for recent codecs) */
4497 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4498 hda_nid_t dig_nid;
4499 err = snd_hda_get_connections(codec,
4500 spec->autocfg.dig_out_pins[i],
4501 &dig_nid, 1);
4502 if (err < 0)
4503 continue;
4504 if (!i)
4505 spec->multiout.dig_out_nid = dig_nid;
4506 else {
4507 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4508 spec->slave_dig_outs[i - 1] = dig_nid;
4509 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
4510 break;
4511 }
4512 }
e9edcee0
TI
4513 if (spec->autocfg.dig_in_pin)
4514 spec->dig_in_nid = ALC880_DIGIN_NID;
4515
603c4019 4516 if (spec->kctls.list)
d88897ea 4517 add_mixer(spec, spec->kctls.list);
e9edcee0 4518
d88897ea 4519 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 4520
a1e8d2da 4521 spec->num_mux_defs = 1;
61b9b9b1 4522 spec->input_mux = &spec->private_imux[0];
e9edcee0 4523
4a79ba34
TI
4524 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4525
e9edcee0
TI
4526 return 1;
4527}
4528
ae6b813a
TI
4529/* additional initialization for auto-configuration model */
4530static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 4531{
f6c7e546 4532 struct alc_spec *spec = codec->spec;
e9edcee0 4533 alc880_auto_init_multi_out(codec);
8d88bc3d 4534 alc880_auto_init_extra_out(codec);
e9edcee0 4535 alc880_auto_init_analog_input(codec);
f6c7e546 4536 if (spec->unsol_event)
7fb0d78f 4537 alc_inithook(codec);
e9edcee0
TI
4538}
4539
f9e336f6
TI
4540static void set_capture_mixer(struct alc_spec *spec)
4541{
a23b688f
TI
4542 static struct snd_kcontrol_new *caps[2][3] = {
4543 { alc_capture_mixer_nosrc1,
4544 alc_capture_mixer_nosrc2,
4545 alc_capture_mixer_nosrc3 },
4546 { alc_capture_mixer1,
4547 alc_capture_mixer2,
4548 alc_capture_mixer3 },
f9e336f6 4549 };
a23b688f
TI
4550 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4551 int mux;
4552 if (spec->input_mux && spec->input_mux->num_items > 1)
4553 mux = 1;
4554 else
4555 mux = 0;
4556 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4557 }
f9e336f6
TI
4558}
4559
45bdd1c1
TI
4560#define set_beep_amp(spec, nid, idx, dir) \
4561 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4562
4563/*
4564 * OK, here we have finally the patch for ALC880
4565 */
4566
1da177e4
LT
4567static int patch_alc880(struct hda_codec *codec)
4568{
4569 struct alc_spec *spec;
4570 int board_config;
df694daa 4571 int err;
1da177e4 4572
e560d8d8 4573 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
4574 if (spec == NULL)
4575 return -ENOMEM;
4576
4577 codec->spec = spec;
4578
f5fcc13c
TI
4579 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4580 alc880_models,
4581 alc880_cfg_tbl);
4582 if (board_config < 0) {
6c627f39
TI
4583 printk(KERN_INFO "hda_codec: Unknown model for %s, "
4584 "trying auto-probe from BIOS...\n", codec->chip_name);
e9edcee0 4585 board_config = ALC880_AUTO;
1da177e4 4586 }
1da177e4 4587
e9edcee0
TI
4588 if (board_config == ALC880_AUTO) {
4589 /* automatic parse from the BIOS config */
4590 err = alc880_parse_auto_config(codec);
4591 if (err < 0) {
4592 alc_free(codec);
4593 return err;
f12ab1e0 4594 } else if (!err) {
9c7f852e
TI
4595 printk(KERN_INFO
4596 "hda_codec: Cannot set up configuration "
4597 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
4598 board_config = ALC880_3ST;
4599 }
1da177e4
LT
4600 }
4601
680cd536
KK
4602 err = snd_hda_attach_beep_device(codec, 0x1);
4603 if (err < 0) {
4604 alc_free(codec);
4605 return err;
4606 }
4607
df694daa
KY
4608 if (board_config != ALC880_AUTO)
4609 setup_preset(spec, &alc880_presets[board_config]);
1da177e4 4610
1da177e4
LT
4611 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4612 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 4613 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 4614
1da177e4
LT
4615 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4616 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4617
f12ab1e0 4618 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 4619 /* check whether NID 0x07 is valid */
54d17403 4620 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0
TI
4621 /* get type */
4622 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
e9edcee0
TI
4623 if (wcap != AC_WID_AUD_IN) {
4624 spec->adc_nids = alc880_adc_nids_alt;
4625 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
4626 } else {
4627 spec->adc_nids = alc880_adc_nids;
4628 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
4629 }
4630 }
f9e336f6 4631 set_capture_mixer(spec);
45bdd1c1 4632 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 4633
2134ea4f
TI
4634 spec->vmaster_nid = 0x0c;
4635
1da177e4 4636 codec->patch_ops = alc_patch_ops;
e9edcee0 4637 if (board_config == ALC880_AUTO)
ae6b813a 4638 spec->init_hook = alc880_auto_init;
cb53c626
TI
4639#ifdef CONFIG_SND_HDA_POWER_SAVE
4640 if (!spec->loopback.amplist)
4641 spec->loopback.amplist = alc880_loopbacks;
4642#endif
daead538 4643 codec->proc_widget_hook = print_realtek_coef;
1da177e4
LT
4644
4645 return 0;
4646}
4647
e9edcee0 4648
1da177e4
LT
4649/*
4650 * ALC260 support
4651 */
4652
e9edcee0
TI
4653static hda_nid_t alc260_dac_nids[1] = {
4654 /* front */
4655 0x02,
4656};
4657
4658static hda_nid_t alc260_adc_nids[1] = {
4659 /* ADC0 */
4660 0x04,
4661};
4662
df694daa 4663static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
4664 /* ADC1 */
4665 0x05,
4666};
4667
d57fdac0
JW
4668/* NIDs used when simultaneous access to both ADCs makes sense. Note that
4669 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4670 */
4671static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
4672 /* ADC0, ADC1 */
4673 0x04, 0x05
4674};
4675
e9edcee0
TI
4676#define ALC260_DIGOUT_NID 0x03
4677#define ALC260_DIGIN_NID 0x06
4678
4679static struct hda_input_mux alc260_capture_source = {
4680 .num_items = 4,
4681 .items = {
4682 { "Mic", 0x0 },
4683 { "Front Mic", 0x1 },
4684 { "Line", 0x2 },
4685 { "CD", 0x4 },
4686 },
4687};
4688
17e7aec6 4689/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
4690 * headphone jack and the internal CD lines since these are the only pins at
4691 * which audio can appear. For flexibility, also allow the option of
4692 * recording the mixer output on the second ADC (ADC0 doesn't have a
4693 * connection to the mixer output).
a9430dd8 4694 */
a1e8d2da
JW
4695static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4696 {
4697 .num_items = 3,
4698 .items = {
4699 { "Mic/Line", 0x0 },
4700 { "CD", 0x4 },
4701 { "Headphone", 0x2 },
4702 },
a9430dd8 4703 },
a1e8d2da
JW
4704 {
4705 .num_items = 4,
4706 .items = {
4707 { "Mic/Line", 0x0 },
4708 { "CD", 0x4 },
4709 { "Headphone", 0x2 },
4710 { "Mixer", 0x5 },
4711 },
4712 },
4713
a9430dd8
JW
4714};
4715
a1e8d2da
JW
4716/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4717 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 4718 */
a1e8d2da
JW
4719static struct hda_input_mux alc260_acer_capture_sources[2] = {
4720 {
4721 .num_items = 4,
4722 .items = {
4723 { "Mic", 0x0 },
4724 { "Line", 0x2 },
4725 { "CD", 0x4 },
4726 { "Headphone", 0x5 },
4727 },
4728 },
4729 {
4730 .num_items = 5,
4731 .items = {
4732 { "Mic", 0x0 },
4733 { "Line", 0x2 },
4734 { "CD", 0x4 },
4735 { "Headphone", 0x6 },
4736 { "Mixer", 0x5 },
4737 },
0bfc90e9
JW
4738 },
4739};
cc959489
MS
4740
4741/* Maxdata Favorit 100XS */
4742static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4743 {
4744 .num_items = 2,
4745 .items = {
4746 { "Line/Mic", 0x0 },
4747 { "CD", 0x4 },
4748 },
4749 },
4750 {
4751 .num_items = 3,
4752 .items = {
4753 { "Line/Mic", 0x0 },
4754 { "CD", 0x4 },
4755 { "Mixer", 0x5 },
4756 },
4757 },
4758};
4759
1da177e4
LT
4760/*
4761 * This is just place-holder, so there's something for alc_build_pcms to look
4762 * at when it calculates the maximum number of channels. ALC260 has no mixer
4763 * element which allows changing the channel mode, so the verb list is
4764 * never used.
4765 */
d2a6d7dc 4766static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
4767 { 2, NULL },
4768};
4769
df694daa
KY
4770
4771/* Mixer combinations
4772 *
4773 * basic: base_output + input + pc_beep + capture
4774 * HP: base_output + input + capture_alt
4775 * HP_3013: hp_3013 + input + capture
4776 * fujitsu: fujitsu + capture
0bfc90e9 4777 * acer: acer + capture
df694daa
KY
4778 */
4779
4780static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 4781 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 4782 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 4783 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 4784 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 4785 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 4786 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 4787 { } /* end */
f12ab1e0 4788};
1da177e4 4789
df694daa 4790static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
4791 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4792 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4793 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4794 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4795 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4796 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4797 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4798 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
4799 { } /* end */
4800};
4801
bec15c3a
TI
4802/* update HP, line and mono out pins according to the master switch */
4803static void alc260_hp_master_update(struct hda_codec *codec,
4804 hda_nid_t hp, hda_nid_t line,
4805 hda_nid_t mono)
4806{
4807 struct alc_spec *spec = codec->spec;
4808 unsigned int val = spec->master_sw ? PIN_HP : 0;
4809 /* change HP and line-out pins */
30cde0aa 4810 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a 4811 val);
30cde0aa 4812 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
4813 val);
4814 /* mono (speaker) depending on the HP jack sense */
4815 val = (val && !spec->jack_present) ? PIN_OUT : 0;
30cde0aa 4816 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
bec15c3a
TI
4817 val);
4818}
4819
4820static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4821 struct snd_ctl_elem_value *ucontrol)
4822{
4823 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4824 struct alc_spec *spec = codec->spec;
4825 *ucontrol->value.integer.value = spec->master_sw;
4826 return 0;
4827}
4828
4829static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4830 struct snd_ctl_elem_value *ucontrol)
4831{
4832 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4833 struct alc_spec *spec = codec->spec;
4834 int val = !!*ucontrol->value.integer.value;
4835 hda_nid_t hp, line, mono;
4836
4837 if (val == spec->master_sw)
4838 return 0;
4839 spec->master_sw = val;
4840 hp = (kcontrol->private_value >> 16) & 0xff;
4841 line = (kcontrol->private_value >> 8) & 0xff;
4842 mono = kcontrol->private_value & 0xff;
4843 alc260_hp_master_update(codec, hp, line, mono);
4844 return 1;
4845}
4846
4847static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4848 {
4849 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4850 .name = "Master Playback Switch",
4851 .info = snd_ctl_boolean_mono_info,
4852 .get = alc260_hp_master_sw_get,
4853 .put = alc260_hp_master_sw_put,
4854 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4855 },
4856 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4857 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4858 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4859 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4860 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4861 HDA_OUTPUT),
4862 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4863 { } /* end */
4864};
4865
4866static struct hda_verb alc260_hp_unsol_verbs[] = {
4867 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4868 {},
4869};
4870
4871static void alc260_hp_automute(struct hda_codec *codec)
4872{
4873 struct alc_spec *spec = codec->spec;
4874 unsigned int present;
4875
4876 present = snd_hda_codec_read(codec, 0x10, 0,
4877 AC_VERB_GET_PIN_SENSE, 0);
4878 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4879 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4880}
4881
4882static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4883{
4884 if ((res >> 26) == ALC880_HP_EVENT)
4885 alc260_hp_automute(codec);
4886}
4887
df694daa 4888static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
4889 {
4890 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4891 .name = "Master Playback Switch",
4892 .info = snd_ctl_boolean_mono_info,
4893 .get = alc260_hp_master_sw_get,
4894 .put = alc260_hp_master_sw_put,
30cde0aa 4895 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
bec15c3a 4896 },
df694daa
KY
4897 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4898 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4899 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4900 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4901 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4902 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
4903 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4904 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
4905 { } /* end */
4906};
4907
3f878308
KY
4908static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4909 .ops = &snd_hda_bind_vol,
4910 .values = {
4911 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4912 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4913 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4914 0
4915 },
4916};
4917
4918static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4919 .ops = &snd_hda_bind_sw,
4920 .values = {
4921 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4922 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4923 0
4924 },
4925};
4926
4927static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4928 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4929 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4930 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4931 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4932 { } /* end */
4933};
4934
bec15c3a
TI
4935static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4936 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4937 {},
4938};
4939
4940static void alc260_hp_3013_automute(struct hda_codec *codec)
4941{
4942 struct alc_spec *spec = codec->spec;
4943 unsigned int present;
4944
4945 present = snd_hda_codec_read(codec, 0x15, 0,
4946 AC_VERB_GET_PIN_SENSE, 0);
4947 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
30cde0aa 4948 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
bec15c3a
TI
4949}
4950
4951static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4952 unsigned int res)
4953{
4954 if ((res >> 26) == ALC880_HP_EVENT)
4955 alc260_hp_3013_automute(codec);
4956}
4957
3f878308
KY
4958static void alc260_hp_3012_automute(struct hda_codec *codec)
4959{
4960 unsigned int present, bits;
4961
4962 present = snd_hda_codec_read(codec, 0x10, 0,
4963 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4964
4965 bits = present ? 0 : PIN_OUT;
4966 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4967 bits);
4968 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4969 bits);
4970 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4971 bits);
4972}
4973
4974static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4975 unsigned int res)
4976{
4977 if ((res >> 26) == ALC880_HP_EVENT)
4978 alc260_hp_3012_automute(codec);
4979}
4980
4981/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
4982 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4983 */
c8b6bf9b 4984static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 4985 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 4986 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 4987 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
4988 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4989 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4990 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4991 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 4992 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
4993 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4994 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
4995 { } /* end */
4996};
4997
a1e8d2da
JW
4998/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4999 * versions of the ALC260 don't act on requests to enable mic bias from NID
5000 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5001 * datasheet doesn't mention this restriction. At this stage it's not clear
5002 * whether this behaviour is intentional or is a hardware bug in chip
5003 * revisions available in early 2006. Therefore for now allow the
5004 * "Headphone Jack Mode" control to span all choices, but if it turns out
5005 * that the lack of mic bias for this NID is intentional we could change the
5006 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5007 *
5008 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5009 * don't appear to make the mic bias available from the "line" jack, even
5010 * though the NID used for this jack (0x14) can supply it. The theory is
5011 * that perhaps Acer have included blocking capacitors between the ALC260
5012 * and the output jack. If this turns out to be the case for all such
5013 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5014 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
5015 *
5016 * The C20x Tablet series have a mono internal speaker which is controlled
5017 * via the chip's Mono sum widget and pin complex, so include the necessary
5018 * controls for such models. On models without a "mono speaker" the control
5019 * won't do anything.
a1e8d2da 5020 */
0bfc90e9
JW
5021static struct snd_kcontrol_new alc260_acer_mixer[] = {
5022 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5023 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 5024 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 5025 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 5026 HDA_OUTPUT),
31bffaa9 5027 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 5028 HDA_INPUT),
0bfc90e9
JW
5029 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5030 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5031 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5032 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5033 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5034 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5035 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5036 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
5037 { } /* end */
5038};
5039
cc959489
MS
5040/* Maxdata Favorit 100XS: one output and one input (0x12) jack
5041 */
5042static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5043 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5044 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5045 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5046 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5047 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5048 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5049 { } /* end */
5050};
5051
bc9f98a9
KY
5052/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5053 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5054 */
5055static struct snd_kcontrol_new alc260_will_mixer[] = {
5056 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5057 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5058 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5059 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5060 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5061 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5062 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5063 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5064 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5065 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
5066 { } /* end */
5067};
5068
5069/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5070 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5071 */
5072static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5073 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5074 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5075 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5076 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5077 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5078 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5079 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5080 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5081 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5082 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5083 { } /* end */
5084};
5085
df694daa
KY
5086/*
5087 * initialization verbs
5088 */
1da177e4
LT
5089static struct hda_verb alc260_init_verbs[] = {
5090 /* Line In pin widget for input */
05acb863 5091 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5092 /* CD pin widget for input */
05acb863 5093 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 5094 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 5095 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5096 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 5097 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 5098 /* LINE-2 is used for line-out in rear */
05acb863 5099 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5100 /* select line-out */
fd56f2db 5101 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5102 /* LINE-OUT pin */
05acb863 5103 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 5104 /* enable HP */
05acb863 5105 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 5106 /* enable Mono */
05acb863
TI
5107 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5108 /* mute capture amp left and right */
16ded525 5109 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
5110 /* set connection select to line in (default select for this ADC) */
5111 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
5112 /* mute capture amp left and right */
5113 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5114 /* set connection select to line in (default select for this ADC) */
5115 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
5116 /* set vol=0 Line-Out mixer amp left and right */
5117 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5118 /* unmute pin widget amp left and right (no gain on this amp) */
5119 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5120 /* set vol=0 HP mixer amp left and right */
5121 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5122 /* unmute pin widget amp left and right (no gain on this amp) */
5123 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5124 /* set vol=0 Mono mixer amp left and right */
5125 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5126 /* unmute pin widget amp left and right (no gain on this amp) */
5127 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5128 /* unmute LINE-2 out pin */
5129 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
5130 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5131 * Line In 2 = 0x03
5132 */
cb53c626
TI
5133 /* mute analog inputs */
5134 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5135 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5136 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5137 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5138 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5139 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
5140 /* mute Front out path */
5141 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5142 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5143 /* mute Headphone out path */
5144 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5145 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5146 /* mute Mono out path */
5147 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5148 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
5149 { }
5150};
5151
474167d6 5152#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
5153static struct hda_verb alc260_hp_init_verbs[] = {
5154 /* Headphone and output */
5155 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5156 /* mono output */
5157 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5158 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5159 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5160 /* Mic2 (front panel) pin widget for input and vref at 80% */
5161 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5162 /* Line In pin widget for input */
5163 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5164 /* Line-2 pin widget for output */
5165 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5166 /* CD pin widget for input */
5167 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5168 /* unmute amp left and right */
5169 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5170 /* set connection select to line in (default select for this ADC) */
5171 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5172 /* unmute Line-Out mixer amp left and right (volume = 0) */
5173 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5174 /* mute pin widget amp left and right (no gain on this amp) */
5175 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5176 /* unmute HP mixer amp left and right (volume = 0) */
5177 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5178 /* mute pin widget amp left and right (no gain on this amp) */
5179 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5180 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5181 * Line In 2 = 0x03
5182 */
cb53c626
TI
5183 /* mute analog inputs */
5184 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5185 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5186 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5187 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5188 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5189 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5190 /* Unmute Front out path */
5191 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5192 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5193 /* Unmute Headphone out path */
5194 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5195 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5196 /* Unmute Mono out path */
5197 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5198 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5199 { }
5200};
474167d6 5201#endif
df694daa
KY
5202
5203static struct hda_verb alc260_hp_3013_init_verbs[] = {
5204 /* Line out and output */
5205 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5206 /* mono output */
5207 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5208 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5209 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5210 /* Mic2 (front panel) pin widget for input and vref at 80% */
5211 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5212 /* Line In pin widget for input */
5213 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5214 /* Headphone pin widget for output */
5215 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5216 /* CD pin widget for input */
5217 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5218 /* unmute amp left and right */
5219 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5220 /* set connection select to line in (default select for this ADC) */
5221 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5222 /* unmute Line-Out mixer amp left and right (volume = 0) */
5223 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5224 /* mute pin widget amp left and right (no gain on this amp) */
5225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5226 /* unmute HP mixer amp left and right (volume = 0) */
5227 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5228 /* mute pin widget amp left and right (no gain on this amp) */
5229 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
5230 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5231 * Line In 2 = 0x03
5232 */
cb53c626
TI
5233 /* mute analog inputs */
5234 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5235 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5236 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5237 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5238 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5239 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5240 /* Unmute Front out path */
5241 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5242 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5243 /* Unmute Headphone out path */
5244 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5245 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5246 /* Unmute Mono out path */
5247 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5248 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5249 { }
5250};
5251
a9430dd8 5252/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
5253 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5254 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
5255 */
5256static struct hda_verb alc260_fujitsu_init_verbs[] = {
5257 /* Disable all GPIOs */
5258 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5259 /* Internal speaker is connected to headphone pin */
5260 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5261 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5262 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
5263 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5264 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5265 /* Ensure all other unused pins are disabled and muted. */
5266 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5267 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 5268 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 5269 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 5270 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
5271 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5272 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5273 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5274
5275 /* Disable digital (SPDIF) pins */
5276 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5277 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 5278
ea1fb29a 5279 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
5280 * when acting as an output.
5281 */
5282 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 5283
f7ace40d 5284 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
5285 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5286 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5287 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5288 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5289 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5290 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5291 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5292 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5293 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 5294
f7ace40d
JW
5295 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5296 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5297 /* Unmute Line1 pin widget output buffer since it starts as an output.
5298 * If the pin mode is changed by the user the pin mode control will
5299 * take care of enabling the pin's input/output buffers as needed.
5300 * Therefore there's no need to enable the input buffer at this
5301 * stage.
cdcd9268 5302 */
f7ace40d 5303 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 5304 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
5305 * mixer ctrl)
5306 */
f7ace40d
JW
5307 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5308
5309 /* Mute capture amp left and right */
5310 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 5311 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
5312 * in (on mic1 pin)
5313 */
5314 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5315
5316 /* Do the same for the second ADC: mute capture input amp and
5317 * set ADC connection to line in (on mic1 pin)
5318 */
5319 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5320 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5321
5322 /* Mute all inputs to mixer widget (even unconnected ones) */
5323 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5324 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5325 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5326 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5327 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5328 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5329 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5330 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
5331
5332 { }
a9430dd8
JW
5333};
5334
0bfc90e9
JW
5335/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5336 * similar laptops (adapted from Fujitsu init verbs).
5337 */
5338static struct hda_verb alc260_acer_init_verbs[] = {
5339 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5340 * the headphone jack. Turn this on and rely on the standard mute
5341 * methods whenever the user wants to turn these outputs off.
5342 */
5343 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5344 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5345 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5346 /* Internal speaker/Headphone jack is connected to Line-out pin */
5347 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5348 /* Internal microphone/Mic jack is connected to Mic1 pin */
5349 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5350 /* Line In jack is connected to Line1 pin */
5351 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
5352 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5353 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
5354 /* Ensure all other unused pins are disabled and muted. */
5355 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5356 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
5357 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5358 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5359 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5360 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5361 /* Disable digital (SPDIF) pins */
5362 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5363 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5364
ea1fb29a 5365 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
5366 * bus when acting as outputs.
5367 */
5368 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5369 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5370
5371 /* Start with output sum widgets muted and their output gains at min */
5372 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5373 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5374 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5375 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5376 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5377 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5378 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5379 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5380 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5381
f12ab1e0
TI
5382 /* Unmute Line-out pin widget amp left and right
5383 * (no equiv mixer ctrl)
5384 */
0bfc90e9 5385 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
5386 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5387 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
5388 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5389 * inputs. If the pin mode is changed by the user the pin mode control
5390 * will take care of enabling the pin's input/output buffers as needed.
5391 * Therefore there's no need to enable the input buffer at this
5392 * stage.
5393 */
5394 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5395 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5396
5397 /* Mute capture amp left and right */
5398 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5399 /* Set ADC connection select to match default mixer setting - mic
5400 * (on mic1 pin)
5401 */
5402 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5403
5404 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 5405 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
5406 */
5407 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 5408 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
5409
5410 /* Mute all inputs to mixer widget (even unconnected ones) */
5411 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5412 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5413 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5414 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5415 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5416 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5417 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5418 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5419
5420 { }
5421};
5422
cc959489
MS
5423/* Initialisation sequence for Maxdata Favorit 100XS
5424 * (adapted from Acer init verbs).
5425 */
5426static struct hda_verb alc260_favorit100_init_verbs[] = {
5427 /* GPIO 0 enables the output jack.
5428 * Turn this on and rely on the standard mute
5429 * methods whenever the user wants to turn these outputs off.
5430 */
5431 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5432 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5433 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5434 /* Line/Mic input jack is connected to Mic1 pin */
5435 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5436 /* Ensure all other unused pins are disabled and muted. */
5437 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5438 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5439 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5440 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5441 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5442 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5443 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5444 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5445 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5446 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5447 /* Disable digital (SPDIF) pins */
5448 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5449 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5450
5451 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5452 * bus when acting as outputs.
5453 */
5454 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5455 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5456
5457 /* Start with output sum widgets muted and their output gains at min */
5458 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5459 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5460 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5461 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5462 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5463 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5464 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5465 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5466 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5467
5468 /* Unmute Line-out pin widget amp left and right
5469 * (no equiv mixer ctrl)
5470 */
5471 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5472 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5473 * inputs. If the pin mode is changed by the user the pin mode control
5474 * will take care of enabling the pin's input/output buffers as needed.
5475 * Therefore there's no need to enable the input buffer at this
5476 * stage.
5477 */
5478 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5479
5480 /* Mute capture amp left and right */
5481 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5482 /* Set ADC connection select to match default mixer setting - mic
5483 * (on mic1 pin)
5484 */
5485 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5486
5487 /* Do similar with the second ADC: mute capture input amp and
5488 * set ADC connection to mic to match ALSA's default state.
5489 */
5490 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5491 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5492
5493 /* Mute all inputs to mixer widget (even unconnected ones) */
5494 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5495 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5496 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5497 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5498 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5499 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5500 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5501 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5502
5503 { }
5504};
5505
bc9f98a9
KY
5506static struct hda_verb alc260_will_verbs[] = {
5507 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5508 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5509 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5510 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5511 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5512 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5513 {}
5514};
5515
5516static struct hda_verb alc260_replacer_672v_verbs[] = {
5517 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5518 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5519 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5520
5521 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5522 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5523 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5524
5525 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5526 {}
5527};
5528
5529/* toggle speaker-output according to the hp-jack state */
5530static void alc260_replacer_672v_automute(struct hda_codec *codec)
5531{
5532 unsigned int present;
5533
5534 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5535 present = snd_hda_codec_read(codec, 0x0f, 0,
5536 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5537 if (present) {
82beb8fd
TI
5538 snd_hda_codec_write_cache(codec, 0x01, 0,
5539 AC_VERB_SET_GPIO_DATA, 1);
5540 snd_hda_codec_write_cache(codec, 0x0f, 0,
5541 AC_VERB_SET_PIN_WIDGET_CONTROL,
5542 PIN_HP);
bc9f98a9 5543 } else {
82beb8fd
TI
5544 snd_hda_codec_write_cache(codec, 0x01, 0,
5545 AC_VERB_SET_GPIO_DATA, 0);
5546 snd_hda_codec_write_cache(codec, 0x0f, 0,
5547 AC_VERB_SET_PIN_WIDGET_CONTROL,
5548 PIN_OUT);
bc9f98a9
KY
5549 }
5550}
5551
5552static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5553 unsigned int res)
5554{
5555 if ((res >> 26) == ALC880_HP_EVENT)
5556 alc260_replacer_672v_automute(codec);
5557}
5558
3f878308
KY
5559static struct hda_verb alc260_hp_dc7600_verbs[] = {
5560 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5561 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5562 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5563 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5564 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5565 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5566 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5567 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5568 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5569 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5570 {}
5571};
5572
7cf51e48
JW
5573/* Test configuration for debugging, modelled after the ALC880 test
5574 * configuration.
5575 */
5576#ifdef CONFIG_SND_DEBUG
5577static hda_nid_t alc260_test_dac_nids[1] = {
5578 0x02,
5579};
5580static hda_nid_t alc260_test_adc_nids[2] = {
5581 0x04, 0x05,
5582};
a1e8d2da 5583/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 5584 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 5585 * is NID 0x04.
17e7aec6 5586 */
a1e8d2da
JW
5587static struct hda_input_mux alc260_test_capture_sources[2] = {
5588 {
5589 .num_items = 7,
5590 .items = {
5591 { "MIC1 pin", 0x0 },
5592 { "MIC2 pin", 0x1 },
5593 { "LINE1 pin", 0x2 },
5594 { "LINE2 pin", 0x3 },
5595 { "CD pin", 0x4 },
5596 { "LINE-OUT pin", 0x5 },
5597 { "HP-OUT pin", 0x6 },
5598 },
5599 },
5600 {
5601 .num_items = 8,
5602 .items = {
5603 { "MIC1 pin", 0x0 },
5604 { "MIC2 pin", 0x1 },
5605 { "LINE1 pin", 0x2 },
5606 { "LINE2 pin", 0x3 },
5607 { "CD pin", 0x4 },
5608 { "Mixer", 0x5 },
5609 { "LINE-OUT pin", 0x6 },
5610 { "HP-OUT pin", 0x7 },
5611 },
7cf51e48
JW
5612 },
5613};
5614static struct snd_kcontrol_new alc260_test_mixer[] = {
5615 /* Output driver widgets */
5616 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5617 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5618 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5619 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5620 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5621 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5622
a1e8d2da
JW
5623 /* Modes for retasking pin widgets
5624 * Note: the ALC260 doesn't seem to act on requests to enable mic
5625 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5626 * mention this restriction. At this stage it's not clear whether
5627 * this behaviour is intentional or is a hardware bug in chip
5628 * revisions available at least up until early 2006. Therefore for
5629 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5630 * choices, but if it turns out that the lack of mic bias for these
5631 * NIDs is intentional we could change their modes from
5632 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5633 */
7cf51e48
JW
5634 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5635 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5636 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5637 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5638 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5639 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5640
5641 /* Loopback mixer controls */
5642 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5643 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5644 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5645 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5646 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5647 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5648 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5649 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5650 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5651 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
5652 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5653 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5654 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5655 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
5656
5657 /* Controls for GPIO pins, assuming they are configured as outputs */
5658 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5659 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5660 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5661 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5662
92621f13
JW
5663 /* Switches to allow the digital IO pins to be enabled. The datasheet
5664 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 5665 * make this output available should provide clarification.
92621f13
JW
5666 */
5667 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5668 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5669
f8225f6d
JW
5670 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5671 * this output to turn on an external amplifier.
5672 */
5673 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5674 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5675
7cf51e48
JW
5676 { } /* end */
5677};
5678static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
5679 /* Enable all GPIOs as outputs with an initial value of 0 */
5680 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5681 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5682 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5683
7cf51e48
JW
5684 /* Enable retasking pins as output, initially without power amp */
5685 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5686 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5687 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5688 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5689 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5690 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5691
92621f13
JW
5692 /* Disable digital (SPDIF) pins initially, but users can enable
5693 * them via a mixer switch. In the case of SPDIF-out, this initverb
5694 * payload also sets the generation to 0, output to be in "consumer"
5695 * PCM format, copyright asserted, no pre-emphasis and no validity
5696 * control.
5697 */
7cf51e48
JW
5698 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5699 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5700
ea1fb29a 5701 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
5702 * OUT1 sum bus when acting as an output.
5703 */
5704 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5705 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5706 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5707 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5708
5709 /* Start with output sum widgets muted and their output gains at min */
5710 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5711 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5712 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5713 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5714 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5715 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5716 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5717 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5718 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5719
cdcd9268
JW
5720 /* Unmute retasking pin widget output buffers since the default
5721 * state appears to be output. As the pin mode is changed by the
5722 * user the pin mode control will take care of enabling the pin's
5723 * input/output buffers as needed.
5724 */
7cf51e48
JW
5725 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5726 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5727 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5728 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5729 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5730 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5731 /* Also unmute the mono-out pin widget */
5732 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5733
7cf51e48
JW
5734 /* Mute capture amp left and right */
5735 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
5736 /* Set ADC connection select to match default mixer setting (mic1
5737 * pin)
7cf51e48
JW
5738 */
5739 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5740
5741 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 5742 * set ADC connection to mic1 pin
7cf51e48
JW
5743 */
5744 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5745 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5746
5747 /* Mute all inputs to mixer widget (even unconnected ones) */
5748 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5749 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5750 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5751 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5752 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5753 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5754 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5755 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5756
5757 { }
5758};
5759#endif
5760
6330079f
TI
5761#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5762#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 5763
a3bcba38
TI
5764#define alc260_pcm_digital_playback alc880_pcm_digital_playback
5765#define alc260_pcm_digital_capture alc880_pcm_digital_capture
5766
df694daa
KY
5767/*
5768 * for BIOS auto-configuration
5769 */
16ded525 5770
df694daa 5771static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 5772 const char *pfx, int *vol_bits)
df694daa
KY
5773{
5774 hda_nid_t nid_vol;
5775 unsigned long vol_val, sw_val;
5776 char name[32];
5777 int err;
5778
5779 if (nid >= 0x0f && nid < 0x11) {
5780 nid_vol = nid - 0x7;
5781 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5782 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5783 } else if (nid == 0x11) {
5784 nid_vol = nid - 0x7;
5785 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5786 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5787 } else if (nid >= 0x12 && nid <= 0x15) {
5788 nid_vol = 0x08;
5789 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5790 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5791 } else
5792 return 0; /* N/A */
ea1fb29a 5793
863b4518
TI
5794 if (!(*vol_bits & (1 << nid_vol))) {
5795 /* first control for the volume widget */
5796 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5797 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5798 if (err < 0)
5799 return err;
5800 *vol_bits |= (1 << nid_vol);
5801 }
df694daa 5802 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
f12ab1e0
TI
5803 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5804 if (err < 0)
df694daa
KY
5805 return err;
5806 return 1;
5807}
5808
5809/* add playback controls from the parsed DAC table */
5810static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5811 const struct auto_pin_cfg *cfg)
5812{
5813 hda_nid_t nid;
5814 int err;
863b4518 5815 int vols = 0;
df694daa
KY
5816
5817 spec->multiout.num_dacs = 1;
5818 spec->multiout.dac_nids = spec->private_dac_nids;
5819 spec->multiout.dac_nids[0] = 0x02;
5820
5821 nid = cfg->line_out_pins[0];
5822 if (nid) {
863b4518 5823 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
df694daa
KY
5824 if (err < 0)
5825 return err;
5826 }
5827
82bc955f 5828 nid = cfg->speaker_pins[0];
df694daa 5829 if (nid) {
863b4518 5830 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
5831 if (err < 0)
5832 return err;
5833 }
5834
eb06ed8f 5835 nid = cfg->hp_pins[0];
df694daa 5836 if (nid) {
863b4518
TI
5837 err = alc260_add_playback_controls(spec, nid, "Headphone",
5838 &vols);
df694daa
KY
5839 if (err < 0)
5840 return err;
5841 }
f12ab1e0 5842 return 0;
df694daa
KY
5843}
5844
5845/* create playback/capture controls for input pins */
5846static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5847 const struct auto_pin_cfg *cfg)
5848{
61b9b9b1 5849 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa
KY
5850 int i, err, idx;
5851
5852 for (i = 0; i < AUTO_PIN_LAST; i++) {
5853 if (cfg->input_pins[i] >= 0x12) {
5854 idx = cfg->input_pins[i] - 0x12;
4a471b7d 5855 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
5856 auto_pin_cfg_labels[i], idx,
5857 0x07);
df694daa
KY
5858 if (err < 0)
5859 return err;
f12ab1e0
TI
5860 imux->items[imux->num_items].label =
5861 auto_pin_cfg_labels[i];
df694daa
KY
5862 imux->items[imux->num_items].index = idx;
5863 imux->num_items++;
5864 }
f12ab1e0 5865 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
df694daa 5866 idx = cfg->input_pins[i] - 0x09;
4a471b7d 5867 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
5868 auto_pin_cfg_labels[i], idx,
5869 0x07);
df694daa
KY
5870 if (err < 0)
5871 return err;
f12ab1e0
TI
5872 imux->items[imux->num_items].label =
5873 auto_pin_cfg_labels[i];
df694daa
KY
5874 imux->items[imux->num_items].index = idx;
5875 imux->num_items++;
5876 }
5877 }
5878 return 0;
5879}
5880
5881static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5882 hda_nid_t nid, int pin_type,
5883 int sel_idx)
5884{
f6c7e546 5885 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
5886 /* need the manual connection? */
5887 if (nid >= 0x12) {
5888 int idx = nid - 0x12;
5889 snd_hda_codec_write(codec, idx + 0x0b, 0,
5890 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
5891 }
5892}
5893
5894static void alc260_auto_init_multi_out(struct hda_codec *codec)
5895{
5896 struct alc_spec *spec = codec->spec;
5897 hda_nid_t nid;
5898
f12ab1e0 5899 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
5900 if (nid) {
5901 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5902 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5903 }
ea1fb29a 5904
82bc955f 5905 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
5906 if (nid)
5907 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5908
eb06ed8f 5909 nid = spec->autocfg.hp_pins[0];
df694daa 5910 if (nid)
baba8ee9 5911 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 5912}
df694daa
KY
5913
5914#define ALC260_PIN_CD_NID 0x16
5915static void alc260_auto_init_analog_input(struct hda_codec *codec)
5916{
5917 struct alc_spec *spec = codec->spec;
5918 int i;
5919
5920 for (i = 0; i < AUTO_PIN_LAST; i++) {
5921 hda_nid_t nid = spec->autocfg.input_pins[i];
5922 if (nid >= 0x12) {
23f0c048 5923 alc_set_input_pin(codec, nid, i);
e82c025b
TI
5924 if (nid != ALC260_PIN_CD_NID &&
5925 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5926 snd_hda_codec_write(codec, nid, 0,
5927 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
5928 AMP_OUT_MUTE);
5929 }
5930 }
5931}
5932
5933/*
5934 * generic initialization of ADC, input mixers and output mixers
5935 */
5936static struct hda_verb alc260_volume_init_verbs[] = {
5937 /*
5938 * Unmute ADC0-1 and set the default input to mic-in
5939 */
5940 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5941 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5942 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5943 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 5944
df694daa
KY
5945 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5946 * mixer widget
f12ab1e0
TI
5947 * Note: PASD motherboards uses the Line In 2 as the input for
5948 * front panel mic (mic 2)
df694daa
KY
5949 */
5950 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
5951 /* mute analog inputs */
5952 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5953 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5954 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5955 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5956 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5957
5958 /*
5959 * Set up output mixers (0x08 - 0x0a)
5960 */
5961 /* set vol=0 to output mixers */
5962 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5963 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5964 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5965 /* set up input amps for analog loopback */
5966 /* Amp Indices: DAC = 0, mixer = 1 */
5967 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5968 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5969 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5970 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5971 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5972 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 5973
df694daa
KY
5974 { }
5975};
5976
5977static int alc260_parse_auto_config(struct hda_codec *codec)
5978{
5979 struct alc_spec *spec = codec->spec;
df694daa
KY
5980 int err;
5981 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5982
f12ab1e0
TI
5983 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5984 alc260_ignore);
5985 if (err < 0)
df694daa 5986 return err;
f12ab1e0
TI
5987 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5988 if (err < 0)
4a471b7d 5989 return err;
603c4019 5990 if (!spec->kctls.list)
df694daa 5991 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
5992 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5993 if (err < 0)
df694daa
KY
5994 return err;
5995
5996 spec->multiout.max_channels = 2;
5997
0852d7a6 5998 if (spec->autocfg.dig_outs)
df694daa 5999 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 6000 if (spec->kctls.list)
d88897ea 6001 add_mixer(spec, spec->kctls.list);
df694daa 6002
d88897ea 6003 add_verb(spec, alc260_volume_init_verbs);
df694daa 6004
a1e8d2da 6005 spec->num_mux_defs = 1;
61b9b9b1 6006 spec->input_mux = &spec->private_imux[0];
df694daa 6007
4a79ba34
TI
6008 alc_ssid_check(codec, 0x10, 0x15, 0x0f);
6009
df694daa
KY
6010 return 1;
6011}
6012
ae6b813a
TI
6013/* additional initialization for auto-configuration model */
6014static void alc260_auto_init(struct hda_codec *codec)
df694daa 6015{
f6c7e546 6016 struct alc_spec *spec = codec->spec;
df694daa
KY
6017 alc260_auto_init_multi_out(codec);
6018 alc260_auto_init_analog_input(codec);
f6c7e546 6019 if (spec->unsol_event)
7fb0d78f 6020 alc_inithook(codec);
df694daa
KY
6021}
6022
cb53c626
TI
6023#ifdef CONFIG_SND_HDA_POWER_SAVE
6024static struct hda_amp_list alc260_loopbacks[] = {
6025 { 0x07, HDA_INPUT, 0 },
6026 { 0x07, HDA_INPUT, 1 },
6027 { 0x07, HDA_INPUT, 2 },
6028 { 0x07, HDA_INPUT, 3 },
6029 { 0x07, HDA_INPUT, 4 },
6030 { } /* end */
6031};
6032#endif
6033
df694daa
KY
6034/*
6035 * ALC260 configurations
6036 */
f5fcc13c
TI
6037static const char *alc260_models[ALC260_MODEL_LAST] = {
6038 [ALC260_BASIC] = "basic",
6039 [ALC260_HP] = "hp",
6040 [ALC260_HP_3013] = "hp-3013",
2922c9af 6041 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
6042 [ALC260_FUJITSU_S702X] = "fujitsu",
6043 [ALC260_ACER] = "acer",
bc9f98a9
KY
6044 [ALC260_WILL] = "will",
6045 [ALC260_REPLACER_672V] = "replacer",
cc959489 6046 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 6047#ifdef CONFIG_SND_DEBUG
f5fcc13c 6048 [ALC260_TEST] = "test",
7cf51e48 6049#endif
f5fcc13c
TI
6050 [ALC260_AUTO] = "auto",
6051};
6052
6053static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 6054 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
f5fcc13c 6055 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 6056 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 6057 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
a8a5d067 6058 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
f5fcc13c 6059 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 6060 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 6061 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
6062 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6063 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6064 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6065 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6066 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6067 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6068 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6069 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6070 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 6071 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 6072 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
6073 {}
6074};
6075
6076static struct alc_config_preset alc260_presets[] = {
6077 [ALC260_BASIC] = {
6078 .mixers = { alc260_base_output_mixer,
45bdd1c1 6079 alc260_input_mixer },
df694daa
KY
6080 .init_verbs = { alc260_init_verbs },
6081 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6082 .dac_nids = alc260_dac_nids,
f9e336f6 6083 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
df694daa
KY
6084 .adc_nids = alc260_adc_nids,
6085 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6086 .channel_mode = alc260_modes,
6087 .input_mux = &alc260_capture_source,
6088 },
6089 [ALC260_HP] = {
bec15c3a 6090 .mixers = { alc260_hp_output_mixer,
f9e336f6 6091 alc260_input_mixer },
bec15c3a
TI
6092 .init_verbs = { alc260_init_verbs,
6093 alc260_hp_unsol_verbs },
df694daa
KY
6094 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6095 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6096 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6097 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6098 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6099 .channel_mode = alc260_modes,
6100 .input_mux = &alc260_capture_source,
bec15c3a
TI
6101 .unsol_event = alc260_hp_unsol_event,
6102 .init_hook = alc260_hp_automute,
df694daa 6103 },
3f878308
KY
6104 [ALC260_HP_DC7600] = {
6105 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 6106 alc260_input_mixer },
3f878308
KY
6107 .init_verbs = { alc260_init_verbs,
6108 alc260_hp_dc7600_verbs },
6109 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6110 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6111 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6112 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
6113 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6114 .channel_mode = alc260_modes,
6115 .input_mux = &alc260_capture_source,
6116 .unsol_event = alc260_hp_3012_unsol_event,
6117 .init_hook = alc260_hp_3012_automute,
6118 },
df694daa
KY
6119 [ALC260_HP_3013] = {
6120 .mixers = { alc260_hp_3013_mixer,
f9e336f6 6121 alc260_input_mixer },
bec15c3a
TI
6122 .init_verbs = { alc260_hp_3013_init_verbs,
6123 alc260_hp_3013_unsol_verbs },
df694daa
KY
6124 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6125 .dac_nids = alc260_dac_nids,
f9e336f6
TI
6126 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6127 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
6128 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6129 .channel_mode = alc260_modes,
6130 .input_mux = &alc260_capture_source,
bec15c3a
TI
6131 .unsol_event = alc260_hp_3013_unsol_event,
6132 .init_hook = alc260_hp_3013_automute,
df694daa
KY
6133 },
6134 [ALC260_FUJITSU_S702X] = {
f9e336f6 6135 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
6136 .init_verbs = { alc260_fujitsu_init_verbs },
6137 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6138 .dac_nids = alc260_dac_nids,
d57fdac0
JW
6139 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6140 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
6141 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6142 .channel_mode = alc260_modes,
a1e8d2da
JW
6143 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6144 .input_mux = alc260_fujitsu_capture_sources,
df694daa 6145 },
0bfc90e9 6146 [ALC260_ACER] = {
f9e336f6 6147 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
6148 .init_verbs = { alc260_acer_init_verbs },
6149 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6150 .dac_nids = alc260_dac_nids,
6151 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6152 .adc_nids = alc260_dual_adc_nids,
6153 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6154 .channel_mode = alc260_modes,
a1e8d2da
JW
6155 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6156 .input_mux = alc260_acer_capture_sources,
0bfc90e9 6157 },
cc959489
MS
6158 [ALC260_FAVORIT100] = {
6159 .mixers = { alc260_favorit100_mixer },
6160 .init_verbs = { alc260_favorit100_init_verbs },
6161 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6162 .dac_nids = alc260_dac_nids,
6163 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6164 .adc_nids = alc260_dual_adc_nids,
6165 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6166 .channel_mode = alc260_modes,
6167 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6168 .input_mux = alc260_favorit100_capture_sources,
6169 },
bc9f98a9 6170 [ALC260_WILL] = {
f9e336f6 6171 .mixers = { alc260_will_mixer },
bc9f98a9
KY
6172 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6173 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6174 .dac_nids = alc260_dac_nids,
6175 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6176 .adc_nids = alc260_adc_nids,
6177 .dig_out_nid = ALC260_DIGOUT_NID,
6178 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6179 .channel_mode = alc260_modes,
6180 .input_mux = &alc260_capture_source,
6181 },
6182 [ALC260_REPLACER_672V] = {
f9e336f6 6183 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
6184 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6185 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6186 .dac_nids = alc260_dac_nids,
6187 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6188 .adc_nids = alc260_adc_nids,
6189 .dig_out_nid = ALC260_DIGOUT_NID,
6190 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6191 .channel_mode = alc260_modes,
6192 .input_mux = &alc260_capture_source,
6193 .unsol_event = alc260_replacer_672v_unsol_event,
6194 .init_hook = alc260_replacer_672v_automute,
6195 },
7cf51e48
JW
6196#ifdef CONFIG_SND_DEBUG
6197 [ALC260_TEST] = {
f9e336f6 6198 .mixers = { alc260_test_mixer },
7cf51e48
JW
6199 .init_verbs = { alc260_test_init_verbs },
6200 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6201 .dac_nids = alc260_test_dac_nids,
6202 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6203 .adc_nids = alc260_test_adc_nids,
6204 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6205 .channel_mode = alc260_modes,
a1e8d2da
JW
6206 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6207 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
6208 },
6209#endif
df694daa
KY
6210};
6211
6212static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
6213{
6214 struct alc_spec *spec;
df694daa 6215 int err, board_config;
1da177e4 6216
e560d8d8 6217 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
6218 if (spec == NULL)
6219 return -ENOMEM;
6220
6221 codec->spec = spec;
6222
f5fcc13c
TI
6223 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6224 alc260_models,
6225 alc260_cfg_tbl);
6226 if (board_config < 0) {
6c627f39
TI
6227 snd_printd(KERN_INFO "hda_codec: Unknown model for %s, "
6228 "trying auto-probe from BIOS...\n",
6229 codec->chip_name);
df694daa 6230 board_config = ALC260_AUTO;
16ded525 6231 }
1da177e4 6232
df694daa
KY
6233 if (board_config == ALC260_AUTO) {
6234 /* automatic parse from the BIOS config */
6235 err = alc260_parse_auto_config(codec);
6236 if (err < 0) {
6237 alc_free(codec);
6238 return err;
f12ab1e0 6239 } else if (!err) {
9c7f852e
TI
6240 printk(KERN_INFO
6241 "hda_codec: Cannot set up configuration "
6242 "from BIOS. Using base mode...\n");
df694daa
KY
6243 board_config = ALC260_BASIC;
6244 }
a9430dd8 6245 }
e9edcee0 6246
680cd536
KK
6247 err = snd_hda_attach_beep_device(codec, 0x1);
6248 if (err < 0) {
6249 alc_free(codec);
6250 return err;
6251 }
6252
df694daa
KY
6253 if (board_config != ALC260_AUTO)
6254 setup_preset(spec, &alc260_presets[board_config]);
1da177e4 6255
1da177e4
LT
6256 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6257 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6258
a3bcba38
TI
6259 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6260 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6261
4ef0ef19
TI
6262 if (!spec->adc_nids && spec->input_mux) {
6263 /* check whether NID 0x04 is valid */
6264 unsigned int wcap = get_wcaps(codec, 0x04);
6265 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6266 /* get type */
6267 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6268 spec->adc_nids = alc260_adc_nids_alt;
6269 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6270 } else {
6271 spec->adc_nids = alc260_adc_nids;
6272 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6273 }
6274 }
f9e336f6 6275 set_capture_mixer(spec);
45bdd1c1 6276 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 6277
2134ea4f
TI
6278 spec->vmaster_nid = 0x08;
6279
1da177e4 6280 codec->patch_ops = alc_patch_ops;
df694daa 6281 if (board_config == ALC260_AUTO)
ae6b813a 6282 spec->init_hook = alc260_auto_init;
cb53c626
TI
6283#ifdef CONFIG_SND_HDA_POWER_SAVE
6284 if (!spec->loopback.amplist)
6285 spec->loopback.amplist = alc260_loopbacks;
6286#endif
daead538 6287 codec->proc_widget_hook = print_realtek_coef;
1da177e4
LT
6288
6289 return 0;
6290}
6291
e9edcee0 6292
1da177e4 6293/*
4953550a 6294 * ALC882/883/885/888/889 support
1da177e4
LT
6295 *
6296 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6297 * configuration. Each pin widget can choose any input DACs and a mixer.
6298 * Each ADC is connected from a mixer of all inputs. This makes possible
6299 * 6-channel independent captures.
6300 *
6301 * In addition, an independent DAC for the multi-playback (not used in this
6302 * driver yet).
6303 */
df694daa
KY
6304#define ALC882_DIGOUT_NID 0x06
6305#define ALC882_DIGIN_NID 0x0a
4953550a
TI
6306#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
6307#define ALC883_DIGIN_NID ALC882_DIGIN_NID
6308#define ALC1200_DIGOUT_NID 0x10
6309
1da177e4 6310
d2a6d7dc 6311static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
6312 { 8, NULL }
6313};
6314
4953550a 6315/* DACs */
1da177e4
LT
6316static hda_nid_t alc882_dac_nids[4] = {
6317 /* front, rear, clfe, rear_surr */
6318 0x02, 0x03, 0x04, 0x05
6319};
4953550a 6320#define alc883_dac_nids alc882_dac_nids
1da177e4 6321
4953550a 6322/* ADCs */
df694daa
KY
6323#define alc882_adc_nids alc880_adc_nids
6324#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a
TI
6325#define alc883_adc_nids alc882_adc_nids_alt
6326static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
6327static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
6328#define alc889_adc_nids alc880_adc_nids
1da177e4 6329
e1406348
TI
6330static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6331static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a
TI
6332#define alc883_capsrc_nids alc882_capsrc_nids_alt
6333static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
6334#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 6335
1da177e4
LT
6336/* input MUX */
6337/* FIXME: should be a matrix-type input source selection */
6338
6339static struct hda_input_mux alc882_capture_source = {
6340 .num_items = 4,
6341 .items = {
6342 { "Mic", 0x0 },
6343 { "Front Mic", 0x1 },
6344 { "Line", 0x2 },
6345 { "CD", 0x4 },
6346 },
6347};
41d5545d 6348
4953550a
TI
6349#define alc883_capture_source alc882_capture_source
6350
41d5545d
KS
6351static struct hda_input_mux mb5_capture_source = {
6352 .num_items = 3,
6353 .items = {
6354 { "Mic", 0x1 },
6355 { "Line", 0x2 },
6356 { "CD", 0x4 },
6357 },
6358};
6359
4953550a
TI
6360static struct hda_input_mux alc883_3stack_6ch_intel = {
6361 .num_items = 4,
6362 .items = {
6363 { "Mic", 0x1 },
6364 { "Front Mic", 0x0 },
6365 { "Line", 0x2 },
6366 { "CD", 0x4 },
6367 },
6368};
6369
6370static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6371 .num_items = 2,
6372 .items = {
6373 { "Mic", 0x1 },
6374 { "Line", 0x2 },
6375 },
6376};
6377
6378static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6379 .num_items = 4,
6380 .items = {
6381 { "Mic", 0x0 },
6382 { "iMic", 0x1 },
6383 { "Line", 0x2 },
6384 { "CD", 0x4 },
6385 },
6386};
6387
6388static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6389 .num_items = 2,
6390 .items = {
6391 { "Mic", 0x0 },
6392 { "Int Mic", 0x1 },
6393 },
6394};
6395
6396static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6397 .num_items = 3,
6398 .items = {
6399 { "Mic", 0x0 },
6400 { "Front Mic", 0x1 },
6401 { "Line", 0x4 },
6402 },
6403};
6404
6405static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6406 .num_items = 2,
6407 .items = {
6408 { "Mic", 0x0 },
6409 { "Line", 0x2 },
6410 },
6411};
6412
6413static struct hda_input_mux alc889A_mb31_capture_source = {
6414 .num_items = 2,
6415 .items = {
6416 { "Mic", 0x0 },
6417 /* Front Mic (0x01) unused */
6418 { "Line", 0x2 },
6419 /* Line 2 (0x03) unused */
6420 /* CD (0x04) unsused? */
6421 },
6422};
6423
6424/*
6425 * 2ch mode
6426 */
6427static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6428 { 2, NULL }
6429};
6430
272a527c
KY
6431/*
6432 * 2ch mode
6433 */
6434static struct hda_verb alc882_3ST_ch2_init[] = {
6435 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6436 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6437 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6438 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6439 { } /* end */
6440};
6441
4953550a
TI
6442/*
6443 * 4ch mode
6444 */
6445static struct hda_verb alc882_3ST_ch4_init[] = {
6446 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6447 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6448 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6449 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6450 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6451 { } /* end */
6452};
6453
272a527c
KY
6454/*
6455 * 6ch mode
6456 */
6457static struct hda_verb alc882_3ST_ch6_init[] = {
6458 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6459 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6460 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6461 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6462 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6463 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6464 { } /* end */
6465};
6466
4953550a 6467static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 6468 { 2, alc882_3ST_ch2_init },
4953550a 6469 { 4, alc882_3ST_ch4_init },
272a527c
KY
6470 { 6, alc882_3ST_ch6_init },
6471};
6472
4953550a
TI
6473#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
6474
df694daa
KY
6475/*
6476 * 6ch mode
6477 */
6478static struct hda_verb alc882_sixstack_ch6_init[] = {
6479 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6480 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6481 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6482 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6483 { } /* end */
6484};
6485
6486/*
6487 * 8ch mode
6488 */
6489static struct hda_verb alc882_sixstack_ch8_init[] = {
6490 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6491 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6492 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6493 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6494 { } /* end */
6495};
6496
6497static struct hda_channel_mode alc882_sixstack_modes[2] = {
6498 { 6, alc882_sixstack_ch6_init },
6499 { 8, alc882_sixstack_ch8_init },
6500};
6501
87350ad0 6502/*
def319f9 6503 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
6504 */
6505
6506/*
6507 * 2ch mode
6508 */
6509static struct hda_verb alc885_mbp_ch2_init[] = {
6510 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6511 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6512 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6513 { } /* end */
6514};
6515
6516/*
6517 * 6ch mode
6518 */
6519static struct hda_verb alc885_mbp_ch6_init[] = {
6520 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6521 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6522 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6523 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6524 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6525 { } /* end */
6526};
6527
6528static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6529 { 2, alc885_mbp_ch2_init },
6530 { 6, alc885_mbp_ch6_init },
6531};
6532
92b9de83
KS
6533/*
6534 * 2ch
6535 * Speakers/Woofer/HP = Front
6536 * LineIn = Input
6537 */
6538static struct hda_verb alc885_mb5_ch2_init[] = {
6539 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6540 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6541 { } /* end */
6542};
6543
6544/*
6545 * 6ch mode
6546 * Speakers/HP = Front
6547 * Woofer = LFE
6548 * LineIn = Surround
6549 */
6550static struct hda_verb alc885_mb5_ch6_init[] = {
6551 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6552 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6553 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6554 { } /* end */
6555};
6556
6557static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
6558 { 2, alc885_mb5_ch2_init },
6559 { 6, alc885_mb5_ch6_init },
6560};
87350ad0 6561
4953550a
TI
6562
6563/*
6564 * 2ch mode
6565 */
6566static struct hda_verb alc883_4ST_ch2_init[] = {
6567 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6568 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6569 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6570 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6571 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6572 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6573 { } /* end */
6574};
6575
6576/*
6577 * 4ch mode
6578 */
6579static struct hda_verb alc883_4ST_ch4_init[] = {
6580 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6581 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6582 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6583 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6584 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6585 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6586 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6587 { } /* end */
6588};
6589
6590/*
6591 * 6ch mode
6592 */
6593static struct hda_verb alc883_4ST_ch6_init[] = {
6594 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6595 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6596 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6597 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6598 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6599 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6600 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6601 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6602 { } /* end */
6603};
6604
6605/*
6606 * 8ch mode
6607 */
6608static struct hda_verb alc883_4ST_ch8_init[] = {
6609 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6610 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6611 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6612 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6613 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6614 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6615 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6616 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6617 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6618 { } /* end */
6619};
6620
6621static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
6622 { 2, alc883_4ST_ch2_init },
6623 { 4, alc883_4ST_ch4_init },
6624 { 6, alc883_4ST_ch6_init },
6625 { 8, alc883_4ST_ch8_init },
6626};
6627
6628
6629/*
6630 * 2ch mode
6631 */
6632static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6633 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6634 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6635 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6636 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6637 { } /* end */
6638};
6639
6640/*
6641 * 4ch mode
6642 */
6643static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6644 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6645 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6646 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6647 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6648 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6649 { } /* end */
6650};
6651
6652/*
6653 * 6ch mode
6654 */
6655static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6656 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6657 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6658 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6659 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6660 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6661 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6662 { } /* end */
6663};
6664
6665static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6666 { 2, alc883_3ST_ch2_intel_init },
6667 { 4, alc883_3ST_ch4_intel_init },
6668 { 6, alc883_3ST_ch6_intel_init },
6669};
6670
6671/*
6672 * 6ch mode
6673 */
6674static struct hda_verb alc883_sixstack_ch6_init[] = {
6675 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6676 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6677 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6678 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6679 { } /* end */
6680};
6681
6682/*
6683 * 8ch mode
6684 */
6685static struct hda_verb alc883_sixstack_ch8_init[] = {
6686 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6687 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6688 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6689 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6690 { } /* end */
6691};
6692
6693static struct hda_channel_mode alc883_sixstack_modes[2] = {
6694 { 6, alc883_sixstack_ch6_init },
6695 { 8, alc883_sixstack_ch8_init },
6696};
6697
6698
1da177e4
LT
6699/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6700 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6701 */
c8b6bf9b 6702static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 6703 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 6704 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 6705 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 6706 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
6707 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6708 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
6709 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6710 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 6711 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 6712 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
6713 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6714 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6715 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6716 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6717 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6718 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6719 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
6720 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6721 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6722 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4 6723 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
6724 { } /* end */
6725};
6726
87350ad0 6727static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
2134ea4f
TI
6728 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6729 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6730 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
6731 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6732 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6733 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
6734 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6735 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 6736 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
6737 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6738 { } /* end */
6739};
41d5545d
KS
6740
6741static struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
6742 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6743 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6744 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6745 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
6746 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
6747 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
6748 HDA_CODEC_VOLUME("HP Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
6749 HDA_BIND_MUTE ("HP Playback Switch", 0x0f, 0x02, HDA_INPUT),
41d5545d
KS
6750 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6751 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6752 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6753 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6754 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
6755 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
6756 { } /* end */
6757};
92b9de83 6758
bdd148a3
KY
6759static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6760 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6761 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6762 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6763 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6764 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6765 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6766 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6767 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6768 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
6769 { } /* end */
6770};
6771
272a527c
KY
6772static struct snd_kcontrol_new alc882_targa_mixer[] = {
6773 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6774 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6775 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6776 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6777 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6778 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6779 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6780 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6781 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 6782 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
6783 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6784 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 6785 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
6786 { } /* end */
6787};
6788
6789/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6790 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6791 */
6792static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
6793 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6794 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6795 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6796 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
6797 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6798 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6799 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6800 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6801 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
6802 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
6803 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6804 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 6805 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
6806 { } /* end */
6807};
6808
914759b7
TI
6809static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
6810 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6811 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6812 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6813 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6814 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6815 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6816 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6817 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6818 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6819 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
6820 { } /* end */
6821};
6822
df694daa
KY
6823static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6824 {
6825 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6826 .name = "Channel Mode",
6827 .info = alc_ch_mode_info,
6828 .get = alc_ch_mode_get,
6829 .put = alc_ch_mode_put,
6830 },
6831 { } /* end */
6832};
6833
4953550a 6834static struct hda_verb alc882_base_init_verbs[] = {
1da177e4 6835 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
6836 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6837 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6838 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 6839 /* Rear mixer */
05acb863
TI
6840 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6841 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6842 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 6843 /* CLFE mixer */
05acb863
TI
6844 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6845 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6846 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 6847 /* Side mixer */
05acb863
TI
6848 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6849 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6850 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 6851
e9edcee0 6852 /* Front Pin: output 0 (0x0c) */
05acb863 6853 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 6854 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 6855 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 6856 /* Rear Pin: output 1 (0x0d) */
05acb863 6857 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 6858 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 6859 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 6860 /* CLFE Pin: output 2 (0x0e) */
05acb863 6861 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 6862 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 6863 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 6864 /* Side Pin: output 3 (0x0f) */
05acb863 6865 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 6866 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 6867 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 6868 /* Mic (rear) pin: input vref at 80% */
16ded525 6869 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
6870 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6871 /* Front Mic pin: input vref at 80% */
16ded525 6872 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
6873 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6874 /* Line In pin: input */
05acb863 6875 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
6876 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6877 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6878 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6879 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6880 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6881 /* CD pin widget for input */
05acb863 6882 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
6883
6884 /* FIXME: use matrix-type input source selection */
6885 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 6886 /* Input mixer2 */
05acb863
TI
6887 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6888 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6889 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6890 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6891 /* Input mixer3 */
05acb863
TI
6892 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6893 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6894 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6895 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
05acb863
TI
6896 /* ADC2: mute amp left and right */
6897 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 6898 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
6899 /* ADC3: mute amp left and right */
6900 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 6901 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
6902
6903 { }
6904};
6905
4953550a
TI
6906static struct hda_verb alc882_adc1_init_verbs[] = {
6907 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6908 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6909 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6910 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6911 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6912 /* ADC1: mute amp left and right */
6913 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6914 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6915 { }
6916};
6917
6918/* HACK - expand to two elements */
6919#define alc882_init_verbs alc882_base_init_verbs, alc882_adc1_init_verbs
6920
4b146cb0
TI
6921static struct hda_verb alc882_eapd_verbs[] = {
6922 /* change to EAPD mode */
6923 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 6924 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 6925 { }
4b146cb0
TI
6926};
6927
4953550a
TI
6928#define alc883_init_verbs alc882_base_init_verbs
6929
9102cd1c
TD
6930/* Mac Pro test */
6931static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6932 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6933 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6934 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6935 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6936 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 6937 /* FIXME: this looks suspicious...
9102cd1c
TD
6938 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6939 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 6940 */
9102cd1c
TD
6941 { } /* end */
6942};
6943
6944static struct hda_verb alc882_macpro_init_verbs[] = {
6945 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6946 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6947 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6948 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6949 /* Front Pin: output 0 (0x0c) */
6950 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6951 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6952 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6953 /* Front Mic pin: input vref at 80% */
6954 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6955 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6956 /* Speaker: output */
6957 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6958 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6959 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6960 /* Headphone output (output 0 - 0x0c) */
6961 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6962 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6963 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6964
6965 /* FIXME: use matrix-type input source selection */
6966 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6967 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6968 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6969 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6970 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6971 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6972 /* Input mixer2 */
6973 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6974 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6975 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6976 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6977 /* Input mixer3 */
6978 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6979 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6980 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6981 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6982 /* ADC1: mute amp left and right */
6983 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6984 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6985 /* ADC2: mute amp left and right */
6986 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6987 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6988 /* ADC3: mute amp left and right */
6989 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6990 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6991
6992 { }
6993};
f12ab1e0 6994
41d5545d
KS
6995/* Macbook 5,1 */
6996static struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
6997 /* DACs */
6998 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6999 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7000 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7001 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 7002 /* Front mixer */
41d5545d
KS
7003 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7004 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7005 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
7006 /* Surround mixer */
7007 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7008 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7009 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7010 /* LFE mixer */
7011 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7012 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7013 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7014 /* HP mixer */
7015 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7016 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7017 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7018 /* Front Pin (0x0c) */
41d5545d
KS
7019 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7020 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
7021 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7022 /* LFE Pin (0x0e) */
7023 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7024 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7025 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7026 /* HP Pin (0x0f) */
41d5545d
KS
7027 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7028 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 7029 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
41d5545d
KS
7030 /* Front Mic pin: input vref at 80% */
7031 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7032 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7033 /* Line In pin */
7034 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7035 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7036
7037 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7038 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7039 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7040 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7041 { }
7042};
7043
87350ad0
TI
7044/* Macbook Pro rev3 */
7045static struct hda_verb alc885_mbp3_init_verbs[] = {
7046 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7047 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7048 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7049 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7050 /* Rear mixer */
7051 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7052 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7053 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7054 /* Front Pin: output 0 (0x0c) */
7055 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7056 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7057 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7058 /* HP Pin: output 0 (0x0d) */
7059 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
7060 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7061 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7062 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7063 /* Mic (rear) pin: input vref at 80% */
7064 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7065 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7066 /* Front Mic pin: input vref at 80% */
7067 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7068 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7069 /* Line In pin: use output 1 when in LineOut mode */
7070 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7071 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7072 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7073
7074 /* FIXME: use matrix-type input source selection */
7075 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7076 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7077 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7078 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7079 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7080 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7081 /* Input mixer2 */
7082 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7083 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7084 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7085 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7086 /* Input mixer3 */
7087 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7088 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7089 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7090 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7091 /* ADC1: mute amp left and right */
7092 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7093 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7094 /* ADC2: mute amp left and right */
7095 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7096 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7097 /* ADC3: mute amp left and right */
7098 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7099 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7100
7101 { }
7102};
7103
c54728d8
NF
7104/* iMac 24 mixer. */
7105static struct snd_kcontrol_new alc885_imac24_mixer[] = {
7106 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7107 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
7108 { } /* end */
7109};
7110
7111/* iMac 24 init verbs. */
7112static struct hda_verb alc885_imac24_init_verbs[] = {
7113 /* Internal speakers: output 0 (0x0c) */
7114 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7115 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7116 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7117 /* Internal speakers: output 0 (0x0c) */
7118 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7119 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7120 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7121 /* Headphone: output 0 (0x0c) */
7122 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7123 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7124 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7125 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7126 /* Front Mic: input vref at 80% */
7127 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7128 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7129 { }
7130};
7131
7132/* Toggle speaker-output according to the hp-jack state */
a9fd4f3f 7133static void alc885_imac24_automute_init_hook(struct hda_codec *codec)
c54728d8 7134{
a9fd4f3f 7135 struct alc_spec *spec = codec->spec;
c54728d8 7136
a9fd4f3f
TI
7137 spec->autocfg.hp_pins[0] = 0x14;
7138 spec->autocfg.speaker_pins[0] = 0x18;
7139 spec->autocfg.speaker_pins[1] = 0x1a;
7140 alc_automute_amp(codec);
c54728d8
NF
7141}
7142
a9fd4f3f 7143static void alc885_mbp3_init_hook(struct hda_codec *codec)
87350ad0 7144{
a9fd4f3f 7145 struct alc_spec *spec = codec->spec;
87350ad0 7146
a9fd4f3f
TI
7147 spec->autocfg.hp_pins[0] = 0x15;
7148 spec->autocfg.speaker_pins[0] = 0x14;
7149 alc_automute_amp(codec);
87350ad0
TI
7150}
7151
7152
272a527c
KY
7153static struct hda_verb alc882_targa_verbs[] = {
7154 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7155 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7156
7157 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7158 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 7159
272a527c
KY
7160 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7161 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7162 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7163
7164 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7165 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7166 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7167 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7168 { } /* end */
7169};
7170
7171/* toggle speaker-output according to the hp-jack state */
7172static void alc882_targa_automute(struct hda_codec *codec)
7173{
a9fd4f3f
TI
7174 struct alc_spec *spec = codec->spec;
7175 alc_automute_amp(codec);
82beb8fd 7176 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
7177 spec->jack_present ? 1 : 3);
7178}
7179
7180static void alc882_targa_init_hook(struct hda_codec *codec)
7181{
7182 struct alc_spec *spec = codec->spec;
7183
7184 spec->autocfg.hp_pins[0] = 0x14;
7185 spec->autocfg.speaker_pins[0] = 0x1b;
7186 alc882_targa_automute(codec);
272a527c
KY
7187}
7188
7189static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
7190{
a9fd4f3f 7191 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 7192 alc882_targa_automute(codec);
272a527c
KY
7193}
7194
7195static struct hda_verb alc882_asus_a7j_verbs[] = {
7196 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7197 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7198
7199 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7200 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7201 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 7202
272a527c
KY
7203 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7204 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7205 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7206
7207 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7208 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7209 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7210 { } /* end */
7211};
7212
914759b7
TI
7213static struct hda_verb alc882_asus_a7m_verbs[] = {
7214 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7215 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7216
7217 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7218 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7219 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 7220
914759b7
TI
7221 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7222 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7223 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7224
7225 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7226 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7227 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7228 { } /* end */
7229};
7230
9102cd1c
TD
7231static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
7232{
7233 unsigned int gpiostate, gpiomask, gpiodir;
7234
7235 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
7236 AC_VERB_GET_GPIO_DATA, 0);
7237
7238 if (!muted)
7239 gpiostate |= (1 << pin);
7240 else
7241 gpiostate &= ~(1 << pin);
7242
7243 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
7244 AC_VERB_GET_GPIO_MASK, 0);
7245 gpiomask |= (1 << pin);
7246
7247 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
7248 AC_VERB_GET_GPIO_DIRECTION, 0);
7249 gpiodir |= (1 << pin);
7250
7251
7252 snd_hda_codec_write(codec, codec->afg, 0,
7253 AC_VERB_SET_GPIO_MASK, gpiomask);
7254 snd_hda_codec_write(codec, codec->afg, 0,
7255 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
7256
7257 msleep(1);
7258
7259 snd_hda_codec_write(codec, codec->afg, 0,
7260 AC_VERB_SET_GPIO_DATA, gpiostate);
7261}
7262
7debbe51
TI
7263/* set up GPIO at initialization */
7264static void alc885_macpro_init_hook(struct hda_codec *codec)
7265{
7266 alc882_gpio_mute(codec, 0, 0);
7267 alc882_gpio_mute(codec, 1, 0);
7268}
7269
7270/* set up GPIO and update auto-muting at initialization */
7271static void alc885_imac24_init_hook(struct hda_codec *codec)
7272{
7273 alc885_macpro_init_hook(codec);
a9fd4f3f 7274 alc885_imac24_automute_init_hook(codec);
7debbe51
TI
7275}
7276
df694daa
KY
7277/*
7278 * generic initialization of ADC, input mixers and output mixers
7279 */
4953550a 7280static struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
7281 /*
7282 * Unmute ADC0-2 and set the default input to mic-in
7283 */
4953550a
TI
7284 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7285 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7286 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7287 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 7288
4953550a
TI
7289 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7290 * mixer widget
7291 * Note: PASD motherboards uses the Line In 2 as the input for
7292 * front panel mic (mic 2)
7293 */
7294 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7295 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7296 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7297 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7298 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7299 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
17bba1b7 7300
4953550a
TI
7301 /*
7302 * Set up output mixers (0x0c - 0x0f)
7303 */
7304 /* set vol=0 to output mixers */
7305 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7306 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7307 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7308 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7309 /* set up input amps for analog loopback */
7310 /* Amp Indices: DAC = 0, mixer = 1 */
7311 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7312 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7313 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7314 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7315 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7316 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7317 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7318 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7319 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7320 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 7321
4953550a
TI
7322 /* FIXME: use matrix-type input source selection */
7323 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7324 /* Input mixer2 */
7325 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7326 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7327 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7328 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7329 /* Input mixer3 */
7330 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7331 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7332 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7333 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9c7f852e 7334
4953550a 7335 { }
9c7f852e
TI
7336};
7337
eb4c41d3
TS
7338/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
7339static struct hda_verb alc889A_mb31_ch2_init[] = {
7340 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7341 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7342 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7343 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7344 { } /* end */
7345};
7346
7347/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
7348static struct hda_verb alc889A_mb31_ch4_init[] = {
7349 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7350 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7351 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7352 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7353 { } /* end */
7354};
7355
7356/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
7357static struct hda_verb alc889A_mb31_ch5_init[] = {
7358 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
7359 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7360 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7361 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7362 { } /* end */
7363};
7364
7365/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
7366static struct hda_verb alc889A_mb31_ch6_init[] = {
7367 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
7368 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
7369 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7370 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7371 { } /* end */
7372};
7373
7374static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
7375 { 2, alc889A_mb31_ch2_init },
7376 { 4, alc889A_mb31_ch4_init },
7377 { 5, alc889A_mb31_ch5_init },
7378 { 6, alc889A_mb31_ch6_init },
7379};
7380
b373bdeb
AN
7381static struct hda_verb alc883_medion_eapd_verbs[] = {
7382 /* eanable EAPD on medion laptop */
7383 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7384 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7385 { }
7386};
7387
4953550a 7388#define alc883_base_mixer alc882_base_mixer
834be88d 7389
a8848bd6
AS
7390static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7391 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7392 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7393 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7394 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7395 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7396 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7397 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7398 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7399 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7400 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7401 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7402 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7403 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
7404 { } /* end */
7405};
7406
0c4cc443 7407static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
7408 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7409 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7410 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7411 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7412 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7413 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7414 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7415 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7416 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7417 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
7418 { } /* end */
7419};
7420
fb97dc67
J
7421static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7422 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7423 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7424 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7425 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7426 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7427 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7428 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7429 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7430 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7431 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
7432 { } /* end */
7433};
7434
9c7f852e
TI
7435static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7436 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7437 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7438 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7439 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7440 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7441 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7442 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7443 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7444 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
7445 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7446 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7447 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 7448 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
7449 { } /* end */
7450};
df694daa 7451
9c7f852e
TI
7452static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7453 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7454 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7455 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7456 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7457 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7458 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7459 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7460 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7461 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7462 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7463 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7464 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7465 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7466 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7467 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
7468 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7469 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7470 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 7471 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
7472 { } /* end */
7473};
7474
17bba1b7
J
7475static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7476 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7477 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7478 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7479 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7480 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7481 HDA_OUTPUT),
7482 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7483 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7484 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7485 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7486 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7487 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7488 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7489 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7490 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7491 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7492 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7493 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7494 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7495 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
7496 { } /* end */
7497};
7498
d1d985f0 7499static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 7500 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 7501 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 7502 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 7503 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
7504 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7505 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
7506 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7507 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
7508 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7509 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7510 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7511 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7512 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7513 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7514 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
7515 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7516 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7517 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8 7518 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
7519 { } /* end */
7520};
7521
c259249f 7522static struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce
KY
7523 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7524 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7525 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7526 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7527 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7528 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7529 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7530 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7531 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7532 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7533 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7534 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7535 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7536 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7537 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 7538 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 7539 { } /* end */
f12ab1e0 7540};
ccc656ce 7541
c259249f 7542static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce
KY
7543 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7544 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7545 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7546 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7547 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7548 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7549 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 7550 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
7551 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7552 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7553 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 7554 { } /* end */
f12ab1e0 7555};
ccc656ce 7556
bc9f98a9
KY
7557static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7558 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7559 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
7560 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7561 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
7562 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7563 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7564 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7565 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 7566 { } /* end */
f12ab1e0 7567};
bc9f98a9 7568
272a527c
KY
7569static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7570 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7571 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7572 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7573 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7574 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7575 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7576 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7577 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7578 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
7579 { } /* end */
7580};
7581
7582static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7583 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7584 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7585 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7586 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7587 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7588 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7589 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7590 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7591 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
272a527c 7592 { } /* end */
ea1fb29a 7593};
272a527c 7594
2880a867 7595static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
7596 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7597 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 7598 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
7599 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7600 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
7601 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7602 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7603 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 7604 { } /* end */
d1a991a6 7605};
2880a867 7606
d2fd4b09
TV
7607static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
7608 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7609 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7610 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7611 HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT),
684a8842
TV
7612 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7613 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
7614 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7615 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7616 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7617 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7618 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7619 { } /* end */
7620};
7621
e2757d5e
KY
7622static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7623 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7624 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7625 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7626 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7627 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7628 0x0d, 1, 0x0, HDA_OUTPUT),
7629 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7630 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7631 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7632 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7633 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
7634 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7635 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7636 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7637 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7638 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7639 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7640 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7641 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7642 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7643 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
7644 { } /* end */
7645};
7646
eb4c41d3
TS
7647static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
7648 /* Output mixers */
7649 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7650 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7651 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7652 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7653 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
7654 HDA_OUTPUT),
7655 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
7656 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
7657 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
7658 /* Output switches */
7659 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
7660 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
7661 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
7662 /* Boost mixers */
7663 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7664 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
7665 /* Input mixers */
7666 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7667 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7668 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7669 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7670 { } /* end */
7671};
7672
3e1647c5
GG
7673static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
7674 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7675 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7676 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7677 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7678 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7679 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7680 { } /* end */
7681};
7682
e2757d5e
KY
7683static struct hda_bind_ctls alc883_bind_cap_vol = {
7684 .ops = &snd_hda_bind_vol,
7685 .values = {
7686 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7687 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7688 0
7689 },
7690};
7691
7692static struct hda_bind_ctls alc883_bind_cap_switch = {
7693 .ops = &snd_hda_bind_sw,
7694 .values = {
7695 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7696 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7697 0
7698 },
7699};
7700
7701static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7702 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7703 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7704 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7705 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7706 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4953550a
TI
7708 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7709 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7710 { } /* end */
7711};
df694daa 7712
4953550a
TI
7713static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
7714 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7715 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7716 {
7717 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7718 /* .name = "Capture Source", */
7719 .name = "Input Source",
7720 .count = 1,
7721 .info = alc_mux_enum_info,
7722 .get = alc_mux_enum_get,
7723 .put = alc_mux_enum_put,
7724 },
7725 { } /* end */
7726};
9c7f852e 7727
4953550a
TI
7728static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7729 {
7730 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7731 .name = "Channel Mode",
7732 .info = alc_ch_mode_info,
7733 .get = alc_ch_mode_get,
7734 .put = alc_ch_mode_put,
7735 },
7736 { } /* end */
9c7f852e
TI
7737};
7738
a8848bd6 7739/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 7740static void alc883_mitac_init_hook(struct hda_codec *codec)
a8848bd6 7741{
a9fd4f3f 7742 struct alc_spec *spec = codec->spec;
a8848bd6 7743
a9fd4f3f
TI
7744 spec->autocfg.hp_pins[0] = 0x15;
7745 spec->autocfg.speaker_pins[0] = 0x14;
7746 spec->autocfg.speaker_pins[1] = 0x17;
7747 alc_automute_amp(codec);
a8848bd6
AS
7748}
7749
7750/* auto-toggle front mic */
7751/*
7752static void alc883_mitac_mic_automute(struct hda_codec *codec)
7753{
7754 unsigned int present;
7755 unsigned char bits;
7756
7757 present = snd_hda_codec_read(codec, 0x18, 0,
7758 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7759 bits = present ? HDA_AMP_MUTE : 0;
7760 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7761}
7762*/
7763
a8848bd6
AS
7764static struct hda_verb alc883_mitac_verbs[] = {
7765 /* HP */
7766 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7767 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7768 /* Subwoofer */
7769 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7770 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7771
7772 /* enable unsolicited event */
7773 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7774 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7775
7776 { } /* end */
7777};
7778
0c4cc443 7779static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
7780 /* HP */
7781 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7782 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7783 /* Int speaker */
7784 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7785 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7786
7787 /* enable unsolicited event */
7788 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 7789 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
7790
7791 { } /* end */
7792};
7793
fb97dc67
J
7794static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7795 /* HP */
7796 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7797 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7798 /* Subwoofer */
7799 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7800 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7801
7802 /* enable unsolicited event */
7803 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7804
7805 { } /* end */
7806};
7807
c259249f 7808static struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
7809 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7810 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7811
7812 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7813 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 7814
64a8be74
DH
7815/* Connect Line-Out side jack (SPDIF) to Side */
7816 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7817 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7818 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7819/* Connect Mic jack to CLFE */
7820 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7821 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7822 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
7823/* Connect Line-in jack to Surround */
7824 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7825 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7826 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7827/* Connect HP out jack to Front */
7828 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7829 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7830 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
7831
7832 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
7833
7834 { } /* end */
7835};
7836
bc9f98a9
KY
7837static struct hda_verb alc883_lenovo_101e_verbs[] = {
7838 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7839 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7840 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7841 { } /* end */
7842};
7843
272a527c
KY
7844static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7845 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7846 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7847 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7848 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7849 { } /* end */
7850};
7851
7852static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7853 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7854 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7855 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7856 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7857 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7858 { } /* end */
7859};
7860
189609ae
KY
7861static struct hda_verb alc883_haier_w66_verbs[] = {
7862 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7863 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7864
7865 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7866
7867 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7868 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7869 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7870 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7871 { } /* end */
7872};
7873
e2757d5e
KY
7874static struct hda_verb alc888_lenovo_sky_verbs[] = {
7875 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7876 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7877 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7878 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7879 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7880 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7881 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7882 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7883 { } /* end */
7884};
7885
8718b700
HRK
7886static struct hda_verb alc888_6st_dell_verbs[] = {
7887 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7888 { }
7889};
7890
3e1647c5
GG
7891static struct hda_verb alc883_vaiott_verbs[] = {
7892 /* HP */
7893 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7894 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7895
7896 /* enable unsolicited event */
7897 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7898
7899 { } /* end */
7900};
7901
a9fd4f3f 7902static void alc888_3st_hp_init_hook(struct hda_codec *codec)
8718b700 7903{
a9fd4f3f 7904 struct alc_spec *spec = codec->spec;
8718b700 7905
a9fd4f3f
TI
7906 spec->autocfg.hp_pins[0] = 0x1b;
7907 spec->autocfg.speaker_pins[0] = 0x14;
7908 spec->autocfg.speaker_pins[1] = 0x16;
7909 spec->autocfg.speaker_pins[2] = 0x18;
7910 alc_automute_amp(codec);
8718b700
HRK
7911}
7912
4723c022 7913static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 7914 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
7915 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7916 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 7917 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 7918 { } /* end */
5795b9e6
CM
7919};
7920
3ea0d7cf
HRK
7921/*
7922 * 2ch mode
7923 */
4723c022 7924static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
7925 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7926 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7927 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7928 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 7929 { } /* end */
8341de60
CM
7930};
7931
3ea0d7cf
HRK
7932/*
7933 * 4ch mode
7934 */
7935static struct hda_verb alc888_3st_hp_4ch_init[] = {
7936 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7937 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7938 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7939 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7940 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
7941 { } /* end */
7942};
7943
7944/*
7945 * 6ch mode
7946 */
4723c022 7947static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
7948 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7949 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 7950 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
7951 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7952 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
7953 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
7954 { } /* end */
8341de60
CM
7955};
7956
3ea0d7cf 7957static struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 7958 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 7959 { 4, alc888_3st_hp_4ch_init },
4723c022 7960 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
7961};
7962
272a527c
KY
7963/* toggle front-jack and RCA according to the hp-jack state */
7964static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7965{
7966 unsigned int present;
ea1fb29a 7967
272a527c
KY
7968 present = snd_hda_codec_read(codec, 0x1b, 0,
7969 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7970 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7971 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7972 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7973 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
7974}
7975
7976/* toggle RCA according to the front-jack state */
7977static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7978{
7979 unsigned int present;
ea1fb29a 7980
272a527c
KY
7981 present = snd_hda_codec_read(codec, 0x14, 0,
7982 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7983 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7984 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 7985}
47fd830a 7986
272a527c
KY
7987static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7988 unsigned int res)
7989{
7990 if ((res >> 26) == ALC880_HP_EVENT)
7991 alc888_lenovo_ms7195_front_automute(codec);
7992 if ((res >> 26) == ALC880_FRONT_EVENT)
7993 alc888_lenovo_ms7195_rca_automute(codec);
7994}
7995
7996static struct hda_verb alc883_medion_md2_verbs[] = {
7997 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7998 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7999
8000 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8001
8002 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8003 { } /* end */
8004};
8005
8006/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 8007static void alc883_medion_md2_init_hook(struct hda_codec *codec)
272a527c 8008{
a9fd4f3f 8009 struct alc_spec *spec = codec->spec;
272a527c 8010
a9fd4f3f
TI
8011 spec->autocfg.hp_pins[0] = 0x14;
8012 spec->autocfg.speaker_pins[0] = 0x15;
8013 alc_automute_amp(codec);
272a527c
KY
8014}
8015
ccc656ce 8016/* toggle speaker-output according to the hp-jack state */
c259249f
SA
8017#define alc883_targa_init_hook alc882_targa_init_hook
8018#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 8019
0c4cc443
HRK
8020static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8021{
8022 unsigned int present;
8023
8024 present = snd_hda_codec_read(codec, 0x18, 0,
8025 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8026 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8027 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8028}
8029
a9fd4f3f 8030static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
0c4cc443 8031{
a9fd4f3f
TI
8032 struct alc_spec *spec = codec->spec;
8033
8034 spec->autocfg.hp_pins[0] = 0x15;
8035 spec->autocfg.speaker_pins[0] = 0x14;
8036 alc_automute_amp(codec);
0c4cc443
HRK
8037 alc883_clevo_m720_mic_automute(codec);
8038}
8039
8040static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
8041 unsigned int res)
8042{
0c4cc443 8043 switch (res >> 26) {
0c4cc443
HRK
8044 case ALC880_MIC_EVENT:
8045 alc883_clevo_m720_mic_automute(codec);
8046 break;
a9fd4f3f
TI
8047 default:
8048 alc_automute_amp_unsol_event(codec, res);
8049 break;
0c4cc443 8050 }
368c7a95
J
8051}
8052
fb97dc67 8053/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 8054static void alc883_2ch_fujitsu_pi2515_init_hook(struct hda_codec *codec)
fb97dc67 8055{
a9fd4f3f 8056 struct alc_spec *spec = codec->spec;
fb97dc67 8057
a9fd4f3f
TI
8058 spec->autocfg.hp_pins[0] = 0x14;
8059 spec->autocfg.speaker_pins[0] = 0x15;
8060 alc_automute_amp(codec);
fb97dc67
J
8061}
8062
a9fd4f3f 8063static void alc883_haier_w66_init_hook(struct hda_codec *codec)
fb97dc67 8064{
a9fd4f3f 8065 struct alc_spec *spec = codec->spec;
189609ae 8066
a9fd4f3f
TI
8067 spec->autocfg.hp_pins[0] = 0x1b;
8068 spec->autocfg.speaker_pins[0] = 0x14;
8069 alc_automute_amp(codec);
189609ae
KY
8070}
8071
bc9f98a9
KY
8072static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8073{
8074 unsigned int present;
f12ab1e0 8075 unsigned char bits;
bc9f98a9 8076
64a8be74
DH
8077 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8078 & AC_PINSENSE_PRESENCE;
47fd830a
TI
8079 bits = present ? HDA_AMP_MUTE : 0;
8080 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8081 HDA_AMP_MUTE, bits);
bc9f98a9
KY
8082}
8083
8084static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8085{
8086 unsigned int present;
f12ab1e0 8087 unsigned char bits;
bc9f98a9
KY
8088
8089 present = snd_hda_codec_read(codec, 0x1b, 0,
8090 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8091 bits = present ? HDA_AMP_MUTE : 0;
8092 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8093 HDA_AMP_MUTE, bits);
8094 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8095 HDA_AMP_MUTE, bits);
bc9f98a9
KY
8096}
8097
8098static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8099 unsigned int res)
8100{
8101 if ((res >> 26) == ALC880_HP_EVENT)
8102 alc883_lenovo_101e_all_automute(codec);
8103 if ((res >> 26) == ALC880_FRONT_EVENT)
8104 alc883_lenovo_101e_ispeaker_automute(codec);
8105}
8106
676a9b53 8107/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 8108static void alc883_acer_aspire_init_hook(struct hda_codec *codec)
676a9b53 8109{
a9fd4f3f 8110 struct alc_spec *spec = codec->spec;
676a9b53 8111
a9fd4f3f
TI
8112 spec->autocfg.hp_pins[0] = 0x14;
8113 spec->autocfg.speaker_pins[0] = 0x15;
8114 spec->autocfg.speaker_pins[1] = 0x16;
8115 alc_automute_amp(codec);
676a9b53
TI
8116}
8117
d1a991a6
KY
8118static struct hda_verb alc883_acer_eapd_verbs[] = {
8119 /* HP Pin: output 0 (0x0c) */
8120 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8121 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8122 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8123 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
8124 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8125 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 8126 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
8127 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8128 /* eanable EAPD on medion laptop */
8129 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8130 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
8131 /* enable unsolicited event */
8132 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
8133 { }
8134};
8135
a9fd4f3f 8136static void alc888_6st_dell_init_hook(struct hda_codec *codec)
5795b9e6 8137{
a9fd4f3f 8138 struct alc_spec *spec = codec->spec;
5795b9e6 8139
a9fd4f3f
TI
8140 spec->autocfg.hp_pins[0] = 0x1b;
8141 spec->autocfg.speaker_pins[0] = 0x14;
8142 spec->autocfg.speaker_pins[1] = 0x15;
8143 spec->autocfg.speaker_pins[2] = 0x16;
8144 spec->autocfg.speaker_pins[3] = 0x17;
8145 alc_automute_amp(codec);
5795b9e6
CM
8146}
8147
a9fd4f3f 8148static void alc888_lenovo_sky_init_hook(struct hda_codec *codec)
e2757d5e 8149{
a9fd4f3f 8150 struct alc_spec *spec = codec->spec;
e2757d5e 8151
a9fd4f3f
TI
8152 spec->autocfg.hp_pins[0] = 0x1b;
8153 spec->autocfg.speaker_pins[0] = 0x14;
8154 spec->autocfg.speaker_pins[1] = 0x15;
8155 spec->autocfg.speaker_pins[2] = 0x16;
8156 spec->autocfg.speaker_pins[3] = 0x17;
8157 spec->autocfg.speaker_pins[4] = 0x1a;
8158 alc_automute_amp(codec);
e2757d5e
KY
8159}
8160
3e1647c5
GG
8161static void alc883_vaiott_init_hook(struct hda_codec *codec)
8162{
8163 struct alc_spec *spec = codec->spec;
8164
8165 spec->autocfg.hp_pins[0] = 0x15;
8166 spec->autocfg.speaker_pins[0] = 0x14;
8167 spec->autocfg.speaker_pins[1] = 0x17;
8168 alc_automute_amp(codec);
8169}
8170
e2757d5e
KY
8171static struct hda_verb alc888_asus_m90v_verbs[] = {
8172 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8173 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8174 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8175 /* enable unsolicited event */
8176 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8177 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8178 { } /* end */
8179};
8180
8181static void alc883_nb_mic_automute(struct hda_codec *codec)
8182{
8183 unsigned int present;
8184
8185 present = snd_hda_codec_read(codec, 0x18, 0,
8186 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8187 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8188 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8189 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8190 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8191}
8192
a9fd4f3f 8193static void alc883_M90V_init_hook(struct hda_codec *codec)
e2757d5e 8194{
a9fd4f3f 8195 struct alc_spec *spec = codec->spec;
e2757d5e 8196
a9fd4f3f
TI
8197 spec->autocfg.hp_pins[0] = 0x1b;
8198 spec->autocfg.speaker_pins[0] = 0x14;
8199 spec->autocfg.speaker_pins[1] = 0x15;
8200 spec->autocfg.speaker_pins[2] = 0x16;
8201 alc_automute_pin(codec);
e2757d5e
KY
8202}
8203
8204static void alc883_mode2_unsol_event(struct hda_codec *codec,
8205 unsigned int res)
8206{
8207 switch (res >> 26) {
e2757d5e
KY
8208 case ALC880_MIC_EVENT:
8209 alc883_nb_mic_automute(codec);
8210 break;
a9fd4f3f
TI
8211 default:
8212 alc_sku_unsol_event(codec, res);
8213 break;
e2757d5e
KY
8214 }
8215}
8216
8217static void alc883_mode2_inithook(struct hda_codec *codec)
8218{
a9fd4f3f 8219 alc883_M90V_init_hook(codec);
e2757d5e
KY
8220 alc883_nb_mic_automute(codec);
8221}
8222
8223static struct hda_verb alc888_asus_eee1601_verbs[] = {
8224 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8225 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8226 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8227 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8228 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8229 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8230 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8231 /* enable unsolicited event */
8232 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8233 { } /* end */
8234};
8235
e2757d5e
KY
8236static void alc883_eee1601_inithook(struct hda_codec *codec)
8237{
a9fd4f3f
TI
8238 struct alc_spec *spec = codec->spec;
8239
8240 spec->autocfg.hp_pins[0] = 0x14;
8241 spec->autocfg.speaker_pins[0] = 0x1b;
8242 alc_automute_pin(codec);
e2757d5e
KY
8243}
8244
eb4c41d3
TS
8245static struct hda_verb alc889A_mb31_verbs[] = {
8246 /* Init rear pin (used as headphone output) */
8247 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
8248 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
8249 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8250 /* Init line pin (used as output in 4ch and 6ch mode) */
8251 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
8252 /* Init line 2 pin (used as headphone out by default) */
8253 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
8254 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
8255 { } /* end */
8256};
8257
8258/* Mute speakers according to the headphone jack state */
8259static void alc889A_mb31_automute(struct hda_codec *codec)
8260{
8261 unsigned int present;
8262
8263 /* Mute only in 2ch or 4ch mode */
8264 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
8265 == 0x00) {
8266 present = snd_hda_codec_read(codec, 0x15, 0,
8267 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
8268 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8269 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8270 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8271 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8272 }
8273}
8274
8275static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
8276{
8277 if ((res >> 26) == ALC880_HP_EVENT)
8278 alc889A_mb31_automute(codec);
8279}
8280
4953550a 8281
cb53c626 8282#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 8283#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
8284#endif
8285
def319f9 8286/* pcm configuration: identical with ALC880 */
4953550a
TI
8287#define alc882_pcm_analog_playback alc880_pcm_analog_playback
8288#define alc882_pcm_analog_capture alc880_pcm_analog_capture
8289#define alc882_pcm_digital_playback alc880_pcm_digital_playback
8290#define alc882_pcm_digital_capture alc880_pcm_digital_capture
8291
8292static hda_nid_t alc883_slave_dig_outs[] = {
8293 ALC1200_DIGOUT_NID, 0,
8294};
8295
8296static hda_nid_t alc1200_slave_dig_outs[] = {
8297 ALC883_DIGOUT_NID, 0,
8298};
9c7f852e
TI
8299
8300/*
8301 * configuration and preset
8302 */
4953550a
TI
8303static const char *alc882_models[ALC882_MODEL_LAST] = {
8304 [ALC882_3ST_DIG] = "3stack-dig",
8305 [ALC882_6ST_DIG] = "6stack-dig",
8306 [ALC882_ARIMA] = "arima",
8307 [ALC882_W2JC] = "w2jc",
8308 [ALC882_TARGA] = "targa",
8309 [ALC882_ASUS_A7J] = "asus-a7j",
8310 [ALC882_ASUS_A7M] = "asus-a7m",
8311 [ALC885_MACPRO] = "macpro",
8312 [ALC885_MB5] = "mb5",
8313 [ALC885_MBP3] = "mbp3",
8314 [ALC885_IMAC24] = "imac24",
8315 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
8316 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8317 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 8318 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
8319 [ALC883_TARGA_DIG] = "targa-dig",
8320 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 8321 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 8322 [ALC883_ACER] = "acer",
2880a867 8323 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 8324 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 8325 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 8326 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
f5fcc13c 8327 [ALC883_MEDION] = "medion",
272a527c 8328 [ALC883_MEDION_MD2] = "medion-md2",
f5fcc13c 8329 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 8330 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
8331 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8332 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 8333 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 8334 [ALC883_HAIER_W66] = "haier-w66",
4723c022 8335 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 8336 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 8337 [ALC883_MITAC] = "mitac",
0c4cc443 8338 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 8339 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 8340 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 8341 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
3ab90935 8342 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 8343 [ALC889A_MB31] = "mb31",
3e1647c5 8344 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 8345 [ALC882_AUTO] = "auto",
f5fcc13c
TI
8346};
8347
4953550a
TI
8348static struct snd_pci_quirk alc882_cfg_tbl[] = {
8349 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
8350
ac3e3741 8351 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 8352 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 8353 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
8354 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8355 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 8356 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
8357 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8358 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd
LW
8359 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8360 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
8361 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
8362 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
8363 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
8364 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
8365 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
8366 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 8367 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 8368 ALC888_ACER_ASPIRE_6530G),
cc374c47 8369 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 8370 ALC888_ACER_ASPIRE_6530G),
22b530e0
TI
8371 /* default Acer -- disabled as it causes more problems.
8372 * model=auto should work fine now
8373 */
8374 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 8375
5795b9e6 8376 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 8377
febe3375 8378 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
8379 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8380 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 8381 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 8382 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 8383 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
8384
8385 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
8386 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
8387 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 8388 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
8389 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
8390 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
8391 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 8392 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 8393 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 8394 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 8395 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
8396
8397 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 8398 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 8399 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 8400 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
8401 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8402 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 8403 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 8404 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
4953550a
TI
8405 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
8406
6f3bf657 8407 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 8408 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8409 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 8410 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
4383fae0 8411 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 8412 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 8413 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 8414 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 8415 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8416 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
8417 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8418 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 8419 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 8420 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
8421 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8422 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8423 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
64a8be74 8424 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
8425 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8426 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8427 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 8428 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 8429 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
8430 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8431 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 8432 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
f5fcc13c 8433 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 8434
ac3e3741 8435 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
0c4cc443
HRK
8436 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8437 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
dea0a509 8438 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 8439 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 8440 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 8441 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 8442 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 8443 ALC883_FUJITSU_PI2515),
bfb53037 8444 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 8445 ALC888_FUJITSU_XA3530),
272a527c 8446 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 8447 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
8448 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8449 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 8450 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
272a527c 8451 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
959973b9 8452 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 8453 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 8454 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 8455
17bba1b7
J
8456 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8457 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 8458 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
4b558991 8459 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
ac3e3741 8460 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9c7f852e 8461
4953550a 8462 {}
f3cd3f5d
WF
8463};
8464
4953550a
TI
8465/* codec SSID table for Intel Mac */
8466static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
8467 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
8468 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
8469 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
8470 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
8471 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
8472 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
8473 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
8474 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
8475 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
8476 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
8477 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
8478 /* FIXME: HP jack sense seems not working for MBP 5,1, so apparently
8479 * no perfect solution yet
8480 */
8481 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
8482 {} /* terminator */
b25c9da1
WF
8483};
8484
4953550a
TI
8485static struct alc_config_preset alc882_presets[] = {
8486 [ALC882_3ST_DIG] = {
8487 .mixers = { alc882_base_mixer },
8488 .init_verbs = { alc882_init_verbs },
8489 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8490 .dac_nids = alc882_dac_nids,
8491 .dig_out_nid = ALC882_DIGOUT_NID,
8492 .dig_in_nid = ALC882_DIGIN_NID,
8493 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8494 .channel_mode = alc882_ch_modes,
8495 .need_dac_fix = 1,
8496 .input_mux = &alc882_capture_source,
8497 },
8498 [ALC882_6ST_DIG] = {
8499 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8500 .init_verbs = { alc882_init_verbs },
8501 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8502 .dac_nids = alc882_dac_nids,
8503 .dig_out_nid = ALC882_DIGOUT_NID,
8504 .dig_in_nid = ALC882_DIGIN_NID,
8505 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8506 .channel_mode = alc882_sixstack_modes,
8507 .input_mux = &alc882_capture_source,
8508 },
8509 [ALC882_ARIMA] = {
8510 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8511 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
8512 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8513 .dac_nids = alc882_dac_nids,
8514 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8515 .channel_mode = alc882_sixstack_modes,
8516 .input_mux = &alc882_capture_source,
8517 },
8518 [ALC882_W2JC] = {
8519 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8520 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
8521 alc880_gpio1_init_verbs },
8522 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8523 .dac_nids = alc882_dac_nids,
8524 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
8525 .channel_mode = alc880_threestack_modes,
8526 .need_dac_fix = 1,
8527 .input_mux = &alc882_capture_source,
8528 .dig_out_nid = ALC882_DIGOUT_NID,
8529 },
8530 [ALC885_MBP3] = {
8531 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
8532 .init_verbs = { alc885_mbp3_init_verbs,
8533 alc880_gpio1_init_verbs },
8534 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8535 .dac_nids = alc882_dac_nids,
8536 .channel_mode = alc885_mbp_6ch_modes,
8537 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
8538 .input_mux = &alc882_capture_source,
8539 .dig_out_nid = ALC882_DIGOUT_NID,
8540 .dig_in_nid = ALC882_DIGIN_NID,
8541 .unsol_event = alc_automute_amp_unsol_event,
8542 .init_hook = alc885_mbp3_init_hook,
8543 },
8544 [ALC885_MB5] = {
8545 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
8546 .init_verbs = { alc885_mb5_init_verbs,
8547 alc880_gpio1_init_verbs },
8548 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8549 .dac_nids = alc882_dac_nids,
8550 .channel_mode = alc885_mb5_6ch_modes,
8551 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
8552 .input_mux = &mb5_capture_source,
8553 .dig_out_nid = ALC882_DIGOUT_NID,
8554 .dig_in_nid = ALC882_DIGIN_NID,
8555 },
8556 [ALC885_MACPRO] = {
8557 .mixers = { alc882_macpro_mixer },
8558 .init_verbs = { alc882_macpro_init_verbs },
8559 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8560 .dac_nids = alc882_dac_nids,
8561 .dig_out_nid = ALC882_DIGOUT_NID,
8562 .dig_in_nid = ALC882_DIGIN_NID,
8563 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8564 .channel_mode = alc882_ch_modes,
8565 .input_mux = &alc882_capture_source,
8566 .init_hook = alc885_macpro_init_hook,
8567 },
8568 [ALC885_IMAC24] = {
8569 .mixers = { alc885_imac24_mixer },
8570 .init_verbs = { alc885_imac24_init_verbs },
8571 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8572 .dac_nids = alc882_dac_nids,
8573 .dig_out_nid = ALC882_DIGOUT_NID,
8574 .dig_in_nid = ALC882_DIGIN_NID,
8575 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8576 .channel_mode = alc882_ch_modes,
8577 .input_mux = &alc882_capture_source,
8578 .unsol_event = alc_automute_amp_unsol_event,
8579 .init_hook = alc885_imac24_init_hook,
8580 },
8581 [ALC882_TARGA] = {
8582 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8583 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
8584 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8585 .dac_nids = alc882_dac_nids,
8586 .dig_out_nid = ALC882_DIGOUT_NID,
8587 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
8588 .adc_nids = alc882_adc_nids,
8589 .capsrc_nids = alc882_capsrc_nids,
8590 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
8591 .channel_mode = alc882_3ST_6ch_modes,
8592 .need_dac_fix = 1,
8593 .input_mux = &alc882_capture_source,
8594 .unsol_event = alc882_targa_unsol_event,
8595 .init_hook = alc882_targa_init_hook,
8596 },
8597 [ALC882_ASUS_A7J] = {
8598 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8599 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
8600 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8601 .dac_nids = alc882_dac_nids,
8602 .dig_out_nid = ALC882_DIGOUT_NID,
8603 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
8604 .adc_nids = alc882_adc_nids,
8605 .capsrc_nids = alc882_capsrc_nids,
8606 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
8607 .channel_mode = alc882_3ST_6ch_modes,
8608 .need_dac_fix = 1,
8609 .input_mux = &alc882_capture_source,
8610 },
8611 [ALC882_ASUS_A7M] = {
8612 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8613 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
8614 alc880_gpio1_init_verbs,
8615 alc882_asus_a7m_verbs },
8616 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8617 .dac_nids = alc882_dac_nids,
8618 .dig_out_nid = ALC882_DIGOUT_NID,
8619 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
8620 .channel_mode = alc880_threestack_modes,
8621 .need_dac_fix = 1,
8622 .input_mux = &alc882_capture_source,
8623 },
9c7f852e
TI
8624 [ALC883_3ST_2ch_DIG] = {
8625 .mixers = { alc883_3ST_2ch_mixer },
8626 .init_verbs = { alc883_init_verbs },
8627 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8628 .dac_nids = alc883_dac_nids,
8629 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8630 .dig_in_nid = ALC883_DIGIN_NID,
8631 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8632 .channel_mode = alc883_3ST_2ch_modes,
8633 .input_mux = &alc883_capture_source,
8634 },
8635 [ALC883_3ST_6ch_DIG] = {
8636 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8637 .init_verbs = { alc883_init_verbs },
8638 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8639 .dac_nids = alc883_dac_nids,
8640 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8641 .dig_in_nid = ALC883_DIGIN_NID,
8642 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8643 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 8644 .need_dac_fix = 1,
9c7f852e 8645 .input_mux = &alc883_capture_source,
f12ab1e0 8646 },
9c7f852e
TI
8647 [ALC883_3ST_6ch] = {
8648 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8649 .init_verbs = { alc883_init_verbs },
8650 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8651 .dac_nids = alc883_dac_nids,
9c7f852e
TI
8652 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8653 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 8654 .need_dac_fix = 1,
9c7f852e 8655 .input_mux = &alc883_capture_source,
f12ab1e0 8656 },
17bba1b7
J
8657 [ALC883_3ST_6ch_INTEL] = {
8658 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8659 .init_verbs = { alc883_init_verbs },
8660 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8661 .dac_nids = alc883_dac_nids,
8662 .dig_out_nid = ALC883_DIGOUT_NID,
8663 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 8664 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
8665 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8666 .channel_mode = alc883_3ST_6ch_intel_modes,
8667 .need_dac_fix = 1,
8668 .input_mux = &alc883_3stack_6ch_intel,
8669 },
9c7f852e
TI
8670 [ALC883_6ST_DIG] = {
8671 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8672 .init_verbs = { alc883_init_verbs },
8673 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8674 .dac_nids = alc883_dac_nids,
8675 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8676 .dig_in_nid = ALC883_DIGIN_NID,
8677 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8678 .channel_mode = alc883_sixstack_modes,
8679 .input_mux = &alc883_capture_source,
8680 },
ccc656ce 8681 [ALC883_TARGA_DIG] = {
c259249f
SA
8682 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
8683 .init_verbs = { alc883_init_verbs, alc883_targa_verbs},
ccc656ce
KY
8684 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8685 .dac_nids = alc883_dac_nids,
8686 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
8687 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8688 .channel_mode = alc883_3ST_6ch_modes,
8689 .need_dac_fix = 1,
8690 .input_mux = &alc883_capture_source,
c259249f
SA
8691 .unsol_event = alc883_targa_unsol_event,
8692 .init_hook = alc883_targa_init_hook,
ccc656ce
KY
8693 },
8694 [ALC883_TARGA_2ch_DIG] = {
c259249f
SA
8695 .mixers = { alc883_targa_2ch_mixer},
8696 .init_verbs = { alc883_init_verbs, alc883_targa_verbs},
ccc656ce
KY
8697 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8698 .dac_nids = alc883_dac_nids,
f9e336f6
TI
8699 .adc_nids = alc883_adc_nids_alt,
8700 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
ccc656ce 8701 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
8702 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8703 .channel_mode = alc883_3ST_2ch_modes,
8704 .input_mux = &alc883_capture_source,
c259249f
SA
8705 .unsol_event = alc883_targa_unsol_event,
8706 .init_hook = alc883_targa_init_hook,
ccc656ce 8707 },
64a8be74
DH
8708 [ALC883_TARGA_8ch_DIG] = {
8709 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8710 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 8711 alc883_targa_verbs },
64a8be74
DH
8712 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8713 .dac_nids = alc883_dac_nids,
8714 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8715 .adc_nids = alc883_adc_nids_rev,
8716 .capsrc_nids = alc883_capsrc_nids_rev,
8717 .dig_out_nid = ALC883_DIGOUT_NID,
8718 .dig_in_nid = ALC883_DIGIN_NID,
8719 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
8720 .channel_mode = alc883_4ST_8ch_modes,
8721 .need_dac_fix = 1,
8722 .input_mux = &alc883_capture_source,
c259249f
SA
8723 .unsol_event = alc883_targa_unsol_event,
8724 .init_hook = alc883_targa_init_hook,
64a8be74 8725 },
bab282b9 8726 [ALC883_ACER] = {
676a9b53 8727 .mixers = { alc883_base_mixer },
bab282b9
VA
8728 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8729 * and the headphone jack. Turn this on and rely on the
8730 * standard mute methods whenever the user wants to turn
8731 * these outputs off.
8732 */
8733 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8734 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8735 .dac_nids = alc883_dac_nids,
bab282b9
VA
8736 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8737 .channel_mode = alc883_3ST_2ch_modes,
8738 .input_mux = &alc883_capture_source,
8739 },
2880a867 8740 [ALC883_ACER_ASPIRE] = {
676a9b53 8741 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 8742 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
8743 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8744 .dac_nids = alc883_dac_nids,
8745 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
8746 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8747 .channel_mode = alc883_3ST_2ch_modes,
8748 .input_mux = &alc883_capture_source,
a9fd4f3f
TI
8749 .unsol_event = alc_automute_amp_unsol_event,
8750 .init_hook = alc883_acer_aspire_init_hook,
d1a991a6 8751 },
5b2d1eca 8752 [ALC888_ACER_ASPIRE_4930G] = {
ef8ef5fb 8753 .mixers = { alc888_base_mixer,
5b2d1eca
VP
8754 alc883_chmode_mixer },
8755 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8756 alc888_acer_aspire_4930g_verbs },
8757 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8758 .dac_nids = alc883_dac_nids,
8759 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8760 .adc_nids = alc883_adc_nids_rev,
8761 .capsrc_nids = alc883_capsrc_nids_rev,
8762 .dig_out_nid = ALC883_DIGOUT_NID,
8763 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8764 .channel_mode = alc883_3ST_6ch_modes,
8765 .need_dac_fix = 1,
8766 .num_mux_defs =
ef8ef5fb
VP
8767 ARRAY_SIZE(alc888_2_capture_sources),
8768 .input_mux = alc888_2_capture_sources,
d2fd4b09
TV
8769 .unsol_event = alc_automute_amp_unsol_event,
8770 .init_hook = alc888_acer_aspire_4930g_init_hook,
8771 },
8772 [ALC888_ACER_ASPIRE_6530G] = {
8773 .mixers = { alc888_acer_aspire_6530_mixer },
8774 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8775 alc888_acer_aspire_6530g_verbs },
8776 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8777 .dac_nids = alc883_dac_nids,
8778 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8779 .adc_nids = alc883_adc_nids_rev,
8780 .capsrc_nids = alc883_capsrc_nids_rev,
8781 .dig_out_nid = ALC883_DIGOUT_NID,
8782 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8783 .channel_mode = alc883_3ST_2ch_modes,
8784 .num_mux_defs =
8785 ARRAY_SIZE(alc888_2_capture_sources),
8786 .input_mux = alc888_acer_aspire_6530_sources,
a9fd4f3f 8787 .unsol_event = alc_automute_amp_unsol_event,
320d5920 8788 .init_hook = alc888_acer_aspire_6530g_init_hook,
5b2d1eca 8789 },
3b315d70
HM
8790 [ALC888_ACER_ASPIRE_8930G] = {
8791 .mixers = { alc888_base_mixer,
8792 alc883_chmode_mixer },
8793 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
018df418 8794 alc889_acer_aspire_8930g_verbs },
3b315d70
HM
8795 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8796 .dac_nids = alc883_dac_nids,
018df418
HM
8797 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
8798 .adc_nids = alc889_adc_nids,
8799 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
8800 .dig_out_nid = ALC883_DIGOUT_NID,
8801 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8802 .channel_mode = alc883_3ST_6ch_modes,
8803 .need_dac_fix = 1,
8804 .const_channel_count = 6,
8805 .num_mux_defs =
018df418
HM
8806 ARRAY_SIZE(alc889_capture_sources),
8807 .input_mux = alc889_capture_sources,
3b315d70 8808 .unsol_event = alc_automute_amp_unsol_event,
018df418 8809 .init_hook = alc889_acer_aspire_8930g_init_hook,
3b315d70 8810 },
c07584c8
TD
8811 [ALC883_MEDION] = {
8812 .mixers = { alc883_fivestack_mixer,
8813 alc883_chmode_mixer },
8814 .init_verbs = { alc883_init_verbs,
b373bdeb 8815 alc883_medion_eapd_verbs },
c07584c8
TD
8816 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8817 .dac_nids = alc883_dac_nids,
f9e336f6
TI
8818 .adc_nids = alc883_adc_nids_alt,
8819 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
c07584c8
TD
8820 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8821 .channel_mode = alc883_sixstack_modes,
8822 .input_mux = &alc883_capture_source,
b373bdeb 8823 },
272a527c
KY
8824 [ALC883_MEDION_MD2] = {
8825 .mixers = { alc883_medion_md2_mixer},
8826 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8827 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8828 .dac_nids = alc883_dac_nids,
8829 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
8830 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8831 .channel_mode = alc883_3ST_2ch_modes,
8832 .input_mux = &alc883_capture_source,
a9fd4f3f
TI
8833 .unsol_event = alc_automute_amp_unsol_event,
8834 .init_hook = alc883_medion_md2_init_hook,
ea1fb29a 8835 },
b373bdeb 8836 [ALC883_LAPTOP_EAPD] = {
676a9b53 8837 .mixers = { alc883_base_mixer },
b373bdeb
AN
8838 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8839 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8840 .dac_nids = alc883_dac_nids,
b373bdeb
AN
8841 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8842 .channel_mode = alc883_3ST_2ch_modes,
8843 .input_mux = &alc883_capture_source,
8844 },
0c4cc443
HRK
8845 [ALC883_CLEVO_M720] = {
8846 .mixers = { alc883_clevo_m720_mixer },
8847 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
8848 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8849 .dac_nids = alc883_dac_nids,
8850 .dig_out_nid = ALC883_DIGOUT_NID,
8851 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8852 .channel_mode = alc883_3ST_2ch_modes,
8853 .input_mux = &alc883_capture_source,
0c4cc443 8854 .unsol_event = alc883_clevo_m720_unsol_event,
a9fd4f3f 8855 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 8856 },
bc9f98a9
KY
8857 [ALC883_LENOVO_101E_2ch] = {
8858 .mixers = { alc883_lenovo_101e_2ch_mixer},
8859 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8860 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8861 .dac_nids = alc883_dac_nids,
f9e336f6
TI
8862 .adc_nids = alc883_adc_nids_alt,
8863 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
bc9f98a9
KY
8864 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8865 .channel_mode = alc883_3ST_2ch_modes,
8866 .input_mux = &alc883_lenovo_101e_capture_source,
8867 .unsol_event = alc883_lenovo_101e_unsol_event,
8868 .init_hook = alc883_lenovo_101e_all_automute,
8869 },
272a527c
KY
8870 [ALC883_LENOVO_NB0763] = {
8871 .mixers = { alc883_lenovo_nb0763_mixer },
8872 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8873 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8874 .dac_nids = alc883_dac_nids,
272a527c
KY
8875 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8876 .channel_mode = alc883_3ST_2ch_modes,
8877 .need_dac_fix = 1,
8878 .input_mux = &alc883_lenovo_nb0763_capture_source,
a9fd4f3f
TI
8879 .unsol_event = alc_automute_amp_unsol_event,
8880 .init_hook = alc883_medion_md2_init_hook,
272a527c
KY
8881 },
8882 [ALC888_LENOVO_MS7195_DIG] = {
8883 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8884 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8885 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8886 .dac_nids = alc883_dac_nids,
8887 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
8888 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8889 .channel_mode = alc883_3ST_6ch_modes,
8890 .need_dac_fix = 1,
8891 .input_mux = &alc883_capture_source,
8892 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8893 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
8894 },
8895 [ALC883_HAIER_W66] = {
c259249f 8896 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
8897 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8898 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8899 .dac_nids = alc883_dac_nids,
8900 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
8901 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8902 .channel_mode = alc883_3ST_2ch_modes,
8903 .input_mux = &alc883_capture_source,
a9fd4f3f
TI
8904 .unsol_event = alc_automute_amp_unsol_event,
8905 .init_hook = alc883_haier_w66_init_hook,
eea6419e 8906 },
4723c022 8907 [ALC888_3ST_HP] = {
eea6419e 8908 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 8909 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
8910 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8911 .dac_nids = alc883_dac_nids,
4723c022
CM
8912 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8913 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
8914 .need_dac_fix = 1,
8915 .input_mux = &alc883_capture_source,
a9fd4f3f
TI
8916 .unsol_event = alc_automute_amp_unsol_event,
8917 .init_hook = alc888_3st_hp_init_hook,
8341de60 8918 },
5795b9e6 8919 [ALC888_6ST_DELL] = {
f24dbdc6 8920 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
8921 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8922 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8923 .dac_nids = alc883_dac_nids,
8924 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
8925 .dig_in_nid = ALC883_DIGIN_NID,
8926 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8927 .channel_mode = alc883_sixstack_modes,
8928 .input_mux = &alc883_capture_source,
a9fd4f3f
TI
8929 .unsol_event = alc_automute_amp_unsol_event,
8930 .init_hook = alc888_6st_dell_init_hook,
5795b9e6 8931 },
a8848bd6
AS
8932 [ALC883_MITAC] = {
8933 .mixers = { alc883_mitac_mixer },
8934 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8935 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8936 .dac_nids = alc883_dac_nids,
a8848bd6
AS
8937 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8938 .channel_mode = alc883_3ST_2ch_modes,
8939 .input_mux = &alc883_capture_source,
a9fd4f3f
TI
8940 .unsol_event = alc_automute_amp_unsol_event,
8941 .init_hook = alc883_mitac_init_hook,
a8848bd6 8942 },
fb97dc67
J
8943 [ALC883_FUJITSU_PI2515] = {
8944 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8945 .init_verbs = { alc883_init_verbs,
8946 alc883_2ch_fujitsu_pi2515_verbs},
8947 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8948 .dac_nids = alc883_dac_nids,
8949 .dig_out_nid = ALC883_DIGOUT_NID,
8950 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8951 .channel_mode = alc883_3ST_2ch_modes,
8952 .input_mux = &alc883_fujitsu_pi2515_capture_source,
a9fd4f3f
TI
8953 .unsol_event = alc_automute_amp_unsol_event,
8954 .init_hook = alc883_2ch_fujitsu_pi2515_init_hook,
fb97dc67 8955 },
ef8ef5fb
VP
8956 [ALC888_FUJITSU_XA3530] = {
8957 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
8958 .init_verbs = { alc883_init_verbs,
8959 alc888_fujitsu_xa3530_verbs },
8960 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8961 .dac_nids = alc883_dac_nids,
8962 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8963 .adc_nids = alc883_adc_nids_rev,
8964 .capsrc_nids = alc883_capsrc_nids_rev,
8965 .dig_out_nid = ALC883_DIGOUT_NID,
8966 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
8967 .channel_mode = alc888_4ST_8ch_intel_modes,
8968 .num_mux_defs =
8969 ARRAY_SIZE(alc888_2_capture_sources),
8970 .input_mux = alc888_2_capture_sources,
a9fd4f3f
TI
8971 .unsol_event = alc_automute_amp_unsol_event,
8972 .init_hook = alc888_fujitsu_xa3530_init_hook,
ef8ef5fb 8973 },
e2757d5e
KY
8974 [ALC888_LENOVO_SKY] = {
8975 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8976 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8977 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8978 .dac_nids = alc883_dac_nids,
8979 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
8980 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8981 .channel_mode = alc883_sixstack_modes,
8982 .need_dac_fix = 1,
8983 .input_mux = &alc883_lenovo_sky_capture_source,
a9fd4f3f
TI
8984 .unsol_event = alc_automute_amp_unsol_event,
8985 .init_hook = alc888_lenovo_sky_init_hook,
e2757d5e
KY
8986 },
8987 [ALC888_ASUS_M90V] = {
8988 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8989 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8990 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8991 .dac_nids = alc883_dac_nids,
8992 .dig_out_nid = ALC883_DIGOUT_NID,
8993 .dig_in_nid = ALC883_DIGIN_NID,
8994 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8995 .channel_mode = alc883_3ST_6ch_modes,
8996 .need_dac_fix = 1,
8997 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8998 .unsol_event = alc883_mode2_unsol_event,
8999 .init_hook = alc883_mode2_inithook,
9000 },
9001 [ALC888_ASUS_EEE1601] = {
9002 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 9003 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
9004 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9005 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9006 .dac_nids = alc883_dac_nids,
9007 .dig_out_nid = ALC883_DIGOUT_NID,
9008 .dig_in_nid = ALC883_DIGIN_NID,
9009 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9010 .channel_mode = alc883_3ST_2ch_modes,
9011 .need_dac_fix = 1,
9012 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 9013 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
9014 .init_hook = alc883_eee1601_inithook,
9015 },
3ab90935
WF
9016 [ALC1200_ASUS_P5Q] = {
9017 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9018 .init_verbs = { alc883_init_verbs },
9019 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9020 .dac_nids = alc883_dac_nids,
9021 .dig_out_nid = ALC1200_DIGOUT_NID,
9022 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 9023 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
9024 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9025 .channel_mode = alc883_sixstack_modes,
9026 .input_mux = &alc883_capture_source,
9027 },
eb4c41d3
TS
9028 [ALC889A_MB31] = {
9029 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
9030 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
9031 alc880_gpio1_init_verbs },
9032 .adc_nids = alc883_adc_nids,
9033 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
9034 .dac_nids = alc883_dac_nids,
9035 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9036 .channel_mode = alc889A_mb31_6ch_modes,
9037 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
9038 .input_mux = &alc889A_mb31_capture_source,
9039 .dig_out_nid = ALC883_DIGOUT_NID,
9040 .unsol_event = alc889A_mb31_unsol_event,
9041 .init_hook = alc889A_mb31_automute,
9042 },
3e1647c5
GG
9043 [ALC883_SONY_VAIO_TT] = {
9044 .mixers = { alc883_vaiott_mixer },
9045 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
9046 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9047 .dac_nids = alc883_dac_nids,
9048 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9049 .channel_mode = alc883_3ST_2ch_modes,
9050 .input_mux = &alc883_capture_source,
9051 .unsol_event = alc_automute_amp_unsol_event,
9052 .init_hook = alc883_vaiott_init_hook,
9053 },
9c7f852e
TI
9054};
9055
9056
4953550a
TI
9057/*
9058 * Pin config fixes
9059 */
9060enum {
9061 PINFIX_ABIT_AW9D_MAX
9062};
9063
9064static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
9065 { 0x15, 0x01080104 }, /* side */
9066 { 0x16, 0x01011012 }, /* rear */
9067 { 0x17, 0x01016011 }, /* clfe */
9068 { }
9069};
9070
9071static const struct alc_pincfg *alc882_pin_fixes[] = {
9072 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
9073};
9074
9075static struct snd_pci_quirk alc882_pinfix_tbl[] = {
9076 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
9077 {}
9078};
9079
9c7f852e
TI
9080/*
9081 * BIOS auto configuration
9082 */
4953550a 9083static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e
TI
9084 hda_nid_t nid, int pin_type,
9085 int dac_idx)
9086{
9087 /* set as output */
9088 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
9089 int idx;
9090
f6c7e546 9091 alc_set_pin_output(codec, nid, pin_type);
9c7f852e
TI
9092 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9093 idx = 4;
9094 else
9095 idx = spec->multiout.dac_nids[dac_idx] - 2;
9c7f852e
TI
9096 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9097
9098}
9099
4953550a 9100static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
9101{
9102 struct alc_spec *spec = codec->spec;
9103 int i;
9104
9105 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 9106 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 9107 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 9108 if (nid)
4953550a 9109 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 9110 i);
9c7f852e
TI
9111 }
9112}
9113
4953550a 9114static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
9115{
9116 struct alc_spec *spec = codec->spec;
9117 hda_nid_t pin;
9118
eb06ed8f 9119 pin = spec->autocfg.hp_pins[0];
9c7f852e
TI
9120 if (pin) /* connect to front */
9121 /* use dac 0 */
4953550a 9122 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
9123 pin = spec->autocfg.speaker_pins[0];
9124 if (pin)
4953550a 9125 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9c7f852e
TI
9126}
9127
4953550a
TI
9128#define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
9129#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
9c7f852e 9130
4953550a 9131static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
9132{
9133 struct alc_spec *spec = codec->spec;
9134 int i;
9135
9136 for (i = 0; i < AUTO_PIN_LAST; i++) {
9137 hda_nid_t nid = spec->autocfg.input_pins[i];
4953550a
TI
9138 if (!nid)
9139 continue;
9140 alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
9141 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
9142 snd_hda_codec_write(codec, nid, 0,
9143 AC_VERB_SET_AMP_GAIN_MUTE,
9144 AMP_OUT_MUTE);
9145 }
9146}
9147
9148static void alc882_auto_init_input_src(struct hda_codec *codec)
9149{
9150 struct alc_spec *spec = codec->spec;
9151 int c;
9152
9153 for (c = 0; c < spec->num_adc_nids; c++) {
9154 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
9155 hda_nid_t nid = spec->capsrc_nids[c];
9156 unsigned int mux_idx;
9157 const struct hda_input_mux *imux;
9158 int conns, mute, idx, item;
9159
9160 conns = snd_hda_get_connections(codec, nid, conn_list,
9161 ARRAY_SIZE(conn_list));
9162 if (conns < 0)
9163 continue;
9164 mux_idx = c >= spec->num_mux_defs ? 0 : c;
9165 imux = &spec->input_mux[mux_idx];
9166 for (idx = 0; idx < conns; idx++) {
9167 /* if the current connection is the selected one,
9168 * unmute it as default - otherwise mute it
9169 */
9170 mute = AMP_IN_MUTE(idx);
9171 for (item = 0; item < imux->num_items; item++) {
9172 if (imux->items[item].index == idx) {
9173 if (spec->cur_mux[c] == item)
9174 mute = AMP_IN_UNMUTE(idx);
9175 break;
9176 }
9177 }
9178 /* check if we have a selector or mixer
9179 * we could check for the widget type instead, but
9180 * just check for Amp-In presence (in case of mixer
9181 * without amp-in there is something wrong, this
9182 * function shouldn't be used or capsrc nid is wrong)
9183 */
9184 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
9185 snd_hda_codec_write(codec, nid, 0,
9186 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
9187 mute);
9188 else if (mute != AMP_IN_MUTE(idx))
9189 snd_hda_codec_write(codec, nid, 0,
9190 AC_VERB_SET_CONNECT_SEL,
9191 idx);
9c7f852e
TI
9192 }
9193 }
9194}
9195
4953550a
TI
9196/* add mic boosts if needed */
9197static int alc_auto_add_mic_boost(struct hda_codec *codec)
9198{
9199 struct alc_spec *spec = codec->spec;
9200 int err;
9201 hda_nid_t nid;
9202
9203 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
9204 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9205 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9206 "Mic Boost",
9207 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9208 if (err < 0)
9209 return err;
9210 }
9211 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
9212 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9213 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9214 "Front Mic Boost",
9215 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9216 if (err < 0)
9217 return err;
9218 }
9219 return 0;
9220}
f511b01c 9221
9c7f852e 9222/* almost identical with ALC880 parser... */
4953550a 9223static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
9224{
9225 struct alc_spec *spec = codec->spec;
4953550a
TI
9226 struct auto_pin_cfg *autocfg = &spec->autocfg;
9227 unsigned int wcap;
61b9b9b1 9228 int i;
4953550a 9229 int err = alc880_parse_auto_config(codec);
9c7f852e
TI
9230
9231 if (err < 0)
9232 return err;
776e184e
TI
9233 else if (!err)
9234 return 0; /* no config found */
9235
9236 err = alc_auto_add_mic_boost(codec);
9237 if (err < 0)
9238 return err;
9239
9240 /* hack - override the init verbs */
9241 spec->init_verbs[0] = alc883_auto_init_verbs;
4953550a
TI
9242 /* if ADC 0x07 is available, initialize it, too */
9243 wcap = get_wcaps(codec, 0x07);
9244 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9245 if (wcap == AC_WID_AUD_IN)
9246 add_verb(spec, alc882_adc1_init_verbs);
776e184e 9247
4953550a
TI
9248 /* digital-mic input pin is excluded in alc880_auto_create..()
9249 * because it's under 0x18
9250 */
9251 if (autocfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9252 autocfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9253 struct hda_input_mux *imux = &spec->private_imux[0];
9254 for (i = 1; i < 3; i++)
9255 memcpy(&spec->private_imux[i],
9256 &spec->private_imux[0],
9257 sizeof(spec->private_imux[0]));
9258 imux->items[imux->num_items].label = "Int DMic";
9259 imux->items[imux->num_items].index = 0x0b;
9260 imux->num_items++;
9261 spec->num_mux_defs = 3;
9262 spec->input_mux = spec->private_imux;
61b9b9b1
HRK
9263 }
9264
776e184e 9265 return 1; /* config found */
9c7f852e
TI
9266}
9267
9268/* additional initialization for auto-configuration model */
4953550a 9269static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 9270{
f6c7e546 9271 struct alc_spec *spec = codec->spec;
4953550a
TI
9272 alc882_auto_init_multi_out(codec);
9273 alc882_auto_init_hp_out(codec);
9274 alc882_auto_init_analog_input(codec);
9275 alc882_auto_init_input_src(codec);
f6c7e546 9276 if (spec->unsol_event)
7fb0d78f 9277 alc_inithook(codec);
9c7f852e
TI
9278}
9279
4953550a 9280static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
9281{
9282 struct alc_spec *spec;
9283 int err, board_config;
9284
9285 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9286 if (spec == NULL)
9287 return -ENOMEM;
9288
9289 codec->spec = spec;
9290
4953550a
TI
9291 switch (codec->vendor_id) {
9292 case 0x10ec0882:
9293 case 0x10ec0885:
9294 break;
9295 default:
9296 /* ALC883 and variants */
9297 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9298 break;
9299 }
2c3bf9ab 9300
4953550a
TI
9301 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
9302 alc882_models,
9303 alc882_cfg_tbl);
9304
9305 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
9306 board_config = snd_hda_check_board_codec_sid_config(codec,
9307 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
9308
9309 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9310 printk(KERN_INFO "hda_codec: Unknown model for %s, "
9311 "trying auto-probe from BIOS...\n",
9312 codec->chip_name);
9313 board_config = ALC882_AUTO;
9c7f852e
TI
9314 }
9315
4953550a
TI
9316 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
9317
9318 if (board_config == ALC882_AUTO) {
9c7f852e 9319 /* automatic parse from the BIOS config */
4953550a 9320 err = alc882_parse_auto_config(codec);
9c7f852e
TI
9321 if (err < 0) {
9322 alc_free(codec);
9323 return err;
f12ab1e0 9324 } else if (!err) {
9c7f852e
TI
9325 printk(KERN_INFO
9326 "hda_codec: Cannot set up configuration "
9327 "from BIOS. Using base mode...\n");
4953550a 9328 board_config = ALC882_3ST_DIG;
9c7f852e
TI
9329 }
9330 }
9331
680cd536
KK
9332 err = snd_hda_attach_beep_device(codec, 0x1);
9333 if (err < 0) {
9334 alc_free(codec);
9335 return err;
9336 }
9337
4953550a
TI
9338 if (board_config != ALC882_AUTO)
9339 setup_preset(spec, &alc882_presets[board_config]);
9c7f852e 9340
4953550a
TI
9341 spec->stream_analog_playback = &alc882_pcm_analog_playback;
9342 spec->stream_analog_capture = &alc882_pcm_analog_capture;
9343 /* FIXME: setup DAC5 */
9344 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
9345 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
9346
9347 spec->stream_digital_playback = &alc882_pcm_digital_playback;
9348 spec->stream_digital_capture = &alc882_pcm_digital_capture;
9349
9350 if (codec->vendor_id == 0x10ec0888)
4a79ba34 9351 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
4953550a
TI
9352
9353 if (!spec->adc_nids && spec->input_mux) {
9354 int i;
9355 spec->num_adc_nids = 0;
9356 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
9357 hda_nid_t cap;
9358 hda_nid_t nid = alc882_adc_nids[i];
9359 unsigned int wcap = get_wcaps(codec, nid);
9360 /* get type */
9361 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9362 if (wcap != AC_WID_AUD_IN)
9363 continue;
9364 spec->private_adc_nids[spec->num_adc_nids] = nid;
9365 err = snd_hda_get_connections(codec, nid, &cap, 1);
9366 if (err < 0)
9367 continue;
9368 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
9369 spec->num_adc_nids++;
61b9b9b1 9370 }
4953550a
TI
9371 spec->adc_nids = spec->private_adc_nids;
9372 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
9373 }
9374
4953550a 9375 set_capture_mixer(spec);
45bdd1c1 9376 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 9377
2134ea4f
TI
9378 spec->vmaster_nid = 0x0c;
9379
9c7f852e 9380 codec->patch_ops = alc_patch_ops;
4953550a
TI
9381 if (board_config == ALC882_AUTO)
9382 spec->init_hook = alc882_auto_init;
cb53c626
TI
9383#ifdef CONFIG_SND_HDA_POWER_SAVE
9384 if (!spec->loopback.amplist)
4953550a 9385 spec->loopback.amplist = alc882_loopbacks;
cb53c626 9386#endif
daead538 9387 codec->proc_widget_hook = print_realtek_coef;
9c7f852e
TI
9388
9389 return 0;
9390}
9391
4953550a 9392
9c7f852e
TI
9393/*
9394 * ALC262 support
9395 */
9396
9397#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9398#define ALC262_DIGIN_NID ALC880_DIGIN_NID
9399
9400#define alc262_dac_nids alc260_dac_nids
9401#define alc262_adc_nids alc882_adc_nids
9402#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
9403#define alc262_capsrc_nids alc882_capsrc_nids
9404#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
9405
9406#define alc262_modes alc260_modes
9407#define alc262_capture_source alc882_capture_source
9408
4e555fe5
KY
9409static hda_nid_t alc262_dmic_adc_nids[1] = {
9410 /* ADC0 */
9411 0x09
9412};
9413
9414static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9415
9c7f852e
TI
9416static struct snd_kcontrol_new alc262_base_mixer[] = {
9417 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9418 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9419 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9420 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9421 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9422 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9423 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9424 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9425 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9426 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9427 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 9428 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
9429 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9430 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9431 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9432 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9433 { } /* end */
9434};
9435
ce875f07
TI
9436/* update HP, line and mono-out pins according to the master switch */
9437static void alc262_hp_master_update(struct hda_codec *codec)
9438{
9439 struct alc_spec *spec = codec->spec;
9440 int val = spec->master_sw;
9441
9442 /* HP & line-out */
9443 snd_hda_codec_write_cache(codec, 0x1b, 0,
9444 AC_VERB_SET_PIN_WIDGET_CONTROL,
9445 val ? PIN_HP : 0);
9446 snd_hda_codec_write_cache(codec, 0x15, 0,
9447 AC_VERB_SET_PIN_WIDGET_CONTROL,
9448 val ? PIN_HP : 0);
9449 /* mono (speaker) depending on the HP jack sense */
9450 val = val && !spec->jack_present;
9451 snd_hda_codec_write_cache(codec, 0x16, 0,
9452 AC_VERB_SET_PIN_WIDGET_CONTROL,
9453 val ? PIN_OUT : 0);
9454}
9455
9456static void alc262_hp_bpc_automute(struct hda_codec *codec)
9457{
9458 struct alc_spec *spec = codec->spec;
9459 unsigned int presence;
9460 presence = snd_hda_codec_read(codec, 0x1b, 0,
9461 AC_VERB_GET_PIN_SENSE, 0);
9462 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9463 alc262_hp_master_update(codec);
9464}
9465
9466static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9467{
9468 if ((res >> 26) != ALC880_HP_EVENT)
9469 return;
9470 alc262_hp_bpc_automute(codec);
9471}
9472
9473static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9474{
9475 struct alc_spec *spec = codec->spec;
9476 unsigned int presence;
9477 presence = snd_hda_codec_read(codec, 0x15, 0,
9478 AC_VERB_GET_PIN_SENSE, 0);
9479 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9480 alc262_hp_master_update(codec);
9481}
9482
9483static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9484 unsigned int res)
9485{
9486 if ((res >> 26) != ALC880_HP_EVENT)
9487 return;
9488 alc262_hp_wildwest_automute(codec);
9489}
9490
b72519b5 9491#define alc262_hp_master_sw_get alc260_hp_master_sw_get
ce875f07
TI
9492
9493static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9494 struct snd_ctl_elem_value *ucontrol)
9495{
9496 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9497 struct alc_spec *spec = codec->spec;
9498 int val = !!*ucontrol->value.integer.value;
9499
9500 if (val == spec->master_sw)
9501 return 0;
9502 spec->master_sw = val;
9503 alc262_hp_master_update(codec);
9504 return 1;
9505}
9506
b72519b5
TI
9507#define ALC262_HP_MASTER_SWITCH \
9508 { \
9509 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9510 .name = "Master Playback Switch", \
9511 .info = snd_ctl_boolean_mono_info, \
9512 .get = alc262_hp_master_sw_get, \
9513 .put = alc262_hp_master_sw_put, \
9514 }
9515
9c7f852e 9516static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 9517 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
9518 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9519 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9520 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
9521 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9522 HDA_OUTPUT),
9523 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9524 HDA_OUTPUT),
9c7f852e
TI
9525 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9526 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9527 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9528 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9529 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 9530 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
9531 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9532 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9533 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9534 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
9535 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9536 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9537 { } /* end */
9538};
9539
cd7509a4 9540static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 9541 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
9542 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9543 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9544 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9545 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
9546 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9547 HDA_OUTPUT),
9548 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9549 HDA_OUTPUT),
cd7509a4
KY
9550 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9551 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 9552 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
9553 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9554 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9555 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9556 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
9557 { } /* end */
9558};
9559
9560static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9561 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9562 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9563 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
9564 { } /* end */
9565};
9566
66d2a9d6 9567/* mute/unmute internal speaker according to the hp jack and mute state */
a9fd4f3f 9568static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
66d2a9d6
KY
9569{
9570 struct alc_spec *spec = codec->spec;
66d2a9d6 9571
a9fd4f3f
TI
9572 spec->autocfg.hp_pins[0] = 0x15;
9573 spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
9574 alc_automute_amp(codec);
66d2a9d6
KY
9575}
9576
66d2a9d6 9577static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
9578 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9579 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
9580 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9581 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9582 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9583 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9584 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9585 { } /* end */
9586};
9587
9588static struct hda_verb alc262_hp_t5735_verbs[] = {
9589 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9590 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9591
9592 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9593 { }
9594};
9595
8c427226 9596static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
9597 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9598 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
9599 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9600 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
9601 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9602 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9603 { } /* end */
9604};
9605
9606static struct hda_verb alc262_hp_rp5700_verbs[] = {
9607 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9608 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9609 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9610 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9611 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9612 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9613 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9614 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9615 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9616 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9617 {}
9618};
9619
9620static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9621 .num_items = 1,
9622 .items = {
9623 { "Line", 0x1 },
9624 },
9625};
9626
42171c17
TI
9627/* bind hp and internal speaker mute (with plug check) as master switch */
9628static void alc262_hippo_master_update(struct hda_codec *codec)
0724ea2a 9629{
42171c17
TI
9630 struct alc_spec *spec = codec->spec;
9631 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9632 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9633 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9634 unsigned int mute;
0724ea2a 9635
42171c17
TI
9636 /* HP */
9637 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
9638 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
9639 HDA_AMP_MUTE, mute);
9640 /* mute internal speaker per jack sense */
9641 if (spec->jack_present)
9642 mute = HDA_AMP_MUTE;
9643 if (line_nid)
9644 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
9645 HDA_AMP_MUTE, mute);
9646 if (speaker_nid && speaker_nid != line_nid)
9647 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
0724ea2a 9648 HDA_AMP_MUTE, mute);
42171c17
TI
9649}
9650
9651#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
9652
9653static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
9654 struct snd_ctl_elem_value *ucontrol)
9655{
9656 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9657 struct alc_spec *spec = codec->spec;
9658 int val = !!*ucontrol->value.integer.value;
9659
9660 if (val == spec->master_sw)
9661 return 0;
9662 spec->master_sw = val;
9663 alc262_hippo_master_update(codec);
9664 return 1;
9665}
9666
9667#define ALC262_HIPPO_MASTER_SWITCH \
9668 { \
9669 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9670 .name = "Master Playback Switch", \
9671 .info = snd_ctl_boolean_mono_info, \
9672 .get = alc262_hippo_master_sw_get, \
9673 .put = alc262_hippo_master_sw_put, \
0724ea2a 9674 }
42171c17
TI
9675
9676static struct snd_kcontrol_new alc262_hippo_mixer[] = {
9677 ALC262_HIPPO_MASTER_SWITCH,
9678 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9679 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9680 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9681 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9682 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9683 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9684 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9685 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9686 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9687 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9688 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9689 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9690 { } /* end */
9691};
9692
9693static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9694 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9695 ALC262_HIPPO_MASTER_SWITCH,
9696 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9697 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9698 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9699 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9700 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9701 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9702 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9703 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9704 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9705 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9706 { } /* end */
9707};
9708
9709/* mute/unmute internal speaker according to the hp jack and mute state */
9710static void alc262_hippo_automute(struct hda_codec *codec)
9711{
9712 struct alc_spec *spec = codec->spec;
9713 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9714 unsigned int present;
9715
9716 /* need to execute and sync at first */
9717 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
9718 present = snd_hda_codec_read(codec, hp_nid, 0,
9719 AC_VERB_GET_PIN_SENSE, 0);
9720 spec->jack_present = (present & 0x80000000) != 0;
9721 alc262_hippo_master_update(codec);
0724ea2a 9722}
5b31954e 9723
42171c17
TI
9724static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
9725{
9726 if ((res >> 26) != ALC880_HP_EVENT)
9727 return;
9728 alc262_hippo_automute(codec);
9729}
9730
9731static void alc262_hippo_init_hook(struct hda_codec *codec)
9732{
9733 struct alc_spec *spec = codec->spec;
9734
9735 spec->autocfg.hp_pins[0] = 0x15;
9736 spec->autocfg.speaker_pins[0] = 0x14;
9737 alc262_hippo_automute(codec);
9738}
9739
9740static void alc262_hippo1_init_hook(struct hda_codec *codec)
9741{
9742 struct alc_spec *spec = codec->spec;
9743
9744 spec->autocfg.hp_pins[0] = 0x1b;
9745 spec->autocfg.speaker_pins[0] = 0x14;
9746 alc262_hippo_automute(codec);
9747}
9748
9749
272a527c 9750static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 9751 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 9752 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
9753 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9754 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9755 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9756 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9757 { } /* end */
9758};
9759
83c34218 9760static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
9761 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9762 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
9763 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9764 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9765 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9766 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9767 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9768 { } /* end */
9769};
272a527c 9770
ba340e82
TV
9771static struct snd_kcontrol_new alc262_tyan_mixer[] = {
9772 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9773 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9774 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
9775 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
9776 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9777 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9778 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9779 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9780 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9781 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9782 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9783 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9784 { } /* end */
9785};
9786
9787static struct hda_verb alc262_tyan_verbs[] = {
9788 /* Headphone automute */
9789 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9790 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9791 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9792
9793 /* P11 AUX_IN, white 4-pin connector */
9794 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9795 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
9796 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
9797 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
9798
9799 {}
9800};
9801
9802/* unsolicited event for HP jack sensing */
a9fd4f3f 9803static void alc262_tyan_init_hook(struct hda_codec *codec)
ba340e82 9804{
a9fd4f3f 9805 struct alc_spec *spec = codec->spec;
ba340e82 9806
a9fd4f3f
TI
9807 spec->autocfg.hp_pins[0] = 0x1b;
9808 spec->autocfg.speaker_pins[0] = 0x15;
9809 alc_automute_amp(codec);
ba340e82
TV
9810}
9811
ba340e82 9812
9c7f852e
TI
9813#define alc262_capture_mixer alc882_capture_mixer
9814#define alc262_capture_alt_mixer alc882_capture_alt_mixer
9815
9816/*
9817 * generic initialization of ADC, input mixers and output mixers
9818 */
9819static struct hda_verb alc262_init_verbs[] = {
9820 /*
9821 * Unmute ADC0-2 and set the default input to mic-in
9822 */
9823 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9824 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9825 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9826 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9827 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9828 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9829
cb53c626 9830 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 9831 * mixer widget
f12ab1e0
TI
9832 * Note: PASD motherboards uses the Line In 2 as the input for
9833 * front panel mic (mic 2)
9c7f852e
TI
9834 */
9835 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
9836 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9837 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9838 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9839 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9840 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
9841
9842 /*
df694daa
KY
9843 * Set up output mixers (0x0c - 0x0e)
9844 */
9845 /* set vol=0 to output mixers */
9846 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9847 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9848 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9849 /* set up input amps for analog loopback */
9850 /* Amp Indices: DAC = 0, mixer = 1 */
9851 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9852 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9853 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9854 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9855 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9856 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9857
9858 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9859 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9860 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9861 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9862 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9863 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9864
9865 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9866 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9867 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9868 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9869 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 9870
df694daa
KY
9871 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9872 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 9873
df694daa
KY
9874 /* FIXME: use matrix-type input source selection */
9875 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9876 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9877 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9878 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9879 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9880 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9881 /* Input mixer2 */
9882 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9883 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9884 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9885 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9886 /* Input mixer3 */
9887 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9888 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9889 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 9890 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
9891
9892 { }
9893};
1da177e4 9894
4e555fe5
KY
9895static struct hda_verb alc262_eapd_verbs[] = {
9896 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9897 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9898 { }
9899};
9900
ccc656ce
KY
9901static struct hda_verb alc262_hippo_unsol_verbs[] = {
9902 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9903 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9904 {}
9905};
9906
9907static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9908 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9909 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9910 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9911
9912 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9913 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9914 {}
9915};
9916
272a527c
KY
9917static struct hda_verb alc262_sony_unsol_verbs[] = {
9918 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9919 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9920 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9921
9922 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9923 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 9924 {}
272a527c
KY
9925};
9926
4e555fe5
KY
9927static struct hda_input_mux alc262_dmic_capture_source = {
9928 .num_items = 2,
9929 .items = {
9930 { "Int DMic", 0x9 },
9931 { "Mic", 0x0 },
9932 },
9933};
9934
9935static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9936 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9937 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9938 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9939 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9940 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
9941 { } /* end */
9942};
9943
9944static struct hda_verb alc262_toshiba_s06_verbs[] = {
9945 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9946 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9947 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9948 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9949 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9950 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9951 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9952 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9953 {}
9954};
9955
9956static void alc262_dmic_automute(struct hda_codec *codec)
9957{
9958 unsigned int present;
9959
9960 present = snd_hda_codec_read(codec, 0x18, 0,
9961 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9962 snd_hda_codec_write(codec, 0x22, 0,
9963 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9964}
9965
4e555fe5
KY
9966
9967/* unsolicited event for HP jack sensing */
9968static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9969 unsigned int res)
9970{
4e555fe5
KY
9971 if ((res >> 26) == ALC880_MIC_EVENT)
9972 alc262_dmic_automute(codec);
a9fd4f3f
TI
9973 else
9974 alc_sku_unsol_event(codec, res);
4e555fe5
KY
9975}
9976
9977static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9978{
a9fd4f3f
TI
9979 struct alc_spec *spec = codec->spec;
9980
9981 spec->autocfg.hp_pins[0] = 0x15;
9982 spec->autocfg.speaker_pins[0] = 0x14;
9983 alc_automute_pin(codec);
4e555fe5
KY
9984 alc262_dmic_automute(codec);
9985}
9986
e8f9ae2a
PT
9987/*
9988 * nec model
9989 * 0x15 = headphone
9990 * 0x16 = internal speaker
9991 * 0x18 = external mic
9992 */
9993
9994static struct snd_kcontrol_new alc262_nec_mixer[] = {
9995 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9996 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9997
9998 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9999 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10000 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10001
10002 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10003 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10004 { } /* end */
10005};
10006
10007static struct hda_verb alc262_nec_verbs[] = {
10008 /* Unmute Speaker */
10009 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10010
10011 /* Headphone */
10012 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10013 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10014
10015 /* External mic to headphone */
10016 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10017 /* External mic to speaker */
10018 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10019 {}
10020};
10021
834be88d
TI
10022/*
10023 * fujitsu model
5d9fab2d
TV
10024 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
10025 * 0x1b = port replicator headphone out
834be88d
TI
10026 */
10027
10028#define ALC_HP_EVENT 0x37
10029
10030static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10031 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10032 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
10033 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10034 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
10035 {}
10036};
10037
0e31daf7
J
10038static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10039 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10040 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10041 {}
10042};
10043
834be88d 10044static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 10045 .num_items = 3,
834be88d
TI
10046 .items = {
10047 { "Mic", 0x0 },
39d3ed38 10048 { "Int Mic", 0x1 },
834be88d
TI
10049 { "CD", 0x4 },
10050 },
10051};
10052
9c7f852e
TI
10053static struct hda_input_mux alc262_HP_capture_source = {
10054 .num_items = 5,
10055 .items = {
10056 { "Mic", 0x0 },
accbe498 10057 { "Front Mic", 0x1 },
9c7f852e
TI
10058 { "Line", 0x2 },
10059 { "CD", 0x4 },
10060 { "AUX IN", 0x6 },
10061 },
10062};
10063
accbe498 10064static struct hda_input_mux alc262_HP_D7000_capture_source = {
10065 .num_items = 4,
10066 .items = {
10067 { "Mic", 0x0 },
10068 { "Front Mic", 0x2 },
10069 { "Line", 0x1 },
10070 { "CD", 0x4 },
10071 },
10072};
10073
ebc7a406 10074/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
10075static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10076{
10077 struct alc_spec *spec = codec->spec;
10078 unsigned int mute;
10079
f12ab1e0 10080 if (force || !spec->sense_updated) {
ebc7a406 10081 unsigned int present;
834be88d
TI
10082 /* need to execute and sync at first */
10083 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
ebc7a406
TI
10084 /* check laptop HP jack */
10085 present = snd_hda_codec_read(codec, 0x14, 0,
10086 AC_VERB_GET_PIN_SENSE, 0);
10087 /* need to execute and sync at first */
10088 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10089 /* check docking HP jack */
10090 present |= snd_hda_codec_read(codec, 0x1b, 0,
10091 AC_VERB_GET_PIN_SENSE, 0);
10092 if (present & AC_PINSENSE_PRESENCE)
10093 spec->jack_present = 1;
10094 else
10095 spec->jack_present = 0;
834be88d
TI
10096 spec->sense_updated = 1;
10097 }
ebc7a406
TI
10098 /* unmute internal speaker only if both HPs are unplugged and
10099 * master switch is on
10100 */
10101 if (spec->jack_present)
10102 mute = HDA_AMP_MUTE;
10103 else
834be88d 10104 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
10105 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10106 HDA_AMP_MUTE, mute);
834be88d
TI
10107}
10108
10109/* unsolicited event for HP jack sensing */
10110static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10111 unsigned int res)
10112{
10113 if ((res >> 26) != ALC_HP_EVENT)
10114 return;
10115 alc262_fujitsu_automute(codec, 1);
10116}
10117
ebc7a406
TI
10118static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10119{
10120 alc262_fujitsu_automute(codec, 1);
10121}
10122
834be88d 10123/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
10124static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10125 .ops = &snd_hda_bind_vol,
10126 .values = {
10127 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10128 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10129 0
10130 },
10131};
834be88d 10132
0e31daf7
J
10133/* mute/unmute internal speaker according to the hp jack and mute state */
10134static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10135{
10136 struct alc_spec *spec = codec->spec;
10137 unsigned int mute;
10138
10139 if (force || !spec->sense_updated) {
10140 unsigned int present_int_hp;
10141 /* need to execute and sync at first */
10142 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10143 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10144 AC_VERB_GET_PIN_SENSE, 0);
10145 spec->jack_present = (present_int_hp & 0x80000000) != 0;
10146 spec->sense_updated = 1;
10147 }
10148 if (spec->jack_present) {
10149 /* mute internal speaker */
10150 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10151 HDA_AMP_MUTE, HDA_AMP_MUTE);
10152 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10153 HDA_AMP_MUTE, HDA_AMP_MUTE);
10154 } else {
10155 /* unmute internal speaker if necessary */
10156 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10157 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10158 HDA_AMP_MUTE, mute);
10159 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10160 HDA_AMP_MUTE, mute);
10161 }
10162}
10163
10164/* unsolicited event for HP jack sensing */
10165static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10166 unsigned int res)
10167{
10168 if ((res >> 26) != ALC_HP_EVENT)
10169 return;
10170 alc262_lenovo_3000_automute(codec, 1);
10171}
10172
834be88d
TI
10173/* bind hp and internal speaker mute (with plug check) */
10174static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10175 struct snd_ctl_elem_value *ucontrol)
10176{
10177 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10178 long *valp = ucontrol->value.integer.value;
10179 int change;
10180
5d9fab2d
TV
10181 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10182 HDA_AMP_MUTE,
10183 valp ? 0 : HDA_AMP_MUTE);
10184 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10185 HDA_AMP_MUTE,
10186 valp ? 0 : HDA_AMP_MUTE);
10187
82beb8fd
TI
10188 if (change)
10189 alc262_fujitsu_automute(codec, 0);
834be88d
TI
10190 return change;
10191}
10192
10193static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 10194 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
10195 {
10196 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10197 .name = "Master Playback Switch",
10198 .info = snd_hda_mixer_amp_switch_info,
10199 .get = snd_hda_mixer_amp_switch_get,
10200 .put = alc262_fujitsu_master_sw_put,
10201 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10202 },
10203 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10204 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10205 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10206 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10207 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
10208 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10209 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10210 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
10211 { } /* end */
10212};
10213
0e31daf7
J
10214/* bind hp and internal speaker mute (with plug check) */
10215static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10216 struct snd_ctl_elem_value *ucontrol)
10217{
10218 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10219 long *valp = ucontrol->value.integer.value;
10220 int change;
10221
10222 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10223 HDA_AMP_MUTE,
10224 valp ? 0 : HDA_AMP_MUTE);
10225
10226 if (change)
10227 alc262_lenovo_3000_automute(codec, 0);
10228 return change;
10229}
10230
10231static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10232 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10233 {
10234 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10235 .name = "Master Playback Switch",
10236 .info = snd_hda_mixer_amp_switch_info,
10237 .get = snd_hda_mixer_amp_switch_get,
10238 .put = alc262_lenovo_3000_master_sw_put,
10239 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10240 },
10241 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10242 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10243 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10244 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10245 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10246 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10247 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10248 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10249 { } /* end */
10250};
10251
9f99a638
HM
10252static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10253 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 10254 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
10255 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10256 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10257 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10258 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10259 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10260 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10261 { } /* end */
10262};
10263
304dcaac
TI
10264/* additional init verbs for Benq laptops */
10265static struct hda_verb alc262_EAPD_verbs[] = {
10266 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10267 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10268 {}
10269};
10270
83c34218
KY
10271static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10272 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10273 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10274
10275 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10276 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10277 {}
10278};
10279
f651b50b
TD
10280/* Samsung Q1 Ultra Vista model setup */
10281static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
10282 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10283 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
10284 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10285 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10286 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 10287 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
10288 { } /* end */
10289};
10290
10291static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
10292 /* output mixer */
10293 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10294 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10295 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10296 /* speaker */
10297 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10298 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10299 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10300 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10301 /* HP */
f651b50b 10302 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
10303 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10304 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10305 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10306 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10307 /* internal mic */
10308 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10309 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10310 /* ADC, choose mic */
10311 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10312 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10313 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10314 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10315 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10316 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10317 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10318 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10319 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10320 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
10321 {}
10322};
10323
f651b50b
TD
10324/* mute/unmute internal speaker according to the hp jack and mute state */
10325static void alc262_ultra_automute(struct hda_codec *codec)
10326{
10327 struct alc_spec *spec = codec->spec;
10328 unsigned int mute;
f651b50b 10329
bb9f76cd
TI
10330 mute = 0;
10331 /* auto-mute only when HP is used as HP */
10332 if (!spec->cur_mux[0]) {
10333 unsigned int present;
10334 /* need to execute and sync at first */
10335 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10336 present = snd_hda_codec_read(codec, 0x15, 0,
10337 AC_VERB_GET_PIN_SENSE, 0);
10338 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10339 if (spec->jack_present)
10340 mute = HDA_AMP_MUTE;
f651b50b 10341 }
bb9f76cd
TI
10342 /* mute/unmute internal speaker */
10343 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10344 HDA_AMP_MUTE, mute);
10345 /* mute/unmute HP */
10346 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10347 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
10348}
10349
10350/* unsolicited event for HP jack sensing */
10351static void alc262_ultra_unsol_event(struct hda_codec *codec,
10352 unsigned int res)
10353{
10354 if ((res >> 26) != ALC880_HP_EVENT)
10355 return;
10356 alc262_ultra_automute(codec);
10357}
10358
bb9f76cd
TI
10359static struct hda_input_mux alc262_ultra_capture_source = {
10360 .num_items = 2,
10361 .items = {
10362 { "Mic", 0x1 },
10363 { "Headphone", 0x7 },
10364 },
10365};
10366
10367static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10368 struct snd_ctl_elem_value *ucontrol)
10369{
10370 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10371 struct alc_spec *spec = codec->spec;
10372 int ret;
10373
54cbc9ab 10374 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
10375 if (!ret)
10376 return 0;
10377 /* reprogram the HP pin as mic or HP according to the input source */
10378 snd_hda_codec_write_cache(codec, 0x15, 0,
10379 AC_VERB_SET_PIN_WIDGET_CONTROL,
10380 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10381 alc262_ultra_automute(codec); /* mute/unmute HP */
10382 return ret;
10383}
10384
10385static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10386 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10387 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10388 {
10389 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10390 .name = "Capture Source",
54cbc9ab
TI
10391 .info = alc_mux_enum_info,
10392 .get = alc_mux_enum_get,
bb9f76cd
TI
10393 .put = alc262_ultra_mux_enum_put,
10394 },
10395 { } /* end */
10396};
10397
df694daa 10398/* add playback controls from the parsed DAC table */
f12ab1e0
TI
10399static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10400 const struct auto_pin_cfg *cfg)
df694daa
KY
10401{
10402 hda_nid_t nid;
10403 int err;
10404
10405 spec->multiout.num_dacs = 1; /* only use one dac */
10406 spec->multiout.dac_nids = spec->private_dac_nids;
10407 spec->multiout.dac_nids[0] = 2;
10408
10409 nid = cfg->line_out_pins[0];
10410 if (nid) {
f12ab1e0
TI
10411 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10412 "Front Playback Volume",
10413 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10414 if (err < 0)
df694daa 10415 return err;
f12ab1e0
TI
10416 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10417 "Front Playback Switch",
10418 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10419 if (err < 0)
df694daa
KY
10420 return err;
10421 }
10422
82bc955f 10423 nid = cfg->speaker_pins[0];
df694daa
KY
10424 if (nid) {
10425 if (nid == 0x16) {
f12ab1e0
TI
10426 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10427 "Speaker Playback Volume",
10428 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10429 HDA_OUTPUT));
10430 if (err < 0)
df694daa 10431 return err;
f12ab1e0
TI
10432 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10433 "Speaker Playback Switch",
10434 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10435 HDA_OUTPUT));
10436 if (err < 0)
df694daa
KY
10437 return err;
10438 } else {
f12ab1e0
TI
10439 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10440 "Speaker Playback Switch",
10441 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10442 HDA_OUTPUT));
10443 if (err < 0)
df694daa
KY
10444 return err;
10445 }
10446 }
eb06ed8f 10447 nid = cfg->hp_pins[0];
df694daa
KY
10448 if (nid) {
10449 /* spec->multiout.hp_nid = 2; */
10450 if (nid == 0x16) {
f12ab1e0
TI
10451 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10452 "Headphone Playback Volume",
10453 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10454 HDA_OUTPUT));
10455 if (err < 0)
df694daa 10456 return err;
f12ab1e0
TI
10457 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10458 "Headphone Playback Switch",
10459 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10460 HDA_OUTPUT));
10461 if (err < 0)
df694daa
KY
10462 return err;
10463 } else {
f12ab1e0
TI
10464 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10465 "Headphone Playback Switch",
10466 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10467 HDA_OUTPUT));
10468 if (err < 0)
df694daa
KY
10469 return err;
10470 }
10471 }
f12ab1e0 10472 return 0;
df694daa
KY
10473}
10474
8c927b4a
TI
10475static int alc262_auto_create_analog_input_ctls(struct alc_spec *spec,
10476 const struct auto_pin_cfg *cfg)
10477{
10478 int err;
10479
10480 err = alc880_auto_create_analog_input_ctls(spec, cfg);
10481 if (err < 0)
10482 return err;
10483 /* digital-mic input pin is excluded in alc880_auto_create..()
10484 * because it's under 0x18
10485 */
10486 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
10487 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
10488 struct hda_input_mux *imux = &spec->private_imux[0];
10489 imux->items[imux->num_items].label = "Int Mic";
10490 imux->items[imux->num_items].index = 0x09;
10491 imux->num_items++;
10492 }
10493 return 0;
10494}
10495
df694daa
KY
10496
10497/*
10498 * generic initialization of ADC, input mixers and output mixers
10499 */
10500static struct hda_verb alc262_volume_init_verbs[] = {
10501 /*
10502 * Unmute ADC0-2 and set the default input to mic-in
10503 */
10504 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10505 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10506 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10507 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10508 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10509 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10510
cb53c626 10511 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 10512 * mixer widget
f12ab1e0
TI
10513 * Note: PASD motherboards uses the Line In 2 as the input for
10514 * front panel mic (mic 2)
df694daa
KY
10515 */
10516 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10517 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10518 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10519 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10520 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10521 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
10522
10523 /*
10524 * Set up output mixers (0x0c - 0x0f)
10525 */
10526 /* set vol=0 to output mixers */
10527 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10528 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10529 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 10530
df694daa
KY
10531 /* set up input amps for analog loopback */
10532 /* Amp Indices: DAC = 0, mixer = 1 */
10533 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10534 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10535 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10536 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10537 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10538 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10539
10540 /* FIXME: use matrix-type input source selection */
10541 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10542 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10543 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10544 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10545 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10546 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10547 /* Input mixer2 */
10548 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10549 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10550 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10551 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10552 /* Input mixer3 */
10553 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10554 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10555 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10556 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10557
10558 { }
10559};
10560
9c7f852e
TI
10561static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10562 /*
10563 * Unmute ADC0-2 and set the default input to mic-in
10564 */
10565 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10566 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10567 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10568 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10569 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10570 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10571
cb53c626 10572 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 10573 * mixer widget
f12ab1e0
TI
10574 * Note: PASD motherboards uses the Line In 2 as the input for
10575 * front panel mic (mic 2)
9c7f852e
TI
10576 */
10577 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10578 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10579 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10580 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10581 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10582 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10583 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10584 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 10585
9c7f852e
TI
10586 /*
10587 * Set up output mixers (0x0c - 0x0e)
10588 */
10589 /* set vol=0 to output mixers */
10590 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10591 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10592 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10593
10594 /* set up input amps for analog loopback */
10595 /* Amp Indices: DAC = 0, mixer = 1 */
10596 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10597 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10598 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10599 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10600 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10601 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10602
ce875f07 10603 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
10604 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10605 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10606
10607 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10608 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10609
10610 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10611 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10612
10613 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10614 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10615 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10616 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10617 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10618
0e4835c1 10619 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
10620 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10621 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 10622 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
10623 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10624 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10625
10626
10627 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
10628 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
10629 /* Input mixer1: only unmute Mic */
9c7f852e 10630 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
10631 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10632 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10633 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10634 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10635 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10636 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10637 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10638 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
10639 /* Input mixer2 */
10640 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
10641 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10642 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10643 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10644 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10645 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10646 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10647 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10648 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
10649 /* Input mixer3 */
10650 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
10651 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
10652 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10653 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10654 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10655 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
10656 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
10657 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
10658 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 10659
ce875f07
TI
10660 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10661
9c7f852e
TI
10662 { }
10663};
10664
cd7509a4
KY
10665static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10666 /*
10667 * Unmute ADC0-2 and set the default input to mic-in
10668 */
10669 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10670 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10671 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10672 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10673 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10674 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10675
cb53c626 10676 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
10677 * mixer widget
10678 * Note: PASD motherboards uses the Line In 2 as the input for front
10679 * panel mic (mic 2)
10680 */
10681 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10682 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10683 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10684 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10685 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10686 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10687 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10688 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10689 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
10690 /*
10691 * Set up output mixers (0x0c - 0x0e)
10692 */
10693 /* set vol=0 to output mixers */
10694 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10695 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10696 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10697
10698 /* set up input amps for analog loopback */
10699 /* Amp Indices: DAC = 0, mixer = 1 */
10700 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10701 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10702 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10703 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10704 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10705 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10706
10707
10708 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10709 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10710 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10711 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10712 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10713 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10714 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10715
10716 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10717 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10718
10719 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10720 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10721
10722 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10723 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10724 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10725 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10726 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10727 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10728
10729 /* FIXME: use matrix-type input source selection */
10730 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10731 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10732 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10733 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10734 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10735 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10736 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10737 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10738 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10739 /* Input mixer2 */
10740 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10741 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10742 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10743 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10744 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10745 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10746 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10747 /* Input mixer3 */
10748 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10749 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10750 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10751 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10752 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10753 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10754 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10755
ce875f07
TI
10756 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10757
cd7509a4
KY
10758 { }
10759};
10760
9f99a638
HM
10761static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10762
10763 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10764 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10765 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10766
10767 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10768 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10769 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10770 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10771
10772 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10773 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10774 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10775 {}
10776};
10777
10778
cb53c626
TI
10779#ifdef CONFIG_SND_HDA_POWER_SAVE
10780#define alc262_loopbacks alc880_loopbacks
10781#endif
10782
def319f9 10783/* pcm configuration: identical with ALC880 */
df694daa
KY
10784#define alc262_pcm_analog_playback alc880_pcm_analog_playback
10785#define alc262_pcm_analog_capture alc880_pcm_analog_capture
10786#define alc262_pcm_digital_playback alc880_pcm_digital_playback
10787#define alc262_pcm_digital_capture alc880_pcm_digital_capture
10788
10789/*
10790 * BIOS auto configuration
10791 */
10792static int alc262_parse_auto_config(struct hda_codec *codec)
10793{
10794 struct alc_spec *spec = codec->spec;
10795 int err;
10796 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10797
f12ab1e0
TI
10798 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10799 alc262_ignore);
10800 if (err < 0)
df694daa 10801 return err;
e64f14f4 10802 if (!spec->autocfg.line_outs) {
0852d7a6 10803 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
10804 spec->multiout.max_channels = 2;
10805 spec->no_analog = 1;
10806 goto dig_only;
10807 }
df694daa 10808 return 0; /* can't find valid BIOS pin config */
e64f14f4 10809 }
f12ab1e0
TI
10810 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10811 if (err < 0)
10812 return err;
10813 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10814 if (err < 0)
df694daa
KY
10815 return err;
10816
10817 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10818
e64f14f4 10819 dig_only:
0852d7a6 10820 if (spec->autocfg.dig_outs) {
df694daa 10821 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
0852d7a6 10822 spec->dig_out_type = spec->autocfg.dig_out_type[0];
e64f14f4 10823 }
df694daa
KY
10824 if (spec->autocfg.dig_in_pin)
10825 spec->dig_in_nid = ALC262_DIGIN_NID;
10826
603c4019 10827 if (spec->kctls.list)
d88897ea 10828 add_mixer(spec, spec->kctls.list);
df694daa 10829
d88897ea 10830 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 10831 spec->num_mux_defs = 1;
61b9b9b1 10832 spec->input_mux = &spec->private_imux[0];
df694daa 10833
776e184e
TI
10834 err = alc_auto_add_mic_boost(codec);
10835 if (err < 0)
10836 return err;
10837
4a79ba34
TI
10838 alc_ssid_check(codec, 0x15, 0x14, 0x1b);
10839
df694daa
KY
10840 return 1;
10841}
10842
10843#define alc262_auto_init_multi_out alc882_auto_init_multi_out
10844#define alc262_auto_init_hp_out alc882_auto_init_hp_out
10845#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 10846#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
10847
10848
10849/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 10850static void alc262_auto_init(struct hda_codec *codec)
df694daa 10851{
f6c7e546 10852 struct alc_spec *spec = codec->spec;
df694daa
KY
10853 alc262_auto_init_multi_out(codec);
10854 alc262_auto_init_hp_out(codec);
10855 alc262_auto_init_analog_input(codec);
f511b01c 10856 alc262_auto_init_input_src(codec);
f6c7e546 10857 if (spec->unsol_event)
7fb0d78f 10858 alc_inithook(codec);
df694daa
KY
10859}
10860
10861/*
10862 * configuration and preset
10863 */
f5fcc13c
TI
10864static const char *alc262_models[ALC262_MODEL_LAST] = {
10865 [ALC262_BASIC] = "basic",
10866 [ALC262_HIPPO] = "hippo",
10867 [ALC262_HIPPO_1] = "hippo_1",
10868 [ALC262_FUJITSU] = "fujitsu",
10869 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 10870 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 10871 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 10872 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 10873 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
10874 [ALC262_BENQ_T31] = "benq-t31",
10875 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 10876 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 10877 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 10878 [ALC262_ULTRA] = "ultra",
0e31daf7 10879 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 10880 [ALC262_NEC] = "nec",
ba340e82 10881 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
10882 [ALC262_AUTO] = "auto",
10883};
10884
10885static struct snd_pci_quirk alc262_cfg_tbl[] = {
10886 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 10887 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
10888 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
10889 ALC262_HP_BPC),
10890 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
10891 ALC262_HP_BPC),
53eff7e1
TI
10892 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
10893 ALC262_HP_BPC),
cd7509a4 10894 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10895 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 10896 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10897 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 10898 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10899 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 10900 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10901 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
10902 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10903 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10904 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
10905 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10906 ALC262_HP_TC_T5735),
8c427226 10907 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 10908 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 10909 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 10910 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 10911 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 10912 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
f872a919
TI
10913 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
10914 ALC262_SONY_ASSAMD),
36ca6e13 10915 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 10916 ALC262_TOSHIBA_RX1),
80ffe869 10917 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 10918 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 10919 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 10920 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
10921 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
10922 ALC262_ULTRA),
3e420e78 10923 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 10924 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
10925 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10926 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10927 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
10928 {}
10929};
10930
10931static struct alc_config_preset alc262_presets[] = {
10932 [ALC262_BASIC] = {
10933 .mixers = { alc262_base_mixer },
10934 .init_verbs = { alc262_init_verbs },
10935 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10936 .dac_nids = alc262_dac_nids,
10937 .hp_nid = 0x03,
10938 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10939 .channel_mode = alc262_modes,
a3bcba38 10940 .input_mux = &alc262_capture_source,
df694daa 10941 },
ccc656ce 10942 [ALC262_HIPPO] = {
42171c17 10943 .mixers = { alc262_hippo_mixer },
ccc656ce
KY
10944 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10945 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10946 .dac_nids = alc262_dac_nids,
10947 .hp_nid = 0x03,
10948 .dig_out_nid = ALC262_DIGOUT_NID,
10949 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10950 .channel_mode = alc262_modes,
10951 .input_mux = &alc262_capture_source,
10952 .unsol_event = alc262_hippo_unsol_event,
42171c17 10953 .init_hook = alc262_hippo_init_hook,
ccc656ce
KY
10954 },
10955 [ALC262_HIPPO_1] = {
10956 .mixers = { alc262_hippo1_mixer },
10957 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10958 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10959 .dac_nids = alc262_dac_nids,
10960 .hp_nid = 0x02,
10961 .dig_out_nid = ALC262_DIGOUT_NID,
10962 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10963 .channel_mode = alc262_modes,
10964 .input_mux = &alc262_capture_source,
42171c17
TI
10965 .unsol_event = alc262_hippo_unsol_event,
10966 .init_hook = alc262_hippo1_init_hook,
ccc656ce 10967 },
834be88d
TI
10968 [ALC262_FUJITSU] = {
10969 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
10970 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10971 alc262_fujitsu_unsol_verbs },
834be88d
TI
10972 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10973 .dac_nids = alc262_dac_nids,
10974 .hp_nid = 0x03,
10975 .dig_out_nid = ALC262_DIGOUT_NID,
10976 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10977 .channel_mode = alc262_modes,
10978 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 10979 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 10980 .init_hook = alc262_fujitsu_init_hook,
834be88d 10981 },
9c7f852e
TI
10982 [ALC262_HP_BPC] = {
10983 .mixers = { alc262_HP_BPC_mixer },
10984 .init_verbs = { alc262_HP_BPC_init_verbs },
10985 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10986 .dac_nids = alc262_dac_nids,
10987 .hp_nid = 0x03,
10988 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10989 .channel_mode = alc262_modes,
10990 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
10991 .unsol_event = alc262_hp_bpc_unsol_event,
10992 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 10993 },
cd7509a4
KY
10994 [ALC262_HP_BPC_D7000_WF] = {
10995 .mixers = { alc262_HP_BPC_WildWest_mixer },
10996 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10997 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10998 .dac_nids = alc262_dac_nids,
10999 .hp_nid = 0x03,
11000 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11001 .channel_mode = alc262_modes,
accbe498 11002 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
11003 .unsol_event = alc262_hp_wildwest_unsol_event,
11004 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 11005 },
cd7509a4
KY
11006 [ALC262_HP_BPC_D7000_WL] = {
11007 .mixers = { alc262_HP_BPC_WildWest_mixer,
11008 alc262_HP_BPC_WildWest_option_mixer },
11009 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11010 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11011 .dac_nids = alc262_dac_nids,
11012 .hp_nid = 0x03,
11013 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11014 .channel_mode = alc262_modes,
accbe498 11015 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
11016 .unsol_event = alc262_hp_wildwest_unsol_event,
11017 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 11018 },
66d2a9d6
KY
11019 [ALC262_HP_TC_T5735] = {
11020 .mixers = { alc262_hp_t5735_mixer },
11021 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11022 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11023 .dac_nids = alc262_dac_nids,
11024 .hp_nid = 0x03,
11025 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11026 .channel_mode = alc262_modes,
11027 .input_mux = &alc262_capture_source,
a9fd4f3f 11028 .unsol_event = alc_automute_amp_unsol_event,
66d2a9d6 11029 .init_hook = alc262_hp_t5735_init_hook,
8c427226
KY
11030 },
11031 [ALC262_HP_RP5700] = {
11032 .mixers = { alc262_hp_rp5700_mixer },
11033 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11034 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11035 .dac_nids = alc262_dac_nids,
11036 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11037 .channel_mode = alc262_modes,
11038 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 11039 },
304dcaac
TI
11040 [ALC262_BENQ_ED8] = {
11041 .mixers = { alc262_base_mixer },
11042 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11043 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11044 .dac_nids = alc262_dac_nids,
11045 .hp_nid = 0x03,
11046 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11047 .channel_mode = alc262_modes,
11048 .input_mux = &alc262_capture_source,
f12ab1e0 11049 },
272a527c
KY
11050 [ALC262_SONY_ASSAMD] = {
11051 .mixers = { alc262_sony_mixer },
11052 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11053 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11054 .dac_nids = alc262_dac_nids,
11055 .hp_nid = 0x02,
11056 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11057 .channel_mode = alc262_modes,
11058 .input_mux = &alc262_capture_source,
11059 .unsol_event = alc262_hippo_unsol_event,
42171c17 11060 .init_hook = alc262_hippo_init_hook,
83c34218
KY
11061 },
11062 [ALC262_BENQ_T31] = {
11063 .mixers = { alc262_benq_t31_mixer },
11064 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
11065 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11066 .dac_nids = alc262_dac_nids,
11067 .hp_nid = 0x03,
11068 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11069 .channel_mode = alc262_modes,
11070 .input_mux = &alc262_capture_source,
11071 .unsol_event = alc262_hippo_unsol_event,
42171c17 11072 .init_hook = alc262_hippo_init_hook,
ea1fb29a 11073 },
f651b50b 11074 [ALC262_ULTRA] = {
f9e336f6
TI
11075 .mixers = { alc262_ultra_mixer },
11076 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 11077 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
11078 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11079 .dac_nids = alc262_dac_nids,
f651b50b
TD
11080 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11081 .channel_mode = alc262_modes,
11082 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
11083 .adc_nids = alc262_adc_nids, /* ADC0 */
11084 .capsrc_nids = alc262_capsrc_nids,
11085 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
11086 .unsol_event = alc262_ultra_unsol_event,
11087 .init_hook = alc262_ultra_automute,
11088 },
0e31daf7
J
11089 [ALC262_LENOVO_3000] = {
11090 .mixers = { alc262_lenovo_3000_mixer },
11091 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11092 alc262_lenovo_3000_unsol_verbs },
11093 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11094 .dac_nids = alc262_dac_nids,
11095 .hp_nid = 0x03,
11096 .dig_out_nid = ALC262_DIGOUT_NID,
11097 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11098 .channel_mode = alc262_modes,
11099 .input_mux = &alc262_fujitsu_capture_source,
11100 .unsol_event = alc262_lenovo_3000_unsol_event,
11101 },
e8f9ae2a
PT
11102 [ALC262_NEC] = {
11103 .mixers = { alc262_nec_mixer },
11104 .init_verbs = { alc262_nec_verbs },
11105 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11106 .dac_nids = alc262_dac_nids,
11107 .hp_nid = 0x03,
11108 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11109 .channel_mode = alc262_modes,
11110 .input_mux = &alc262_capture_source,
11111 },
4e555fe5
KY
11112 [ALC262_TOSHIBA_S06] = {
11113 .mixers = { alc262_toshiba_s06_mixer },
11114 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11115 alc262_eapd_verbs },
11116 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11117 .capsrc_nids = alc262_dmic_capsrc_nids,
11118 .dac_nids = alc262_dac_nids,
11119 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 11120 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
11121 .dig_out_nid = ALC262_DIGOUT_NID,
11122 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11123 .channel_mode = alc262_modes,
11124 .input_mux = &alc262_dmic_capture_source,
11125 .unsol_event = alc262_toshiba_s06_unsol_event,
11126 .init_hook = alc262_toshiba_s06_init_hook,
11127 },
9f99a638
HM
11128 [ALC262_TOSHIBA_RX1] = {
11129 .mixers = { alc262_toshiba_rx1_mixer },
11130 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11131 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11132 .dac_nids = alc262_dac_nids,
11133 .hp_nid = 0x03,
11134 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11135 .channel_mode = alc262_modes,
11136 .input_mux = &alc262_capture_source,
11137 .unsol_event = alc262_hippo_unsol_event,
42171c17 11138 .init_hook = alc262_hippo_init_hook,
9f99a638 11139 },
ba340e82
TV
11140 [ALC262_TYAN] = {
11141 .mixers = { alc262_tyan_mixer },
11142 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11143 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11144 .dac_nids = alc262_dac_nids,
11145 .hp_nid = 0x02,
11146 .dig_out_nid = ALC262_DIGOUT_NID,
11147 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11148 .channel_mode = alc262_modes,
11149 .input_mux = &alc262_capture_source,
a9fd4f3f
TI
11150 .unsol_event = alc_automute_amp_unsol_event,
11151 .init_hook = alc262_tyan_init_hook,
ba340e82 11152 },
df694daa
KY
11153};
11154
11155static int patch_alc262(struct hda_codec *codec)
11156{
11157 struct alc_spec *spec;
11158 int board_config;
11159 int err;
11160
dc041e0b 11161 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
11162 if (spec == NULL)
11163 return -ENOMEM;
11164
11165 codec->spec = spec;
11166#if 0
f12ab1e0
TI
11167 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11168 * under-run
11169 */
df694daa
KY
11170 {
11171 int tmp;
11172 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11173 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11174 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11175 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11176 }
11177#endif
11178
2c3bf9ab
TI
11179 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11180
f5fcc13c
TI
11181 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11182 alc262_models,
11183 alc262_cfg_tbl);
cd7509a4 11184
f5fcc13c 11185 if (board_config < 0) {
6c627f39
TI
11186 printk(KERN_INFO "hda_codec: Unknown model for %s, "
11187 "trying auto-probe from BIOS...\n", codec->chip_name);
df694daa
KY
11188 board_config = ALC262_AUTO;
11189 }
11190
11191 if (board_config == ALC262_AUTO) {
11192 /* automatic parse from the BIOS config */
11193 err = alc262_parse_auto_config(codec);
11194 if (err < 0) {
11195 alc_free(codec);
11196 return err;
f12ab1e0 11197 } else if (!err) {
9c7f852e
TI
11198 printk(KERN_INFO
11199 "hda_codec: Cannot set up configuration "
11200 "from BIOS. Using base mode...\n");
df694daa
KY
11201 board_config = ALC262_BASIC;
11202 }
11203 }
11204
07eba61d
TI
11205 if (!spec->no_analog) {
11206 err = snd_hda_attach_beep_device(codec, 0x1);
11207 if (err < 0) {
11208 alc_free(codec);
11209 return err;
11210 }
680cd536
KK
11211 }
11212
df694daa
KY
11213 if (board_config != ALC262_AUTO)
11214 setup_preset(spec, &alc262_presets[board_config]);
11215
df694daa
KY
11216 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11217 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 11218
df694daa
KY
11219 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11220 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11221
f12ab1e0 11222 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
11223 int i;
11224 /* check whether the digital-mic has to be supported */
11225 for (i = 0; i < spec->input_mux->num_items; i++) {
11226 if (spec->input_mux->items[i].index >= 9)
11227 break;
11228 }
11229 if (i < spec->input_mux->num_items) {
11230 /* use only ADC0 */
11231 spec->adc_nids = alc262_dmic_adc_nids;
11232 spec->num_adc_nids = 1;
11233 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 11234 } else {
8c927b4a
TI
11235 /* all analog inputs */
11236 /* check whether NID 0x07 is valid */
11237 unsigned int wcap = get_wcaps(codec, 0x07);
11238
11239 /* get type */
11240 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11241 if (wcap != AC_WID_AUD_IN) {
11242 spec->adc_nids = alc262_adc_nids_alt;
11243 spec->num_adc_nids =
11244 ARRAY_SIZE(alc262_adc_nids_alt);
11245 spec->capsrc_nids = alc262_capsrc_nids_alt;
11246 } else {
11247 spec->adc_nids = alc262_adc_nids;
11248 spec->num_adc_nids =
11249 ARRAY_SIZE(alc262_adc_nids);
11250 spec->capsrc_nids = alc262_capsrc_nids;
11251 }
df694daa
KY
11252 }
11253 }
e64f14f4 11254 if (!spec->cap_mixer && !spec->no_analog)
f9e336f6 11255 set_capture_mixer(spec);
07eba61d
TI
11256 if (!spec->no_analog)
11257 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 11258
2134ea4f
TI
11259 spec->vmaster_nid = 0x0c;
11260
df694daa
KY
11261 codec->patch_ops = alc_patch_ops;
11262 if (board_config == ALC262_AUTO)
ae6b813a 11263 spec->init_hook = alc262_auto_init;
cb53c626
TI
11264#ifdef CONFIG_SND_HDA_POWER_SAVE
11265 if (!spec->loopback.amplist)
11266 spec->loopback.amplist = alc262_loopbacks;
11267#endif
daead538 11268 codec->proc_widget_hook = print_realtek_coef;
ea1fb29a 11269
df694daa
KY
11270 return 0;
11271}
11272
a361d84b
KY
11273/*
11274 * ALC268 channel source setting (2 channel)
11275 */
11276#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11277#define alc268_modes alc260_modes
ea1fb29a 11278
a361d84b
KY
11279static hda_nid_t alc268_dac_nids[2] = {
11280 /* front, hp */
11281 0x02, 0x03
11282};
11283
11284static hda_nid_t alc268_adc_nids[2] = {
11285 /* ADC0-1 */
11286 0x08, 0x07
11287};
11288
11289static hda_nid_t alc268_adc_nids_alt[1] = {
11290 /* ADC0 */
11291 0x08
11292};
11293
e1406348
TI
11294static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11295
a361d84b
KY
11296static struct snd_kcontrol_new alc268_base_mixer[] = {
11297 /* output mixer control */
11298 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11299 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11300 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11301 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
11302 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11303 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11304 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
11305 { }
11306};
11307
42171c17
TI
11308static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
11309 /* output mixer control */
11310 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11311 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11312 ALC262_HIPPO_MASTER_SWITCH,
11313 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11314 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11315 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11316 { }
11317};
11318
aef9d318
TI
11319/* bind Beep switches of both NID 0x0f and 0x10 */
11320static struct hda_bind_ctls alc268_bind_beep_sw = {
11321 .ops = &snd_hda_bind_sw,
11322 .values = {
11323 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11324 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11325 0
11326 },
11327};
11328
11329static struct snd_kcontrol_new alc268_beep_mixer[] = {
11330 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11331 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11332 { }
11333};
11334
d1a991a6
KY
11335static struct hda_verb alc268_eapd_verbs[] = {
11336 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11337 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11338 { }
11339};
11340
d273809e 11341/* Toshiba specific */
d273809e
TI
11342static struct hda_verb alc268_toshiba_verbs[] = {
11343 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11344 { } /* end */
11345};
11346
8ef355da
KY
11347static struct hda_input_mux alc268_acer_lc_capture_source = {
11348 .num_items = 2,
11349 .items = {
11350 { "i-Mic", 0x6 },
11351 { "E-Mic", 0x0 },
11352 },
11353};
11354
d273809e 11355/* Acer specific */
889c4395 11356/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
11357static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11358 .ops = &snd_hda_bind_vol,
11359 .values = {
11360 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11361 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11362 0
11363 },
11364};
11365
889c4395
TI
11366/* mute/unmute internal speaker according to the hp jack and mute state */
11367static void alc268_acer_automute(struct hda_codec *codec, int force)
11368{
11369 struct alc_spec *spec = codec->spec;
11370 unsigned int mute;
11371
11372 if (force || !spec->sense_updated) {
11373 unsigned int present;
11374 present = snd_hda_codec_read(codec, 0x14, 0,
11375 AC_VERB_GET_PIN_SENSE, 0);
11376 spec->jack_present = (present & 0x80000000) != 0;
11377 spec->sense_updated = 1;
11378 }
11379 if (spec->jack_present)
11380 mute = HDA_AMP_MUTE; /* mute internal speaker */
11381 else /* unmute internal speaker if necessary */
11382 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11383 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11384 HDA_AMP_MUTE, mute);
11385}
11386
11387
11388/* bind hp and internal speaker mute (with plug check) */
11389static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11390 struct snd_ctl_elem_value *ucontrol)
11391{
11392 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11393 long *valp = ucontrol->value.integer.value;
11394 int change;
11395
11396 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11397 HDA_AMP_MUTE,
11398 valp[0] ? 0 : HDA_AMP_MUTE);
11399 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11400 HDA_AMP_MUTE,
11401 valp[1] ? 0 : HDA_AMP_MUTE);
11402 if (change)
11403 alc268_acer_automute(codec, 0);
11404 return change;
11405}
d273809e 11406
8ef355da
KY
11407static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11408 /* output mixer control */
11409 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11410 {
11411 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11412 .name = "Master Playback Switch",
11413 .info = snd_hda_mixer_amp_switch_info,
11414 .get = snd_hda_mixer_amp_switch_get,
11415 .put = alc268_acer_master_sw_put,
11416 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11417 },
11418 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11419 { }
11420};
11421
d273809e
TI
11422static struct snd_kcontrol_new alc268_acer_mixer[] = {
11423 /* output mixer control */
11424 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11425 {
11426 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11427 .name = "Master Playback Switch",
11428 .info = snd_hda_mixer_amp_switch_info,
11429 .get = snd_hda_mixer_amp_switch_get,
11430 .put = alc268_acer_master_sw_put,
11431 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11432 },
33bf17ab
TI
11433 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11434 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11435 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
11436 { }
11437};
11438
c238b4f4
TI
11439static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11440 /* output mixer control */
11441 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11442 {
11443 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11444 .name = "Master Playback Switch",
11445 .info = snd_hda_mixer_amp_switch_info,
11446 .get = snd_hda_mixer_amp_switch_get,
11447 .put = alc268_acer_master_sw_put,
11448 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11449 },
11450 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11451 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11452 { }
11453};
11454
8ef355da
KY
11455static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11456 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11457 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11458 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11459 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11460 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11461 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11462 { }
11463};
11464
d273809e 11465static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
11466 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11467 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
11468 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11469 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
11470 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11471 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
11472 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11473 { }
11474};
11475
11476/* unsolicited event for HP jack sensing */
42171c17
TI
11477#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
11478#define alc268_toshiba_init_hook alc262_hippo_init_hook
d273809e
TI
11479
11480static void alc268_acer_unsol_event(struct hda_codec *codec,
11481 unsigned int res)
11482{
889c4395 11483 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
11484 return;
11485 alc268_acer_automute(codec, 1);
11486}
11487
889c4395
TI
11488static void alc268_acer_init_hook(struct hda_codec *codec)
11489{
11490 alc268_acer_automute(codec, 1);
11491}
11492
8ef355da
KY
11493/* toggle speaker-output according to the hp-jack state */
11494static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11495{
11496 unsigned int present;
11497 unsigned char bits;
11498
11499 present = snd_hda_codec_read(codec, 0x15, 0,
11500 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11501 bits = present ? AMP_IN_MUTE(0) : 0;
11502 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11503 AMP_IN_MUTE(0), bits);
11504 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11505 AMP_IN_MUTE(0), bits);
11506}
11507
11508
11509static void alc268_acer_mic_automute(struct hda_codec *codec)
11510{
11511 unsigned int present;
11512
11513 present = snd_hda_codec_read(codec, 0x18, 0,
11514 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11515 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11516 present ? 0x0 : 0x6);
11517}
11518
11519static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11520 unsigned int res)
11521{
11522 if ((res >> 26) == ALC880_HP_EVENT)
11523 alc268_aspire_one_speaker_automute(codec);
11524 if ((res >> 26) == ALC880_MIC_EVENT)
11525 alc268_acer_mic_automute(codec);
11526}
11527
11528static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11529{
11530 alc268_aspire_one_speaker_automute(codec);
11531 alc268_acer_mic_automute(codec);
11532}
11533
3866f0b0
TI
11534static struct snd_kcontrol_new alc268_dell_mixer[] = {
11535 /* output mixer control */
11536 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11537 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11538 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11539 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11540 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11541 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11542 { }
11543};
11544
11545static struct hda_verb alc268_dell_verbs[] = {
11546 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11547 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11548 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11549 { }
11550};
11551
11552/* mute/unmute internal speaker according to the hp jack and mute state */
a9fd4f3f 11553static void alc268_dell_init_hook(struct hda_codec *codec)
3866f0b0 11554{
a9fd4f3f 11555 struct alc_spec *spec = codec->spec;
3866f0b0 11556
a9fd4f3f
TI
11557 spec->autocfg.hp_pins[0] = 0x15;
11558 spec->autocfg.speaker_pins[0] = 0x14;
11559 alc_automute_pin(codec);
3866f0b0
TI
11560}
11561
eb5a6621
HRK
11562static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11563 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11564 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11565 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11566 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11567 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11568 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11569 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11570 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11571 { }
11572};
11573
11574static struct hda_verb alc267_quanta_il1_verbs[] = {
11575 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11576 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11577 { }
11578};
11579
eb5a6621
HRK
11580static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11581{
11582 unsigned int present;
11583
11584 present = snd_hda_codec_read(codec, 0x18, 0,
11585 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11586 snd_hda_codec_write(codec, 0x23, 0,
11587 AC_VERB_SET_CONNECT_SEL,
11588 present ? 0x00 : 0x01);
11589}
11590
a9fd4f3f 11591static void alc267_quanta_il1_init_hook(struct hda_codec *codec)
eb5a6621 11592{
a9fd4f3f
TI
11593 struct alc_spec *spec = codec->spec;
11594
11595 spec->autocfg.hp_pins[0] = 0x15;
11596 spec->autocfg.speaker_pins[0] = 0x14;
11597 alc_automute_pin(codec);
eb5a6621
HRK
11598 alc267_quanta_il1_mic_automute(codec);
11599}
11600
11601static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11602 unsigned int res)
11603{
11604 switch (res >> 26) {
eb5a6621
HRK
11605 case ALC880_MIC_EVENT:
11606 alc267_quanta_il1_mic_automute(codec);
11607 break;
a9fd4f3f
TI
11608 default:
11609 alc_sku_unsol_event(codec, res);
11610 break;
eb5a6621
HRK
11611 }
11612}
11613
a361d84b
KY
11614/*
11615 * generic initialization of ADC, input mixers and output mixers
11616 */
11617static struct hda_verb alc268_base_init_verbs[] = {
11618 /* Unmute DAC0-1 and set vol = 0 */
11619 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 11620 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
11621
11622 /*
11623 * Set up output mixers (0x0c - 0x0e)
11624 */
11625 /* set vol=0 to output mixers */
11626 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
11627 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11628
11629 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11630 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11631
11632 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11633 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11634 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11635 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11636 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11637 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11638 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11639 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11640
11641 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11642 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11643 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11644 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 11645 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
11646
11647 /* set PCBEEP vol = 0, mute connections */
11648 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11649 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11650 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 11651
a9b3aa8a 11652 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 11653
a9b3aa8a
JZ
11654 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11655 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11656 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11657 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 11658
a361d84b
KY
11659 { }
11660};
11661
11662/*
11663 * generic initialization of ADC, input mixers and output mixers
11664 */
11665static struct hda_verb alc268_volume_init_verbs[] = {
11666 /* set output DAC */
4cfb91c6
TI
11667 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11668 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
11669
11670 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11671 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11672 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11673 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11674 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11675
a361d84b 11676 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
11677 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11678 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11679
11680 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 11681 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 11682
aef9d318
TI
11683 /* set PCBEEP vol = 0, mute connections */
11684 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11685 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11686 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
11687
11688 { }
11689};
11690
a361d84b
KY
11691static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11692 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11693 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11694 {
11695 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11696 /* The multiple "Capture Source" controls confuse alsamixer
11697 * So call somewhat different..
a361d84b
KY
11698 */
11699 /* .name = "Capture Source", */
11700 .name = "Input Source",
11701 .count = 1,
54cbc9ab
TI
11702 .info = alc_mux_enum_info,
11703 .get = alc_mux_enum_get,
11704 .put = alc_mux_enum_put,
a361d84b
KY
11705 },
11706 { } /* end */
11707};
11708
11709static struct snd_kcontrol_new alc268_capture_mixer[] = {
11710 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11711 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11712 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11713 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11714 {
11715 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11716 /* The multiple "Capture Source" controls confuse alsamixer
11717 * So call somewhat different..
a361d84b
KY
11718 */
11719 /* .name = "Capture Source", */
11720 .name = "Input Source",
11721 .count = 2,
54cbc9ab
TI
11722 .info = alc_mux_enum_info,
11723 .get = alc_mux_enum_get,
11724 .put = alc_mux_enum_put,
a361d84b
KY
11725 },
11726 { } /* end */
11727};
11728
11729static struct hda_input_mux alc268_capture_source = {
11730 .num_items = 4,
11731 .items = {
11732 { "Mic", 0x0 },
11733 { "Front Mic", 0x1 },
11734 { "Line", 0x2 },
11735 { "CD", 0x3 },
11736 },
11737};
11738
0ccb541c 11739static struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
11740 .num_items = 3,
11741 .items = {
11742 { "Mic", 0x0 },
11743 { "Internal Mic", 0x1 },
11744 { "Line", 0x2 },
11745 },
11746};
11747
11748static struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
11749 .num_items = 3,
11750 .items = {
11751 { "Mic", 0x0 },
11752 { "Internal Mic", 0x6 },
11753 { "Line", 0x2 },
11754 },
11755};
11756
86c53bd2
JW
11757#ifdef CONFIG_SND_DEBUG
11758static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
11759 /* Volume widgets */
11760 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11761 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11762 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11763 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11764 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11765 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11766 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11767 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11768 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11769 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11770 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11771 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11772 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
11773 /* The below appears problematic on some hardwares */
11774 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
11775 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11776 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11777 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11778 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11779
11780 /* Modes for retasking pin widgets */
11781 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11782 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11783 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11784 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11785
11786 /* Controls for GPIO pins, assuming they are configured as outputs */
11787 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11788 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11789 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11790 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11791
11792 /* Switches to allow the digital SPDIF output pin to be enabled.
11793 * The ALC268 does not have an SPDIF input.
11794 */
11795 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11796
11797 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11798 * this output to turn on an external amplifier.
11799 */
11800 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11801 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11802
11803 { } /* end */
11804};
11805#endif
11806
a361d84b
KY
11807/* create input playback/capture controls for the given pin */
11808static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11809 const char *ctlname, int idx)
11810{
11811 char name[32];
11812 int err;
11813
11814 sprintf(name, "%s Playback Volume", ctlname);
11815 if (nid == 0x14) {
11816 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11817 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11818 HDA_OUTPUT));
11819 if (err < 0)
11820 return err;
11821 } else if (nid == 0x15) {
11822 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11823 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11824 HDA_OUTPUT));
11825 if (err < 0)
11826 return err;
11827 } else
11828 return -1;
11829 sprintf(name, "%s Playback Switch", ctlname);
11830 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11831 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11832 if (err < 0)
11833 return err;
11834 return 0;
11835}
11836
11837/* add playback controls from the parsed DAC table */
11838static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11839 const struct auto_pin_cfg *cfg)
11840{
11841 hda_nid_t nid;
11842 int err;
11843
11844 spec->multiout.num_dacs = 2; /* only use one dac */
11845 spec->multiout.dac_nids = spec->private_dac_nids;
11846 spec->multiout.dac_nids[0] = 2;
11847 spec->multiout.dac_nids[1] = 3;
11848
11849 nid = cfg->line_out_pins[0];
11850 if (nid)
ea1fb29a 11851 alc268_new_analog_output(spec, nid, "Front", 0);
a361d84b
KY
11852
11853 nid = cfg->speaker_pins[0];
11854 if (nid == 0x1d) {
11855 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11856 "Speaker Playback Volume",
11857 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11858 if (err < 0)
11859 return err;
11860 }
11861 nid = cfg->hp_pins[0];
11862 if (nid)
11863 alc268_new_analog_output(spec, nid, "Headphone", 0);
11864
11865 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11866 if (nid == 0x16) {
11867 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11868 "Mono Playback Switch",
11869 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11870 if (err < 0)
11871 return err;
11872 }
ea1fb29a 11873 return 0;
a361d84b
KY
11874}
11875
11876/* create playback/capture controls for input pins */
11877static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11878 const struct auto_pin_cfg *cfg)
11879{
61b9b9b1 11880 struct hda_input_mux *imux = &spec->private_imux[0];
a361d84b
KY
11881 int i, idx1;
11882
11883 for (i = 0; i < AUTO_PIN_LAST; i++) {
11884 switch(cfg->input_pins[i]) {
11885 case 0x18:
11886 idx1 = 0; /* Mic 1 */
11887 break;
11888 case 0x19:
11889 idx1 = 1; /* Mic 2 */
11890 break;
11891 case 0x1a:
11892 idx1 = 2; /* Line In */
11893 break;
ea1fb29a 11894 case 0x1c:
a361d84b
KY
11895 idx1 = 3; /* CD */
11896 break;
7194cae6
TI
11897 case 0x12:
11898 case 0x13:
11899 idx1 = 6; /* digital mics */
11900 break;
a361d84b
KY
11901 default:
11902 continue;
11903 }
11904 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11905 imux->items[imux->num_items].index = idx1;
ea1fb29a 11906 imux->num_items++;
a361d84b
KY
11907 }
11908 return 0;
11909}
11910
11911static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11912{
11913 struct alc_spec *spec = codec->spec;
11914 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11915 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11916 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11917 unsigned int dac_vol1, dac_vol2;
11918
11919 if (speaker_nid) {
11920 snd_hda_codec_write(codec, speaker_nid, 0,
11921 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11922 snd_hda_codec_write(codec, 0x0f, 0,
11923 AC_VERB_SET_AMP_GAIN_MUTE,
11924 AMP_IN_UNMUTE(1));
11925 snd_hda_codec_write(codec, 0x10, 0,
11926 AC_VERB_SET_AMP_GAIN_MUTE,
11927 AMP_IN_UNMUTE(1));
11928 } else {
11929 snd_hda_codec_write(codec, 0x0f, 0,
11930 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11931 snd_hda_codec_write(codec, 0x10, 0,
11932 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11933 }
11934
11935 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 11936 if (line_nid == 0x14)
a361d84b
KY
11937 dac_vol2 = AMP_OUT_ZERO;
11938 else if (line_nid == 0x15)
11939 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 11940 if (hp_nid == 0x14)
a361d84b
KY
11941 dac_vol2 = AMP_OUT_ZERO;
11942 else if (hp_nid == 0x15)
11943 dac_vol1 = AMP_OUT_ZERO;
11944 if (line_nid != 0x16 || hp_nid != 0x16 ||
11945 spec->autocfg.line_out_pins[1] != 0x16 ||
11946 spec->autocfg.line_out_pins[2] != 0x16)
11947 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11948
11949 snd_hda_codec_write(codec, 0x02, 0,
11950 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11951 snd_hda_codec_write(codec, 0x03, 0,
11952 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11953}
11954
def319f9 11955/* pcm configuration: identical with ALC880 */
a361d84b
KY
11956#define alc268_pcm_analog_playback alc880_pcm_analog_playback
11957#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 11958#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
11959#define alc268_pcm_digital_playback alc880_pcm_digital_playback
11960
11961/*
11962 * BIOS auto configuration
11963 */
11964static int alc268_parse_auto_config(struct hda_codec *codec)
11965{
11966 struct alc_spec *spec = codec->spec;
11967 int err;
11968 static hda_nid_t alc268_ignore[] = { 0 };
11969
11970 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11971 alc268_ignore);
11972 if (err < 0)
11973 return err;
7e0e44d4
TI
11974 if (!spec->autocfg.line_outs) {
11975 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
11976 spec->multiout.max_channels = 2;
11977 spec->no_analog = 1;
11978 goto dig_only;
11979 }
a361d84b 11980 return 0; /* can't find valid BIOS pin config */
7e0e44d4 11981 }
a361d84b
KY
11982 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11983 if (err < 0)
11984 return err;
11985 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11986 if (err < 0)
11987 return err;
11988
11989 spec->multiout.max_channels = 2;
11990
7e0e44d4 11991 dig_only:
a361d84b 11992 /* digital only support output */
7e0e44d4 11993 if (spec->autocfg.dig_outs) {
a361d84b 11994 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
7e0e44d4
TI
11995 spec->dig_out_type = spec->autocfg.dig_out_type[0];
11996 }
603c4019 11997 if (spec->kctls.list)
d88897ea 11998 add_mixer(spec, spec->kctls.list);
a361d84b 11999
892981ff 12000 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 12001 add_mixer(spec, alc268_beep_mixer);
aef9d318 12002
d88897ea 12003 add_verb(spec, alc268_volume_init_verbs);
a361d84b 12004 spec->num_mux_defs = 1;
61b9b9b1 12005 spec->input_mux = &spec->private_imux[0];
a361d84b 12006
776e184e
TI
12007 err = alc_auto_add_mic_boost(codec);
12008 if (err < 0)
12009 return err;
12010
1d955ebd
TI
12011 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
12012
a361d84b
KY
12013 return 1;
12014}
12015
12016#define alc268_auto_init_multi_out alc882_auto_init_multi_out
12017#define alc268_auto_init_hp_out alc882_auto_init_hp_out
12018#define alc268_auto_init_analog_input alc882_auto_init_analog_input
12019
12020/* init callback for auto-configuration model -- overriding the default init */
12021static void alc268_auto_init(struct hda_codec *codec)
12022{
f6c7e546 12023 struct alc_spec *spec = codec->spec;
a361d84b
KY
12024 alc268_auto_init_multi_out(codec);
12025 alc268_auto_init_hp_out(codec);
12026 alc268_auto_init_mono_speaker_out(codec);
12027 alc268_auto_init_analog_input(codec);
f6c7e546 12028 if (spec->unsol_event)
7fb0d78f 12029 alc_inithook(codec);
a361d84b
KY
12030}
12031
12032/*
12033 * configuration and preset
12034 */
12035static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 12036 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 12037 [ALC268_3ST] = "3stack",
983f8ae4 12038 [ALC268_TOSHIBA] = "toshiba",
d273809e 12039 [ALC268_ACER] = "acer",
c238b4f4 12040 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 12041 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 12042 [ALC268_DELL] = "dell",
f12462c5 12043 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
12044#ifdef CONFIG_SND_DEBUG
12045 [ALC268_TEST] = "test",
12046#endif
a361d84b
KY
12047 [ALC268_AUTO] = "auto",
12048};
12049
12050static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 12051 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 12052 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 12053 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 12054 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 12055 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
12056 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12057 ALC268_ACER_ASPIRE_ONE),
3866f0b0 12058 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
57d13927 12059 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
8871e5b9
TI
12060 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
12061 ALC268_TOSHIBA),
a361d84b 12062 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9
TI
12063 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12064 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
12065 ALC268_TOSHIBA),
378bd6a5 12066 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 12067 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 12068 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
8871e5b9 12069 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
a361d84b
KY
12070 {}
12071};
12072
12073static struct alc_config_preset alc268_presets[] = {
eb5a6621 12074 [ALC267_QUANTA_IL1] = {
22971e3a 12075 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
eb5a6621
HRK
12076 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12077 alc267_quanta_il1_verbs },
12078 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12079 .dac_nids = alc268_dac_nids,
12080 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12081 .adc_nids = alc268_adc_nids_alt,
12082 .hp_nid = 0x03,
12083 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12084 .channel_mode = alc268_modes,
12085 .input_mux = &alc268_capture_source,
12086 .unsol_event = alc267_quanta_il1_unsol_event,
a9fd4f3f 12087 .init_hook = alc267_quanta_il1_init_hook,
eb5a6621 12088 },
a361d84b 12089 [ALC268_3ST] = {
aef9d318
TI
12090 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12091 alc268_beep_mixer },
a361d84b
KY
12092 .init_verbs = { alc268_base_init_verbs },
12093 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12094 .dac_nids = alc268_dac_nids,
12095 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12096 .adc_nids = alc268_adc_nids_alt,
e1406348 12097 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
12098 .hp_nid = 0x03,
12099 .dig_out_nid = ALC268_DIGOUT_NID,
12100 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12101 .channel_mode = alc268_modes,
12102 .input_mux = &alc268_capture_source,
12103 },
d1a991a6 12104 [ALC268_TOSHIBA] = {
42171c17 12105 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 12106 alc268_beep_mixer },
d273809e
TI
12107 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12108 alc268_toshiba_verbs },
d1a991a6
KY
12109 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12110 .dac_nids = alc268_dac_nids,
12111 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12112 .adc_nids = alc268_adc_nids_alt,
e1406348 12113 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
12114 .hp_nid = 0x03,
12115 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12116 .channel_mode = alc268_modes,
12117 .input_mux = &alc268_capture_source,
d273809e 12118 .unsol_event = alc268_toshiba_unsol_event,
42171c17 12119 .init_hook = alc268_toshiba_init_hook,
d273809e
TI
12120 },
12121 [ALC268_ACER] = {
aef9d318
TI
12122 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12123 alc268_beep_mixer },
d273809e
TI
12124 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12125 alc268_acer_verbs },
12126 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12127 .dac_nids = alc268_dac_nids,
12128 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12129 .adc_nids = alc268_adc_nids_alt,
e1406348 12130 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
12131 .hp_nid = 0x02,
12132 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12133 .channel_mode = alc268_modes,
0ccb541c 12134 .input_mux = &alc268_acer_capture_source,
d273809e 12135 .unsol_event = alc268_acer_unsol_event,
889c4395 12136 .init_hook = alc268_acer_init_hook,
d1a991a6 12137 },
c238b4f4
TI
12138 [ALC268_ACER_DMIC] = {
12139 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12140 alc268_beep_mixer },
12141 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12142 alc268_acer_verbs },
12143 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12144 .dac_nids = alc268_dac_nids,
12145 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12146 .adc_nids = alc268_adc_nids_alt,
12147 .capsrc_nids = alc268_capsrc_nids,
12148 .hp_nid = 0x02,
12149 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12150 .channel_mode = alc268_modes,
12151 .input_mux = &alc268_acer_dmic_capture_source,
12152 .unsol_event = alc268_acer_unsol_event,
12153 .init_hook = alc268_acer_init_hook,
12154 },
8ef355da
KY
12155 [ALC268_ACER_ASPIRE_ONE] = {
12156 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a
TI
12157 alc268_beep_mixer,
12158 alc268_capture_alt_mixer },
8ef355da
KY
12159 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12160 alc268_acer_aspire_one_verbs },
12161 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12162 .dac_nids = alc268_dac_nids,
12163 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12164 .adc_nids = alc268_adc_nids_alt,
12165 .capsrc_nids = alc268_capsrc_nids,
12166 .hp_nid = 0x03,
12167 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12168 .channel_mode = alc268_modes,
12169 .input_mux = &alc268_acer_lc_capture_source,
12170 .unsol_event = alc268_acer_lc_unsol_event,
12171 .init_hook = alc268_acer_lc_init_hook,
12172 },
3866f0b0 12173 [ALC268_DELL] = {
aef9d318 12174 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
3866f0b0
TI
12175 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12176 alc268_dell_verbs },
12177 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12178 .dac_nids = alc268_dac_nids,
12179 .hp_nid = 0x02,
12180 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12181 .channel_mode = alc268_modes,
a9fd4f3f 12182 .unsol_event = alc_sku_unsol_event,
3866f0b0
TI
12183 .init_hook = alc268_dell_init_hook,
12184 .input_mux = &alc268_capture_source,
12185 },
f12462c5 12186 [ALC268_ZEPTO] = {
aef9d318
TI
12187 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12188 alc268_beep_mixer },
f12462c5
MT
12189 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12190 alc268_toshiba_verbs },
12191 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12192 .dac_nids = alc268_dac_nids,
12193 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12194 .adc_nids = alc268_adc_nids_alt,
e1406348 12195 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
12196 .hp_nid = 0x03,
12197 .dig_out_nid = ALC268_DIGOUT_NID,
12198 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12199 .channel_mode = alc268_modes,
12200 .input_mux = &alc268_capture_source,
12201 .unsol_event = alc268_toshiba_unsol_event,
42171c17 12202 .init_hook = alc268_toshiba_init_hook
f12462c5 12203 },
86c53bd2
JW
12204#ifdef CONFIG_SND_DEBUG
12205 [ALC268_TEST] = {
12206 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12207 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12208 alc268_volume_init_verbs },
12209 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12210 .dac_nids = alc268_dac_nids,
12211 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12212 .adc_nids = alc268_adc_nids_alt,
e1406348 12213 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
12214 .hp_nid = 0x03,
12215 .dig_out_nid = ALC268_DIGOUT_NID,
12216 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12217 .channel_mode = alc268_modes,
12218 .input_mux = &alc268_capture_source,
12219 },
12220#endif
a361d84b
KY
12221};
12222
12223static int patch_alc268(struct hda_codec *codec)
12224{
12225 struct alc_spec *spec;
12226 int board_config;
22971e3a 12227 int i, has_beep, err;
a361d84b
KY
12228
12229 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12230 if (spec == NULL)
12231 return -ENOMEM;
12232
12233 codec->spec = spec;
12234
12235 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12236 alc268_models,
12237 alc268_cfg_tbl);
12238
12239 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
6c627f39
TI
12240 printk(KERN_INFO "hda_codec: Unknown model for %s, "
12241 "trying auto-probe from BIOS...\n", codec->chip_name);
a361d84b
KY
12242 board_config = ALC268_AUTO;
12243 }
12244
12245 if (board_config == ALC268_AUTO) {
12246 /* automatic parse from the BIOS config */
12247 err = alc268_parse_auto_config(codec);
12248 if (err < 0) {
12249 alc_free(codec);
12250 return err;
12251 } else if (!err) {
12252 printk(KERN_INFO
12253 "hda_codec: Cannot set up configuration "
12254 "from BIOS. Using base mode...\n");
12255 board_config = ALC268_3ST;
12256 }
12257 }
12258
12259 if (board_config != ALC268_AUTO)
12260 setup_preset(spec, &alc268_presets[board_config]);
12261
a361d84b
KY
12262 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12263 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 12264 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 12265
a361d84b
KY
12266 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12267
22971e3a
TI
12268 has_beep = 0;
12269 for (i = 0; i < spec->num_mixers; i++) {
12270 if (spec->mixers[i] == alc268_beep_mixer) {
12271 has_beep = 1;
12272 break;
12273 }
12274 }
12275
12276 if (has_beep) {
12277 err = snd_hda_attach_beep_device(codec, 0x1);
12278 if (err < 0) {
12279 alc_free(codec);
12280 return err;
12281 }
12282 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12283 /* override the amp caps for beep generator */
12284 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
12285 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12286 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12287 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12288 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 12289 }
aef9d318 12290
7e0e44d4 12291 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
12292 /* check whether NID 0x07 is valid */
12293 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 12294 int i;
3866f0b0
TI
12295
12296 /* get type */
12297 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
67ebcb03 12298 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
12299 spec->adc_nids = alc268_adc_nids_alt;
12300 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
d88897ea 12301 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
12302 } else {
12303 spec->adc_nids = alc268_adc_nids;
12304 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 12305 add_mixer(spec, alc268_capture_mixer);
a361d84b 12306 }
e1406348 12307 spec->capsrc_nids = alc268_capsrc_nids;
85860c06
TI
12308 /* set default input source */
12309 for (i = 0; i < spec->num_adc_nids; i++)
12310 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12311 0, AC_VERB_SET_CONNECT_SEL,
12312 spec->input_mux->items[0].index);
a361d84b 12313 }
2134ea4f
TI
12314
12315 spec->vmaster_nid = 0x02;
12316
a361d84b
KY
12317 codec->patch_ops = alc_patch_ops;
12318 if (board_config == ALC268_AUTO)
12319 spec->init_hook = alc268_auto_init;
ea1fb29a 12320
daead538
TI
12321 codec->proc_widget_hook = print_realtek_coef;
12322
a361d84b
KY
12323 return 0;
12324}
12325
f6a92248
KY
12326/*
12327 * ALC269 channel source setting (2 channel)
12328 */
12329#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12330
12331#define alc269_dac_nids alc260_dac_nids
12332
12333static hda_nid_t alc269_adc_nids[1] = {
12334 /* ADC1 */
f53281e6
KY
12335 0x08,
12336};
12337
e01bf509
TI
12338static hda_nid_t alc269_capsrc_nids[1] = {
12339 0x23,
12340};
12341
12342/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12343 * not a mux!
12344 */
12345
f53281e6
KY
12346static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12347 .num_items = 2,
12348 .items = {
12349 { "i-Mic", 0x5 },
12350 { "e-Mic", 0x0 },
12351 },
12352};
12353
12354static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12355 .num_items = 2,
12356 .items = {
12357 { "i-Mic", 0x1 },
12358 { "e-Mic", 0x0 },
12359 },
f6a92248
KY
12360};
12361
12362#define alc269_modes alc260_modes
12363#define alc269_capture_source alc880_lg_lw_capture_source
12364
12365static struct snd_kcontrol_new alc269_base_mixer[] = {
12366 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12367 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12368 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12369 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12371 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12372 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12373 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12374 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12375 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12376 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12377 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12378 { } /* end */
12379};
12380
60db6b53
KY
12381static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12382 /* output mixer control */
12383 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12384 {
12385 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12386 .name = "Master Playback Switch",
12387 .info = snd_hda_mixer_amp_switch_info,
12388 .get = snd_hda_mixer_amp_switch_get,
12389 .put = alc268_acer_master_sw_put,
12390 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12391 },
12392 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12393 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12394 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12395 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12396 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12397 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
60db6b53
KY
12398 { }
12399};
12400
64154835
TV
12401static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12402 /* output mixer control */
12403 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12404 {
12405 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12406 .name = "Master Playback Switch",
12407 .info = snd_hda_mixer_amp_switch_info,
12408 .get = snd_hda_mixer_amp_switch_get,
12409 .put = alc268_acer_master_sw_put,
12410 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12411 },
12412 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12413 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12414 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12415 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12416 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12417 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12418 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12419 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12420 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
64154835
TV
12421 { }
12422};
12423
f53281e6
KY
12424/* bind volumes of both NID 0x0c and 0x0d */
12425static struct hda_bind_ctls alc269_epc_bind_vol = {
12426 .ops = &snd_hda_bind_vol,
12427 .values = {
12428 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12429 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12430 0
12431 },
12432};
12433
12434static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12435 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12436 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
12437 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12438 { } /* end */
12439};
12440
f53281e6
KY
12441/* capture mixer elements */
12442static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12443 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12444 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
26f5df26
TI
12445 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12446 { } /* end */
12447};
12448
12449/* FSC amilo */
12450static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
12451 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12452 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12453 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
f53281e6
KY
12454 { } /* end */
12455};
12456
60db6b53
KY
12457static struct hda_verb alc269_quanta_fl1_verbs[] = {
12458 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12459 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12460 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12461 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12462 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12463 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12464 { }
12465};
f6a92248 12466
64154835
TV
12467static struct hda_verb alc269_lifebook_verbs[] = {
12468 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12469 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12470 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12471 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12472 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12473 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12474 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12475 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12476 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12477 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12478 { }
12479};
12480
60db6b53
KY
12481/* toggle speaker-output according to the hp-jack state */
12482static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12483{
12484 unsigned int present;
12485 unsigned char bits;
f6a92248 12486
60db6b53
KY
12487 present = snd_hda_codec_read(codec, 0x15, 0,
12488 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12489 bits = present ? AMP_IN_MUTE(0) : 0;
12490 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12491 AMP_IN_MUTE(0), bits);
12492 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12493 AMP_IN_MUTE(0), bits);
f6a92248 12494
60db6b53
KY
12495 snd_hda_codec_write(codec, 0x20, 0,
12496 AC_VERB_SET_COEF_INDEX, 0x0c);
12497 snd_hda_codec_write(codec, 0x20, 0,
12498 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 12499
60db6b53
KY
12500 snd_hda_codec_write(codec, 0x20, 0,
12501 AC_VERB_SET_COEF_INDEX, 0x0c);
12502 snd_hda_codec_write(codec, 0x20, 0,
12503 AC_VERB_SET_PROC_COEF, 0x480);
12504}
f6a92248 12505
64154835
TV
12506/* toggle speaker-output according to the hp-jacks state */
12507static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12508{
12509 unsigned int present;
12510 unsigned char bits;
12511
12512 /* Check laptop headphone socket */
12513 present = snd_hda_codec_read(codec, 0x15, 0,
12514 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12515
12516 /* Check port replicator headphone socket */
12517 present |= snd_hda_codec_read(codec, 0x1a, 0,
12518 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12519
12520 bits = present ? AMP_IN_MUTE(0) : 0;
12521 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12522 AMP_IN_MUTE(0), bits);
12523 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12524 AMP_IN_MUTE(0), bits);
12525
12526 snd_hda_codec_write(codec, 0x20, 0,
12527 AC_VERB_SET_COEF_INDEX, 0x0c);
12528 snd_hda_codec_write(codec, 0x20, 0,
12529 AC_VERB_SET_PROC_COEF, 0x680);
12530
12531 snd_hda_codec_write(codec, 0x20, 0,
12532 AC_VERB_SET_COEF_INDEX, 0x0c);
12533 snd_hda_codec_write(codec, 0x20, 0,
12534 AC_VERB_SET_PROC_COEF, 0x480);
12535}
12536
60db6b53
KY
12537static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12538{
12539 unsigned int present;
f6a92248 12540
60db6b53
KY
12541 present = snd_hda_codec_read(codec, 0x18, 0,
12542 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12543 snd_hda_codec_write(codec, 0x23, 0,
12544 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12545}
f6a92248 12546
64154835
TV
12547static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12548{
12549 unsigned int present_laptop;
12550 unsigned int present_dock;
12551
12552 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12553 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12554
12555 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12556 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12557
12558 /* Laptop mic port overrides dock mic port, design decision */
12559 if (present_dock)
12560 snd_hda_codec_write(codec, 0x23, 0,
12561 AC_VERB_SET_CONNECT_SEL, 0x3);
12562 if (present_laptop)
12563 snd_hda_codec_write(codec, 0x23, 0,
12564 AC_VERB_SET_CONNECT_SEL, 0x0);
12565 if (!present_dock && !present_laptop)
12566 snd_hda_codec_write(codec, 0x23, 0,
12567 AC_VERB_SET_CONNECT_SEL, 0x1);
12568}
12569
60db6b53
KY
12570static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12571 unsigned int res)
12572{
12573 if ((res >> 26) == ALC880_HP_EVENT)
12574 alc269_quanta_fl1_speaker_automute(codec);
12575 if ((res >> 26) == ALC880_MIC_EVENT)
12576 alc269_quanta_fl1_mic_automute(codec);
12577}
f6a92248 12578
64154835
TV
12579static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12580 unsigned int res)
12581{
12582 if ((res >> 26) == ALC880_HP_EVENT)
12583 alc269_lifebook_speaker_automute(codec);
12584 if ((res >> 26) == ALC880_MIC_EVENT)
12585 alc269_lifebook_mic_autoswitch(codec);
12586}
12587
60db6b53
KY
12588static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12589{
12590 alc269_quanta_fl1_speaker_automute(codec);
12591 alc269_quanta_fl1_mic_automute(codec);
12592}
f6a92248 12593
64154835
TV
12594static void alc269_lifebook_init_hook(struct hda_codec *codec)
12595{
12596 alc269_lifebook_speaker_automute(codec);
12597 alc269_lifebook_mic_autoswitch(codec);
12598}
12599
f53281e6
KY
12600static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12601 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12602 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12603 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12604 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12605 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12606 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12607 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12608 {}
12609};
12610
12611static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12612 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12613 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12614 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12615 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12616 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12617 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12618 {}
12619};
12620
12621/* toggle speaker-output according to the hp-jack state */
12622static void alc269_speaker_automute(struct hda_codec *codec)
12623{
12624 unsigned int present;
60db6b53 12625 unsigned char bits;
f53281e6
KY
12626
12627 present = snd_hda_codec_read(codec, 0x15, 0,
60db6b53 12628 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
f53281e6
KY
12629 bits = present ? AMP_IN_MUTE(0) : 0;
12630 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
60db6b53 12631 AMP_IN_MUTE(0), bits);
f53281e6 12632 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
60db6b53 12633 AMP_IN_MUTE(0), bits);
f53281e6
KY
12634}
12635
12636static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12637{
12638 unsigned int present;
12639
60db6b53
KY
12640 present = snd_hda_codec_read(codec, 0x18, 0,
12641 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12642 snd_hda_codec_write(codec, 0x23, 0,
12643 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
f53281e6
KY
12644}
12645
12646static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12647{
12648 unsigned int present;
12649
60db6b53
KY
12650 present = snd_hda_codec_read(codec, 0x18, 0,
12651 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
f53281e6 12652 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
60db6b53 12653 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
f53281e6 12654 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
60db6b53 12655 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
f53281e6
KY
12656}
12657
12658/* unsolicited event for HP jack sensing */
12659static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
60db6b53 12660 unsigned int res)
f53281e6
KY
12661{
12662 if ((res >> 26) == ALC880_HP_EVENT)
12663 alc269_speaker_automute(codec);
12664
12665 if ((res >> 26) == ALC880_MIC_EVENT)
12666 alc269_eeepc_dmic_automute(codec);
12667}
12668
12669static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12670{
12671 alc269_speaker_automute(codec);
12672 alc269_eeepc_dmic_automute(codec);
12673}
12674
12675/* unsolicited event for HP jack sensing */
12676static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
ea1fb29a 12677 unsigned int res)
f53281e6
KY
12678{
12679 if ((res >> 26) == ALC880_HP_EVENT)
12680 alc269_speaker_automute(codec);
12681
12682 if ((res >> 26) == ALC880_MIC_EVENT)
12683 alc269_eeepc_amic_automute(codec);
12684}
12685
12686static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12687{
12688 alc269_speaker_automute(codec);
12689 alc269_eeepc_amic_automute(codec);
12690}
12691
60db6b53
KY
12692/*
12693 * generic initialization of ADC, input mixers and output mixers
12694 */
12695static struct hda_verb alc269_init_verbs[] = {
12696 /*
12697 * Unmute ADC0 and set the default input to mic-in
12698 */
12699 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12700
12701 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12702 * analog-loopback mixer widget
12703 * Note: PASD motherboards uses the Line In 2 as the input for
12704 * front panel mic (mic 2)
12705 */
12706 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12707 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12708 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12709 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12710 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12711 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12712
12713 /*
12714 * Set up output mixers (0x0c - 0x0e)
12715 */
12716 /* set vol=0 to output mixers */
12717 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12718 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12719
12720 /* set up input amps for analog loopback */
12721 /* Amp Indices: DAC = 0, mixer = 1 */
12722 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12723 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12724 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12725 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12726 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12727 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12728
12729 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12730 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12731 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12732 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12733 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12734 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12735 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12736
12737 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12738 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12739 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12740 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12741 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12742 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12743 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12744
12745 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12746 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12747
12748 /* FIXME: use matrix-type input source selection */
12749 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12750 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12751 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12752 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12753 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12754 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12755
12756 /* set EAPD */
12757 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12758 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12759 { }
12760};
12761
f6a92248
KY
12762/* add playback controls from the parsed DAC table */
12763static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12764 const struct auto_pin_cfg *cfg)
12765{
12766 hda_nid_t nid;
12767 int err;
12768
12769 spec->multiout.num_dacs = 1; /* only use one dac */
12770 spec->multiout.dac_nids = spec->private_dac_nids;
12771 spec->multiout.dac_nids[0] = 2;
12772
12773 nid = cfg->line_out_pins[0];
12774 if (nid) {
12775 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12776 "Front Playback Volume",
12777 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12778 if (err < 0)
12779 return err;
12780 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12781 "Front Playback Switch",
12782 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12783 if (err < 0)
12784 return err;
12785 }
12786
12787 nid = cfg->speaker_pins[0];
12788 if (nid) {
12789 if (!cfg->line_out_pins[0]) {
12790 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12791 "Speaker Playback Volume",
12792 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12793 HDA_OUTPUT));
12794 if (err < 0)
12795 return err;
12796 }
12797 if (nid == 0x16) {
12798 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12799 "Speaker Playback Switch",
12800 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12801 HDA_OUTPUT));
12802 if (err < 0)
12803 return err;
12804 } else {
12805 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12806 "Speaker Playback Switch",
12807 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12808 HDA_OUTPUT));
12809 if (err < 0)
12810 return err;
12811 }
12812 }
12813 nid = cfg->hp_pins[0];
12814 if (nid) {
12815 /* spec->multiout.hp_nid = 2; */
12816 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12817 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12818 "Headphone Playback Volume",
12819 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12820 HDA_OUTPUT));
12821 if (err < 0)
12822 return err;
12823 }
12824 if (nid == 0x16) {
12825 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12826 "Headphone Playback Switch",
12827 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12828 HDA_OUTPUT));
12829 if (err < 0)
12830 return err;
12831 } else {
12832 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12833 "Headphone Playback Switch",
12834 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12835 HDA_OUTPUT));
12836 if (err < 0)
12837 return err;
12838 }
12839 }
12840 return 0;
12841}
12842
8c927b4a
TI
12843#define alc269_auto_create_analog_input_ctls \
12844 alc262_auto_create_analog_input_ctls
f6a92248
KY
12845
12846#ifdef CONFIG_SND_HDA_POWER_SAVE
12847#define alc269_loopbacks alc880_loopbacks
12848#endif
12849
def319f9 12850/* pcm configuration: identical with ALC880 */
f6a92248
KY
12851#define alc269_pcm_analog_playback alc880_pcm_analog_playback
12852#define alc269_pcm_analog_capture alc880_pcm_analog_capture
12853#define alc269_pcm_digital_playback alc880_pcm_digital_playback
12854#define alc269_pcm_digital_capture alc880_pcm_digital_capture
12855
f03d3115
TI
12856static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
12857 .substreams = 1,
12858 .channels_min = 2,
12859 .channels_max = 8,
12860 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12861 /* NID is set in alc_build_pcms */
12862 .ops = {
12863 .open = alc880_playback_pcm_open,
12864 .prepare = alc880_playback_pcm_prepare,
12865 .cleanup = alc880_playback_pcm_cleanup
12866 },
12867};
12868
12869static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
12870 .substreams = 1,
12871 .channels_min = 2,
12872 .channels_max = 2,
12873 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12874 /* NID is set in alc_build_pcms */
12875};
12876
f6a92248
KY
12877/*
12878 * BIOS auto configuration
12879 */
12880static int alc269_parse_auto_config(struct hda_codec *codec)
12881{
12882 struct alc_spec *spec = codec->spec;
cfb9fb55 12883 int err;
f6a92248
KY
12884 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12885
12886 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12887 alc269_ignore);
12888 if (err < 0)
12889 return err;
12890
12891 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12892 if (err < 0)
12893 return err;
12894 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12895 if (err < 0)
12896 return err;
12897
12898 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12899
0852d7a6 12900 if (spec->autocfg.dig_outs)
f6a92248
KY
12901 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12902
603c4019 12903 if (spec->kctls.list)
d88897ea 12904 add_mixer(spec, spec->kctls.list);
f6a92248 12905
d88897ea 12906 add_verb(spec, alc269_init_verbs);
f6a92248 12907 spec->num_mux_defs = 1;
61b9b9b1 12908 spec->input_mux = &spec->private_imux[0];
e01bf509
TI
12909 /* set default input source */
12910 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12911 0, AC_VERB_SET_CONNECT_SEL,
12912 spec->input_mux->items[0].index);
f6a92248
KY
12913
12914 err = alc_auto_add_mic_boost(codec);
12915 if (err < 0)
12916 return err;
12917
7e0e44d4 12918 if (!spec->cap_mixer && !spec->no_analog)
f9e336f6 12919 set_capture_mixer(spec);
f53281e6 12920
1d955ebd
TI
12921 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
12922
f6a92248
KY
12923 return 1;
12924}
12925
12926#define alc269_auto_init_multi_out alc882_auto_init_multi_out
12927#define alc269_auto_init_hp_out alc882_auto_init_hp_out
12928#define alc269_auto_init_analog_input alc882_auto_init_analog_input
12929
12930
12931/* init callback for auto-configuration model -- overriding the default init */
12932static void alc269_auto_init(struct hda_codec *codec)
12933{
f6c7e546 12934 struct alc_spec *spec = codec->spec;
f6a92248
KY
12935 alc269_auto_init_multi_out(codec);
12936 alc269_auto_init_hp_out(codec);
12937 alc269_auto_init_analog_input(codec);
f6c7e546 12938 if (spec->unsol_event)
7fb0d78f 12939 alc_inithook(codec);
f6a92248
KY
12940}
12941
12942/*
12943 * configuration and preset
12944 */
12945static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 12946 [ALC269_BASIC] = "basic",
2922c9af
TI
12947 [ALC269_QUANTA_FL1] = "quanta",
12948 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
26f5df26 12949 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
64154835
TV
12950 [ALC269_FUJITSU] = "fujitsu",
12951 [ALC269_LIFEBOOK] = "lifebook"
f6a92248
KY
12952};
12953
12954static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 12955 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
f53281e6
KY
12956 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12957 ALC269_ASUS_EEEPC_P703),
622e84cd
KY
12958 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
12959 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
12960 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
12961 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
12962 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
12963 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
f53281e6
KY
12964 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12965 ALC269_ASUS_EEEPC_P901),
60db6b53
KY
12966 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12967 ALC269_ASUS_EEEPC_P901),
622e84cd 12968 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
26f5df26 12969 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
64154835 12970 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
f6a92248
KY
12971 {}
12972};
12973
12974static struct alc_config_preset alc269_presets[] = {
12975 [ALC269_BASIC] = {
f9e336f6 12976 .mixers = { alc269_base_mixer },
f6a92248
KY
12977 .init_verbs = { alc269_init_verbs },
12978 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12979 .dac_nids = alc269_dac_nids,
12980 .hp_nid = 0x03,
12981 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12982 .channel_mode = alc269_modes,
12983 .input_mux = &alc269_capture_source,
12984 },
60db6b53
KY
12985 [ALC269_QUANTA_FL1] = {
12986 .mixers = { alc269_quanta_fl1_mixer },
12987 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12988 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12989 .dac_nids = alc269_dac_nids,
12990 .hp_nid = 0x03,
12991 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12992 .channel_mode = alc269_modes,
12993 .input_mux = &alc269_capture_source,
12994 .unsol_event = alc269_quanta_fl1_unsol_event,
12995 .init_hook = alc269_quanta_fl1_init_hook,
12996 },
f53281e6 12997 [ALC269_ASUS_EEEPC_P703] = {
f9e336f6
TI
12998 .mixers = { alc269_eeepc_mixer },
12999 .cap_mixer = alc269_epc_capture_mixer,
f53281e6
KY
13000 .init_verbs = { alc269_init_verbs,
13001 alc269_eeepc_amic_init_verbs },
13002 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13003 .dac_nids = alc269_dac_nids,
13004 .hp_nid = 0x03,
13005 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13006 .channel_mode = alc269_modes,
13007 .input_mux = &alc269_eeepc_amic_capture_source,
13008 .unsol_event = alc269_eeepc_amic_unsol_event,
13009 .init_hook = alc269_eeepc_amic_inithook,
13010 },
13011 [ALC269_ASUS_EEEPC_P901] = {
f9e336f6
TI
13012 .mixers = { alc269_eeepc_mixer },
13013 .cap_mixer = alc269_epc_capture_mixer,
f53281e6
KY
13014 .init_verbs = { alc269_init_verbs,
13015 alc269_eeepc_dmic_init_verbs },
13016 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13017 .dac_nids = alc269_dac_nids,
13018 .hp_nid = 0x03,
13019 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13020 .channel_mode = alc269_modes,
13021 .input_mux = &alc269_eeepc_dmic_capture_source,
13022 .unsol_event = alc269_eeepc_dmic_unsol_event,
13023 .init_hook = alc269_eeepc_dmic_inithook,
13024 },
26f5df26 13025 [ALC269_FUJITSU] = {
45bdd1c1 13026 .mixers = { alc269_fujitsu_mixer },
26f5df26
TI
13027 .cap_mixer = alc269_epc_capture_mixer,
13028 .init_verbs = { alc269_init_verbs,
13029 alc269_eeepc_dmic_init_verbs },
13030 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13031 .dac_nids = alc269_dac_nids,
13032 .hp_nid = 0x03,
13033 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13034 .channel_mode = alc269_modes,
13035 .input_mux = &alc269_eeepc_dmic_capture_source,
13036 .unsol_event = alc269_eeepc_dmic_unsol_event,
13037 .init_hook = alc269_eeepc_dmic_inithook,
13038 },
64154835
TV
13039 [ALC269_LIFEBOOK] = {
13040 .mixers = { alc269_lifebook_mixer },
13041 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13042 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13043 .dac_nids = alc269_dac_nids,
13044 .hp_nid = 0x03,
13045 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13046 .channel_mode = alc269_modes,
13047 .input_mux = &alc269_capture_source,
13048 .unsol_event = alc269_lifebook_unsol_event,
13049 .init_hook = alc269_lifebook_init_hook,
13050 },
f6a92248
KY
13051};
13052
13053static int patch_alc269(struct hda_codec *codec)
13054{
13055 struct alc_spec *spec;
13056 int board_config;
13057 int err;
13058
13059 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13060 if (spec == NULL)
13061 return -ENOMEM;
13062
13063 codec->spec = spec;
13064
2c3bf9ab
TI
13065 alc_fix_pll_init(codec, 0x20, 0x04, 15);
13066
f6a92248
KY
13067 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13068 alc269_models,
13069 alc269_cfg_tbl);
13070
13071 if (board_config < 0) {
6c627f39
TI
13072 printk(KERN_INFO "hda_codec: Unknown model for %s, "
13073 "trying auto-probe from BIOS...\n", codec->chip_name);
f6a92248
KY
13074 board_config = ALC269_AUTO;
13075 }
13076
13077 if (board_config == ALC269_AUTO) {
13078 /* automatic parse from the BIOS config */
13079 err = alc269_parse_auto_config(codec);
13080 if (err < 0) {
13081 alc_free(codec);
13082 return err;
13083 } else if (!err) {
13084 printk(KERN_INFO
13085 "hda_codec: Cannot set up configuration "
13086 "from BIOS. Using base mode...\n");
13087 board_config = ALC269_BASIC;
13088 }
13089 }
13090
680cd536
KK
13091 err = snd_hda_attach_beep_device(codec, 0x1);
13092 if (err < 0) {
13093 alc_free(codec);
13094 return err;
13095 }
13096
f6a92248
KY
13097 if (board_config != ALC269_AUTO)
13098 setup_preset(spec, &alc269_presets[board_config]);
13099
f03d3115
TI
13100 if (codec->subsystem_id == 0x17aa3bf8) {
13101 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13102 * fix the sample rate of analog I/O to 44.1kHz
13103 */
13104 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13105 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13106 } else {
13107 spec->stream_analog_playback = &alc269_pcm_analog_playback;
13108 spec->stream_analog_capture = &alc269_pcm_analog_capture;
13109 }
f6a92248
KY
13110 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13111 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13112
13113 spec->adc_nids = alc269_adc_nids;
13114 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
e01bf509 13115 spec->capsrc_nids = alc269_capsrc_nids;
f9e336f6
TI
13116 if (!spec->cap_mixer)
13117 set_capture_mixer(spec);
45bdd1c1 13118 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248
KY
13119
13120 codec->patch_ops = alc_patch_ops;
13121 if (board_config == ALC269_AUTO)
13122 spec->init_hook = alc269_auto_init;
13123#ifdef CONFIG_SND_HDA_POWER_SAVE
13124 if (!spec->loopback.amplist)
13125 spec->loopback.amplist = alc269_loopbacks;
13126#endif
daead538 13127 codec->proc_widget_hook = print_realtek_coef;
f6a92248
KY
13128
13129 return 0;
13130}
13131
df694daa
KY
13132/*
13133 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13134 */
13135
13136/*
13137 * set the path ways for 2 channel output
13138 * need to set the codec line out and mic 1 pin widgets to inputs
13139 */
13140static struct hda_verb alc861_threestack_ch2_init[] = {
13141 /* set pin widget 1Ah (line in) for input */
13142 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
13143 /* set pin widget 18h (mic1/2) for input, for mic also enable
13144 * the vref
13145 */
df694daa
KY
13146 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13147
9c7f852e
TI
13148 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13149#if 0
13150 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13151 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13152#endif
df694daa
KY
13153 { } /* end */
13154};
13155/*
13156 * 6ch mode
13157 * need to set the codec line out and mic 1 pin widgets to outputs
13158 */
13159static struct hda_verb alc861_threestack_ch6_init[] = {
13160 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13161 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13162 /* set pin widget 18h (mic1) for output (CLFE)*/
13163 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13164
13165 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 13166 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 13167
9c7f852e
TI
13168 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13169#if 0
13170 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13171 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13172#endif
df694daa
KY
13173 { } /* end */
13174};
13175
13176static struct hda_channel_mode alc861_threestack_modes[2] = {
13177 { 2, alc861_threestack_ch2_init },
13178 { 6, alc861_threestack_ch6_init },
13179};
22309c3e
TI
13180/* Set mic1 as input and unmute the mixer */
13181static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13182 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13183 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13184 { } /* end */
13185};
13186/* Set mic1 as output and mute mixer */
13187static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13188 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13189 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13190 { } /* end */
13191};
13192
13193static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13194 { 2, alc861_uniwill_m31_ch2_init },
13195 { 4, alc861_uniwill_m31_ch4_init },
13196};
df694daa 13197
7cdbff94
MD
13198/* Set mic1 and line-in as input and unmute the mixer */
13199static struct hda_verb alc861_asus_ch2_init[] = {
13200 /* set pin widget 1Ah (line in) for input */
13201 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
13202 /* set pin widget 18h (mic1/2) for input, for mic also enable
13203 * the vref
13204 */
7cdbff94
MD
13205 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13206
13207 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13208#if 0
13209 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13210 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13211#endif
13212 { } /* end */
13213};
13214/* Set mic1 nad line-in as output and mute mixer */
13215static struct hda_verb alc861_asus_ch6_init[] = {
13216 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13217 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13218 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13219 /* set pin widget 18h (mic1) for output (CLFE)*/
13220 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13221 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13222 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13223 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13224
13225 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13226#if 0
13227 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13228 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13229#endif
13230 { } /* end */
13231};
13232
13233static struct hda_channel_mode alc861_asus_modes[2] = {
13234 { 2, alc861_asus_ch2_init },
13235 { 6, alc861_asus_ch6_init },
13236};
13237
df694daa
KY
13238/* patch-ALC861 */
13239
13240static struct snd_kcontrol_new alc861_base_mixer[] = {
13241 /* output mixer control */
13242 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13243 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13244 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13245 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13246 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13247
13248 /*Input mixer control */
13249 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13250 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13251 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13252 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13253 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13254 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13255 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13256 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13257 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13258 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 13259
df694daa
KY
13260 { } /* end */
13261};
13262
13263static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13264 /* output mixer control */
13265 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13266 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13267 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13268 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13269 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13270
13271 /* Input mixer control */
13272 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13273 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13274 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13275 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13276 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13277 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13278 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13279 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13280 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13281 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 13282
df694daa
KY
13283 {
13284 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13285 .name = "Channel Mode",
13286 .info = alc_ch_mode_info,
13287 .get = alc_ch_mode_get,
13288 .put = alc_ch_mode_put,
13289 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13290 },
13291 { } /* end */
a53d1aec
TD
13292};
13293
d1d985f0 13294static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
13295 /* output mixer control */
13296 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13297 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13298 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 13299
a53d1aec 13300 { } /* end */
f12ab1e0 13301};
a53d1aec 13302
22309c3e
TI
13303static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13304 /* output mixer control */
13305 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13306 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13307 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13308 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13309 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13310
13311 /* Input mixer control */
13312 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13313 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13314 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13315 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13316 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13317 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13318 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13319 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13320 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13321 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 13322
22309c3e
TI
13323 {
13324 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13325 .name = "Channel Mode",
13326 .info = alc_ch_mode_info,
13327 .get = alc_ch_mode_get,
13328 .put = alc_ch_mode_put,
13329 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13330 },
13331 { } /* end */
f12ab1e0 13332};
7cdbff94
MD
13333
13334static struct snd_kcontrol_new alc861_asus_mixer[] = {
13335 /* output mixer control */
13336 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13337 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13338 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13339 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13340 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13341
13342 /* Input mixer control */
13343 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13344 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13345 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13346 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13347 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13348 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13349 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13350 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13351 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
13352 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13353
7cdbff94
MD
13354 {
13355 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13356 .name = "Channel Mode",
13357 .info = alc_ch_mode_info,
13358 .get = alc_ch_mode_get,
13359 .put = alc_ch_mode_put,
13360 .private_value = ARRAY_SIZE(alc861_asus_modes),
13361 },
13362 { }
56bb0cab
TI
13363};
13364
13365/* additional mixer */
d1d985f0 13366static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
13367 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13368 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
13369 { }
13370};
7cdbff94 13371
df694daa
KY
13372/*
13373 * generic initialization of ADC, input mixers and output mixers
13374 */
13375static struct hda_verb alc861_base_init_verbs[] = {
13376 /*
13377 * Unmute ADC0 and set the default input to mic-in
13378 */
13379 /* port-A for surround (rear panel) */
13380 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13381 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13382 /* port-B for mic-in (rear panel) with vref */
13383 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13384 /* port-C for line-in (rear panel) */
13385 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13386 /* port-D for Front */
13387 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13388 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13389 /* port-E for HP out (front panel) */
13390 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13391 /* route front PCM to HP */
9dece1d7 13392 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
13393 /* port-F for mic-in (front panel) with vref */
13394 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13395 /* port-G for CLFE (rear panel) */
13396 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13397 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13398 /* port-H for side (rear panel) */
13399 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13400 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13401 /* CD-in */
13402 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13403 /* route front mic to ADC1*/
13404 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13405 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 13406
df694daa
KY
13407 /* Unmute DAC0~3 & spdif out*/
13408 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13409 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13410 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13411 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13412 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13413
df694daa
KY
13414 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13415 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13416 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13417 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13418 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13419
df694daa
KY
13420 /* Unmute Stereo Mixer 15 */
13421 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13422 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13423 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13424 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
13425
13426 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13427 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13428 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13429 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13430 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13431 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13432 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13433 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13434 /* hp used DAC 3 (Front) */
13435 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
13436 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13437
13438 { }
13439};
13440
13441static struct hda_verb alc861_threestack_init_verbs[] = {
13442 /*
13443 * Unmute ADC0 and set the default input to mic-in
13444 */
13445 /* port-A for surround (rear panel) */
13446 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13447 /* port-B for mic-in (rear panel) with vref */
13448 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13449 /* port-C for line-in (rear panel) */
13450 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13451 /* port-D for Front */
13452 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13453 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13454 /* port-E for HP out (front panel) */
13455 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13456 /* route front PCM to HP */
9dece1d7 13457 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
13458 /* port-F for mic-in (front panel) with vref */
13459 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13460 /* port-G for CLFE (rear panel) */
13461 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13462 /* port-H for side (rear panel) */
13463 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13464 /* CD-in */
13465 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13466 /* route front mic to ADC1*/
13467 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13468 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13469 /* Unmute DAC0~3 & spdif out*/
13470 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13471 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13472 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13473 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13474 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13475
df694daa
KY
13476 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13477 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13478 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13479 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13480 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13481
df694daa
KY
13482 /* Unmute Stereo Mixer 15 */
13483 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13484 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13485 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13486 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
13487
13488 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13489 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13490 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13491 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13492 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13493 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13494 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13495 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13496 /* hp used DAC 3 (Front) */
13497 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
13498 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13499 { }
13500};
22309c3e
TI
13501
13502static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13503 /*
13504 * Unmute ADC0 and set the default input to mic-in
13505 */
13506 /* port-A for surround (rear panel) */
13507 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13508 /* port-B for mic-in (rear panel) with vref */
13509 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13510 /* port-C for line-in (rear panel) */
13511 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13512 /* port-D for Front */
13513 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13514 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13515 /* port-E for HP out (front panel) */
f12ab1e0
TI
13516 /* this has to be set to VREF80 */
13517 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 13518 /* route front PCM to HP */
9dece1d7 13519 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
13520 /* port-F for mic-in (front panel) with vref */
13521 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13522 /* port-G for CLFE (rear panel) */
13523 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13524 /* port-H for side (rear panel) */
13525 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13526 /* CD-in */
13527 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13528 /* route front mic to ADC1*/
13529 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13530 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13531 /* Unmute DAC0~3 & spdif out*/
13532 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13533 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13534 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13535 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13536 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13537
22309c3e
TI
13538 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13539 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13540 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13541 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13542 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13543
22309c3e
TI
13544 /* Unmute Stereo Mixer 15 */
13545 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13546 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13547 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13548 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
13549
13550 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13551 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13552 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13553 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13554 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13555 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13556 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13557 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13558 /* hp used DAC 3 (Front) */
13559 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
13560 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13561 { }
13562};
13563
7cdbff94
MD
13564static struct hda_verb alc861_asus_init_verbs[] = {
13565 /*
13566 * Unmute ADC0 and set the default input to mic-in
13567 */
f12ab1e0
TI
13568 /* port-A for surround (rear panel)
13569 * according to codec#0 this is the HP jack
13570 */
7cdbff94
MD
13571 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13572 /* route front PCM to HP */
13573 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13574 /* port-B for mic-in (rear panel) with vref */
13575 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13576 /* port-C for line-in (rear panel) */
13577 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13578 /* port-D for Front */
13579 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13580 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13581 /* port-E for HP out (front panel) */
f12ab1e0
TI
13582 /* this has to be set to VREF80 */
13583 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 13584 /* route front PCM to HP */
9dece1d7 13585 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
13586 /* port-F for mic-in (front panel) with vref */
13587 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13588 /* port-G for CLFE (rear panel) */
13589 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13590 /* port-H for side (rear panel) */
13591 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13592 /* CD-in */
13593 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13594 /* route front mic to ADC1*/
13595 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13596 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13597 /* Unmute DAC0~3 & spdif out*/
13598 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13599 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13600 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13601 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13602 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13603 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13604 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13605 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13606 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13607 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13608
7cdbff94
MD
13609 /* Unmute Stereo Mixer 15 */
13610 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13611 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13612 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13613 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
13614
13615 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13616 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13617 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13618 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13619 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13620 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13621 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13622 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13623 /* hp used DAC 3 (Front) */
13624 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
13625 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13626 { }
13627};
13628
56bb0cab
TI
13629/* additional init verbs for ASUS laptops */
13630static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13631 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13632 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13633 { }
13634};
7cdbff94 13635
df694daa
KY
13636/*
13637 * generic initialization of ADC, input mixers and output mixers
13638 */
13639static struct hda_verb alc861_auto_init_verbs[] = {
13640 /*
13641 * Unmute ADC0 and set the default input to mic-in
13642 */
f12ab1e0 13643 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 13644 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 13645
df694daa
KY
13646 /* Unmute DAC0~3 & spdif out*/
13647 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13648 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13649 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13650 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13651 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13652
df694daa
KY
13653 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13654 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13655 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13656 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13657 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13658
df694daa
KY
13659 /* Unmute Stereo Mixer 15 */
13660 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13661 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13662 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13663 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13664
13665 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13666 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13667 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13668 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13669 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13670 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13671 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13672 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13673
13674 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13675 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
13676 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13677 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
13678 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13679 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
13680 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13681 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa 13682
f12ab1e0 13683 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
13684
13685 { }
13686};
13687
a53d1aec
TD
13688static struct hda_verb alc861_toshiba_init_verbs[] = {
13689 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 13690
a53d1aec
TD
13691 { }
13692};
13693
13694/* toggle speaker-output according to the hp-jack state */
13695static void alc861_toshiba_automute(struct hda_codec *codec)
13696{
13697 unsigned int present;
13698
13699 present = snd_hda_codec_read(codec, 0x0f, 0,
13700 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
13701 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13702 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13703 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13704 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
13705}
13706
13707static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13708 unsigned int res)
13709{
a53d1aec
TD
13710 if ((res >> 26) == ALC880_HP_EVENT)
13711 alc861_toshiba_automute(codec);
13712}
13713
def319f9 13714/* pcm configuration: identical with ALC880 */
df694daa
KY
13715#define alc861_pcm_analog_playback alc880_pcm_analog_playback
13716#define alc861_pcm_analog_capture alc880_pcm_analog_capture
13717#define alc861_pcm_digital_playback alc880_pcm_digital_playback
13718#define alc861_pcm_digital_capture alc880_pcm_digital_capture
13719
13720
13721#define ALC861_DIGOUT_NID 0x07
13722
13723static struct hda_channel_mode alc861_8ch_modes[1] = {
13724 { 8, NULL }
13725};
13726
13727static hda_nid_t alc861_dac_nids[4] = {
13728 /* front, surround, clfe, side */
13729 0x03, 0x06, 0x05, 0x04
13730};
13731
9c7f852e
TI
13732static hda_nid_t alc660_dac_nids[3] = {
13733 /* front, clfe, surround */
13734 0x03, 0x05, 0x06
13735};
13736
df694daa
KY
13737static hda_nid_t alc861_adc_nids[1] = {
13738 /* ADC0-2 */
13739 0x08,
13740};
13741
13742static struct hda_input_mux alc861_capture_source = {
13743 .num_items = 5,
13744 .items = {
13745 { "Mic", 0x0 },
13746 { "Front Mic", 0x3 },
13747 { "Line", 0x1 },
13748 { "CD", 0x4 },
13749 { "Mixer", 0x5 },
13750 },
13751};
13752
13753/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
13754static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13755 const struct auto_pin_cfg *cfg)
df694daa
KY
13756{
13757 int i;
13758 hda_nid_t nid;
13759
13760 spec->multiout.dac_nids = spec->private_dac_nids;
13761 for (i = 0; i < cfg->line_outs; i++) {
13762 nid = cfg->line_out_pins[i];
13763 if (nid) {
13764 if (i >= ARRAY_SIZE(alc861_dac_nids))
13765 continue;
13766 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13767 }
13768 }
13769 spec->multiout.num_dacs = cfg->line_outs;
13770 return 0;
13771}
13772
13773/* add playback controls from the parsed DAC table */
13774static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13775 const struct auto_pin_cfg *cfg)
13776{
13777 char name[32];
f12ab1e0
TI
13778 static const char *chname[4] = {
13779 "Front", "Surround", NULL /*CLFE*/, "Side"
13780 };
df694daa
KY
13781 hda_nid_t nid;
13782 int i, idx, err;
13783
13784 for (i = 0; i < cfg->line_outs; i++) {
13785 nid = spec->multiout.dac_nids[i];
f12ab1e0 13786 if (!nid)
df694daa
KY
13787 continue;
13788 if (nid == 0x05) {
13789 /* Center/LFE */
f12ab1e0
TI
13790 err = add_control(spec, ALC_CTL_BIND_MUTE,
13791 "Center Playback Switch",
13792 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13793 HDA_OUTPUT));
13794 if (err < 0)
df694daa 13795 return err;
f12ab1e0
TI
13796 err = add_control(spec, ALC_CTL_BIND_MUTE,
13797 "LFE Playback Switch",
13798 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13799 HDA_OUTPUT));
13800 if (err < 0)
df694daa
KY
13801 return err;
13802 } else {
f12ab1e0
TI
13803 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13804 idx++)
df694daa
KY
13805 if (nid == alc861_dac_nids[idx])
13806 break;
13807 sprintf(name, "%s Playback Switch", chname[idx]);
f12ab1e0
TI
13808 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13809 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13810 HDA_OUTPUT));
13811 if (err < 0)
df694daa
KY
13812 return err;
13813 }
13814 }
13815 return 0;
13816}
13817
13818static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13819{
13820 int err;
13821 hda_nid_t nid;
13822
f12ab1e0 13823 if (!pin)
df694daa
KY
13824 return 0;
13825
13826 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13827 nid = 0x03;
f12ab1e0
TI
13828 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13829 "Headphone Playback Switch",
13830 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13831 if (err < 0)
df694daa
KY
13832 return err;
13833 spec->multiout.hp_nid = nid;
13834 }
13835 return 0;
13836}
13837
13838/* create playback/capture controls for input pins */
f12ab1e0
TI
13839static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13840 const struct auto_pin_cfg *cfg)
df694daa 13841{
61b9b9b1 13842 struct hda_input_mux *imux = &spec->private_imux[0];
df694daa
KY
13843 int i, err, idx, idx1;
13844
13845 for (i = 0; i < AUTO_PIN_LAST; i++) {
f12ab1e0 13846 switch (cfg->input_pins[i]) {
df694daa
KY
13847 case 0x0c:
13848 idx1 = 1;
f12ab1e0 13849 idx = 2; /* Line In */
df694daa
KY
13850 break;
13851 case 0x0f:
13852 idx1 = 2;
f12ab1e0 13853 idx = 2; /* Line In */
df694daa
KY
13854 break;
13855 case 0x0d:
13856 idx1 = 0;
f12ab1e0 13857 idx = 1; /* Mic In */
df694daa 13858 break;
f12ab1e0 13859 case 0x10:
df694daa 13860 idx1 = 3;
f12ab1e0 13861 idx = 1; /* Mic In */
df694daa
KY
13862 break;
13863 case 0x11:
13864 idx1 = 4;
f12ab1e0 13865 idx = 0; /* CD */
df694daa
KY
13866 break;
13867 default:
13868 continue;
13869 }
13870
4a471b7d
TI
13871 err = new_analog_input(spec, cfg->input_pins[i],
13872 auto_pin_cfg_labels[i], idx, 0x15);
df694daa
KY
13873 if (err < 0)
13874 return err;
13875
4a471b7d 13876 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
df694daa 13877 imux->items[imux->num_items].index = idx1;
f12ab1e0 13878 imux->num_items++;
df694daa
KY
13879 }
13880 return 0;
13881}
13882
f12ab1e0
TI
13883static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13884 hda_nid_t nid,
df694daa
KY
13885 int pin_type, int dac_idx)
13886{
564c5bea
JL
13887 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13888 pin_type);
13889 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13890 AMP_OUT_UNMUTE);
df694daa
KY
13891}
13892
13893static void alc861_auto_init_multi_out(struct hda_codec *codec)
13894{
13895 struct alc_spec *spec = codec->spec;
13896 int i;
13897
13898 for (i = 0; i < spec->autocfg.line_outs; i++) {
13899 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 13900 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 13901 if (nid)
baba8ee9 13902 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 13903 spec->multiout.dac_nids[i]);
df694daa
KY
13904 }
13905}
13906
13907static void alc861_auto_init_hp_out(struct hda_codec *codec)
13908{
13909 struct alc_spec *spec = codec->spec;
13910 hda_nid_t pin;
13911
eb06ed8f 13912 pin = spec->autocfg.hp_pins[0];
df694daa 13913 if (pin) /* connect to front */
f12ab1e0
TI
13914 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13915 spec->multiout.dac_nids[0]);
f6c7e546
TI
13916 pin = spec->autocfg.speaker_pins[0];
13917 if (pin)
13918 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
13919}
13920
13921static void alc861_auto_init_analog_input(struct hda_codec *codec)
13922{
13923 struct alc_spec *spec = codec->spec;
13924 int i;
13925
13926 for (i = 0; i < AUTO_PIN_LAST; i++) {
13927 hda_nid_t nid = spec->autocfg.input_pins[i];
23f0c048
TI
13928 if (nid >= 0x0c && nid <= 0x11)
13929 alc_set_input_pin(codec, nid, i);
df694daa
KY
13930 }
13931}
13932
13933/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
13934/* return 1 if successful, 0 if the proper config is not found,
13935 * or a negative error code
13936 */
df694daa
KY
13937static int alc861_parse_auto_config(struct hda_codec *codec)
13938{
13939 struct alc_spec *spec = codec->spec;
13940 int err;
13941 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13942
f12ab1e0
TI
13943 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13944 alc861_ignore);
13945 if (err < 0)
df694daa 13946 return err;
f12ab1e0 13947 if (!spec->autocfg.line_outs)
df694daa
KY
13948 return 0; /* can't find valid BIOS pin config */
13949
f12ab1e0
TI
13950 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13951 if (err < 0)
13952 return err;
13953 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13954 if (err < 0)
13955 return err;
13956 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13957 if (err < 0)
13958 return err;
13959 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13960 if (err < 0)
df694daa
KY
13961 return err;
13962
13963 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13964
0852d7a6 13965 if (spec->autocfg.dig_outs)
df694daa
KY
13966 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13967
603c4019 13968 if (spec->kctls.list)
d88897ea 13969 add_mixer(spec, spec->kctls.list);
df694daa 13970
d88897ea 13971 add_verb(spec, alc861_auto_init_verbs);
df694daa 13972
a1e8d2da 13973 spec->num_mux_defs = 1;
61b9b9b1 13974 spec->input_mux = &spec->private_imux[0];
df694daa
KY
13975
13976 spec->adc_nids = alc861_adc_nids;
13977 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
f9e336f6 13978 set_capture_mixer(spec);
df694daa 13979
4a79ba34
TI
13980 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
13981
df694daa
KY
13982 return 1;
13983}
13984
ae6b813a
TI
13985/* additional initialization for auto-configuration model */
13986static void alc861_auto_init(struct hda_codec *codec)
df694daa 13987{
f6c7e546 13988 struct alc_spec *spec = codec->spec;
df694daa
KY
13989 alc861_auto_init_multi_out(codec);
13990 alc861_auto_init_hp_out(codec);
13991 alc861_auto_init_analog_input(codec);
f6c7e546 13992 if (spec->unsol_event)
7fb0d78f 13993 alc_inithook(codec);
df694daa
KY
13994}
13995
cb53c626
TI
13996#ifdef CONFIG_SND_HDA_POWER_SAVE
13997static struct hda_amp_list alc861_loopbacks[] = {
13998 { 0x15, HDA_INPUT, 0 },
13999 { 0x15, HDA_INPUT, 1 },
14000 { 0x15, HDA_INPUT, 2 },
14001 { 0x15, HDA_INPUT, 3 },
14002 { } /* end */
14003};
14004#endif
14005
df694daa
KY
14006
14007/*
14008 * configuration and preset
14009 */
f5fcc13c
TI
14010static const char *alc861_models[ALC861_MODEL_LAST] = {
14011 [ALC861_3ST] = "3stack",
14012 [ALC660_3ST] = "3stack-660",
14013 [ALC861_3ST_DIG] = "3stack-dig",
14014 [ALC861_6ST_DIG] = "6stack-dig",
14015 [ALC861_UNIWILL_M31] = "uniwill-m31",
14016 [ALC861_TOSHIBA] = "toshiba",
14017 [ALC861_ASUS] = "asus",
14018 [ALC861_ASUS_LAPTOP] = "asus-laptop",
14019 [ALC861_AUTO] = "auto",
14020};
14021
14022static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 14023 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
14024 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14025 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14026 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 14027 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 14028 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 14029 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
14030 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14031 * Any other models that need this preset?
14032 */
14033 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
14034 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14035 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 14036 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
14037 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14038 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14039 /* FIXME: the below seems conflict */
14040 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 14041 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 14042 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
14043 {}
14044};
14045
14046static struct alc_config_preset alc861_presets[] = {
14047 [ALC861_3ST] = {
14048 .mixers = { alc861_3ST_mixer },
14049 .init_verbs = { alc861_threestack_init_verbs },
14050 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14051 .dac_nids = alc861_dac_nids,
14052 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14053 .channel_mode = alc861_threestack_modes,
4e195a7b 14054 .need_dac_fix = 1,
df694daa
KY
14055 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14056 .adc_nids = alc861_adc_nids,
14057 .input_mux = &alc861_capture_source,
14058 },
14059 [ALC861_3ST_DIG] = {
14060 .mixers = { alc861_base_mixer },
14061 .init_verbs = { alc861_threestack_init_verbs },
14062 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14063 .dac_nids = alc861_dac_nids,
14064 .dig_out_nid = ALC861_DIGOUT_NID,
14065 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14066 .channel_mode = alc861_threestack_modes,
4e195a7b 14067 .need_dac_fix = 1,
df694daa
KY
14068 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14069 .adc_nids = alc861_adc_nids,
14070 .input_mux = &alc861_capture_source,
14071 },
14072 [ALC861_6ST_DIG] = {
14073 .mixers = { alc861_base_mixer },
14074 .init_verbs = { alc861_base_init_verbs },
14075 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14076 .dac_nids = alc861_dac_nids,
14077 .dig_out_nid = ALC861_DIGOUT_NID,
14078 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14079 .channel_mode = alc861_8ch_modes,
14080 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14081 .adc_nids = alc861_adc_nids,
14082 .input_mux = &alc861_capture_source,
14083 },
9c7f852e
TI
14084 [ALC660_3ST] = {
14085 .mixers = { alc861_3ST_mixer },
14086 .init_verbs = { alc861_threestack_init_verbs },
14087 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
14088 .dac_nids = alc660_dac_nids,
14089 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14090 .channel_mode = alc861_threestack_modes,
4e195a7b 14091 .need_dac_fix = 1,
9c7f852e
TI
14092 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14093 .adc_nids = alc861_adc_nids,
14094 .input_mux = &alc861_capture_source,
14095 },
22309c3e
TI
14096 [ALC861_UNIWILL_M31] = {
14097 .mixers = { alc861_uniwill_m31_mixer },
14098 .init_verbs = { alc861_uniwill_m31_init_verbs },
14099 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14100 .dac_nids = alc861_dac_nids,
14101 .dig_out_nid = ALC861_DIGOUT_NID,
14102 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14103 .channel_mode = alc861_uniwill_m31_modes,
14104 .need_dac_fix = 1,
14105 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14106 .adc_nids = alc861_adc_nids,
14107 .input_mux = &alc861_capture_source,
14108 },
a53d1aec
TD
14109 [ALC861_TOSHIBA] = {
14110 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
14111 .init_verbs = { alc861_base_init_verbs,
14112 alc861_toshiba_init_verbs },
a53d1aec
TD
14113 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14114 .dac_nids = alc861_dac_nids,
14115 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14116 .channel_mode = alc883_3ST_2ch_modes,
14117 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14118 .adc_nids = alc861_adc_nids,
14119 .input_mux = &alc861_capture_source,
14120 .unsol_event = alc861_toshiba_unsol_event,
14121 .init_hook = alc861_toshiba_automute,
14122 },
7cdbff94
MD
14123 [ALC861_ASUS] = {
14124 .mixers = { alc861_asus_mixer },
14125 .init_verbs = { alc861_asus_init_verbs },
14126 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14127 .dac_nids = alc861_dac_nids,
14128 .dig_out_nid = ALC861_DIGOUT_NID,
14129 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14130 .channel_mode = alc861_asus_modes,
14131 .need_dac_fix = 1,
14132 .hp_nid = 0x06,
14133 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14134 .adc_nids = alc861_adc_nids,
14135 .input_mux = &alc861_capture_source,
14136 },
56bb0cab
TI
14137 [ALC861_ASUS_LAPTOP] = {
14138 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14139 .init_verbs = { alc861_asus_init_verbs,
14140 alc861_asus_laptop_init_verbs },
14141 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14142 .dac_nids = alc861_dac_nids,
14143 .dig_out_nid = ALC861_DIGOUT_NID,
14144 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14145 .channel_mode = alc883_3ST_2ch_modes,
14146 .need_dac_fix = 1,
14147 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14148 .adc_nids = alc861_adc_nids,
14149 .input_mux = &alc861_capture_source,
14150 },
14151};
df694daa
KY
14152
14153
14154static int patch_alc861(struct hda_codec *codec)
14155{
14156 struct alc_spec *spec;
14157 int board_config;
14158 int err;
14159
dc041e0b 14160 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
14161 if (spec == NULL)
14162 return -ENOMEM;
14163
f12ab1e0 14164 codec->spec = spec;
df694daa 14165
f5fcc13c
TI
14166 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14167 alc861_models,
14168 alc861_cfg_tbl);
9c7f852e 14169
f5fcc13c 14170 if (board_config < 0) {
6c627f39
TI
14171 printk(KERN_INFO "hda_codec: Unknown model for %s, "
14172 "trying auto-probe from BIOS...\n", codec->chip_name);
df694daa
KY
14173 board_config = ALC861_AUTO;
14174 }
14175
14176 if (board_config == ALC861_AUTO) {
14177 /* automatic parse from the BIOS config */
14178 err = alc861_parse_auto_config(codec);
14179 if (err < 0) {
14180 alc_free(codec);
14181 return err;
f12ab1e0 14182 } else if (!err) {
9c7f852e
TI
14183 printk(KERN_INFO
14184 "hda_codec: Cannot set up configuration "
14185 "from BIOS. Using base mode...\n");
df694daa
KY
14186 board_config = ALC861_3ST_DIG;
14187 }
14188 }
14189
680cd536
KK
14190 err = snd_hda_attach_beep_device(codec, 0x23);
14191 if (err < 0) {
14192 alc_free(codec);
14193 return err;
14194 }
14195
df694daa
KY
14196 if (board_config != ALC861_AUTO)
14197 setup_preset(spec, &alc861_presets[board_config]);
14198
df694daa
KY
14199 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14200 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14201
df694daa
KY
14202 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14203 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14204
45bdd1c1
TI
14205 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14206
2134ea4f
TI
14207 spec->vmaster_nid = 0x03;
14208
df694daa
KY
14209 codec->patch_ops = alc_patch_ops;
14210 if (board_config == ALC861_AUTO)
ae6b813a 14211 spec->init_hook = alc861_auto_init;
cb53c626
TI
14212#ifdef CONFIG_SND_HDA_POWER_SAVE
14213 if (!spec->loopback.amplist)
14214 spec->loopback.amplist = alc861_loopbacks;
14215#endif
daead538 14216 codec->proc_widget_hook = print_realtek_coef;
ea1fb29a 14217
1da177e4
LT
14218 return 0;
14219}
14220
f32610ed
JS
14221/*
14222 * ALC861-VD support
14223 *
14224 * Based on ALC882
14225 *
14226 * In addition, an independent DAC
14227 */
14228#define ALC861VD_DIGOUT_NID 0x06
14229
14230static hda_nid_t alc861vd_dac_nids[4] = {
14231 /* front, surr, clfe, side surr */
14232 0x02, 0x03, 0x04, 0x05
14233};
14234
14235/* dac_nids for ALC660vd are in a different order - according to
14236 * Realtek's driver.
def319f9 14237 * This should probably result in a different mixer for 6stack models
f32610ed
JS
14238 * of ALC660vd codecs, but for now there is only 3stack mixer
14239 * - and it is the same as in 861vd.
14240 * adc_nids in ALC660vd are (is) the same as in 861vd
14241 */
14242static hda_nid_t alc660vd_dac_nids[3] = {
14243 /* front, rear, clfe, rear_surr */
14244 0x02, 0x04, 0x03
14245};
14246
14247static hda_nid_t alc861vd_adc_nids[1] = {
14248 /* ADC0 */
14249 0x09,
14250};
14251
e1406348
TI
14252static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14253
f32610ed
JS
14254/* input MUX */
14255/* FIXME: should be a matrix-type input source selection */
14256static struct hda_input_mux alc861vd_capture_source = {
14257 .num_items = 4,
14258 .items = {
14259 { "Mic", 0x0 },
14260 { "Front Mic", 0x1 },
14261 { "Line", 0x2 },
14262 { "CD", 0x4 },
14263 },
14264};
14265
272a527c 14266static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 14267 .num_items = 2,
272a527c 14268 .items = {
b419f346
TD
14269 { "Ext Mic", 0x0 },
14270 { "Int Mic", 0x1 },
272a527c
KY
14271 },
14272};
14273
d1a991a6
KY
14274static struct hda_input_mux alc861vd_hp_capture_source = {
14275 .num_items = 2,
14276 .items = {
14277 { "Front Mic", 0x0 },
14278 { "ATAPI Mic", 0x1 },
14279 },
14280};
14281
f32610ed
JS
14282/*
14283 * 2ch mode
14284 */
14285static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14286 { 2, NULL }
14287};
14288
14289/*
14290 * 6ch mode
14291 */
14292static struct hda_verb alc861vd_6stack_ch6_init[] = {
14293 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14294 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14295 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14296 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14297 { } /* end */
14298};
14299
14300/*
14301 * 8ch mode
14302 */
14303static struct hda_verb alc861vd_6stack_ch8_init[] = {
14304 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14305 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14306 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14307 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14308 { } /* end */
14309};
14310
14311static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14312 { 6, alc861vd_6stack_ch6_init },
14313 { 8, alc861vd_6stack_ch8_init },
14314};
14315
14316static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14317 {
14318 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14319 .name = "Channel Mode",
14320 .info = alc_ch_mode_info,
14321 .get = alc_ch_mode_get,
14322 .put = alc_ch_mode_put,
14323 },
14324 { } /* end */
14325};
14326
f32610ed
JS
14327/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14328 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14329 */
14330static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14331 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14332 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14333
14334 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14335 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14336
14337 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14338 HDA_OUTPUT),
14339 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14340 HDA_OUTPUT),
14341 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14342 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14343
14344 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14345 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14346
14347 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14348
14349 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14350 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14351 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14352
14353 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14354 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14355 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14356
14357 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14358 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14359
14360 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14361 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14362
f32610ed
JS
14363 { } /* end */
14364};
14365
14366static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14367 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14368 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14369
14370 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14371
14372 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14373 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14374 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14375
14376 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14377 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14378 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14379
14380 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14381 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14382
14383 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14384 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14385
f32610ed
JS
14386 { } /* end */
14387};
14388
bdd148a3
KY
14389static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14390 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14391 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14392 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14393
14394 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14395
14396 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14397 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14398 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14399
14400 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14401 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14402 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14403
14404 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14405 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14406
14407 { } /* end */
14408};
14409
b419f346
TD
14410/* Pin assignment: Speaker=0x14, HP = 0x15,
14411 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
14412 */
14413static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
14414 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14415 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
14416 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14417 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
14418 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14419 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14420 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14421 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14422 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14423 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
14424 { } /* end */
14425};
14426
d1a991a6
KY
14427/* Pin assignment: Speaker=0x14, Line-out = 0x15,
14428 * Front Mic=0x18, ATAPI Mic = 0x19,
14429 */
14430static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14431 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14432 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14433 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14434 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14435 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14436 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14437 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14438 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 14439
d1a991a6
KY
14440 { } /* end */
14441};
14442
f32610ed
JS
14443/*
14444 * generic initialization of ADC, input mixers and output mixers
14445 */
14446static struct hda_verb alc861vd_volume_init_verbs[] = {
14447 /*
14448 * Unmute ADC0 and set the default input to mic-in
14449 */
14450 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14451 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14452
14453 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14454 * the analog-loopback mixer widget
14455 */
14456 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
14457 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14458 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14459 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14460 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14461 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
14462
14463 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
14464 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14465 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14466 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 14467 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
14468
14469 /*
14470 * Set up output mixers (0x02 - 0x05)
14471 */
14472 /* set vol=0 to output mixers */
14473 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14474 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14475 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14476 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14477
14478 /* set up input amps for analog loopback */
14479 /* Amp Indices: DAC = 0, mixer = 1 */
14480 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14481 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14482 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14483 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14484 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14485 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14486 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14487 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14488
14489 { }
14490};
14491
14492/*
14493 * 3-stack pin configuration:
14494 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14495 */
14496static struct hda_verb alc861vd_3stack_init_verbs[] = {
14497 /*
14498 * Set pin mode and muting
14499 */
14500 /* set front pin widgets 0x14 for output */
14501 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14502 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14503 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14504
14505 /* Mic (rear) pin: input vref at 80% */
14506 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14507 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14508 /* Front Mic pin: input vref at 80% */
14509 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14510 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14511 /* Line In pin: input */
14512 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14513 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14514 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14515 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14516 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14517 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14518 /* CD pin widget for input */
14519 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14520
14521 { }
14522};
14523
14524/*
14525 * 6-stack pin configuration:
14526 */
14527static struct hda_verb alc861vd_6stack_init_verbs[] = {
14528 /*
14529 * Set pin mode and muting
14530 */
14531 /* set front pin widgets 0x14 for output */
14532 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14533 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14534 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14535
14536 /* Rear Pin: output 1 (0x0d) */
14537 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14538 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14539 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14540 /* CLFE Pin: output 2 (0x0e) */
14541 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14542 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14543 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14544 /* Side Pin: output 3 (0x0f) */
14545 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14546 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14547 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14548
14549 /* Mic (rear) pin: input vref at 80% */
14550 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14551 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14552 /* Front Mic pin: input vref at 80% */
14553 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14554 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14555 /* Line In pin: input */
14556 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14557 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14558 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14559 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14560 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14561 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14562 /* CD pin widget for input */
14563 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14564
14565 { }
14566};
14567
bdd148a3
KY
14568static struct hda_verb alc861vd_eapd_verbs[] = {
14569 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14570 { }
14571};
14572
f9423e7a
KY
14573static struct hda_verb alc660vd_eapd_verbs[] = {
14574 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14575 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14576 { }
14577};
14578
bdd148a3
KY
14579static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14580 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14581 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14582 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14583 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 14584 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
14585 {}
14586};
14587
bdd148a3
KY
14588static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14589{
14590 unsigned int present;
14591 unsigned char bits;
14592
14593 present = snd_hda_codec_read(codec, 0x18, 0,
14594 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
14595 bits = present ? HDA_AMP_MUTE : 0;
14596 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14597 HDA_AMP_MUTE, bits);
bdd148a3
KY
14598}
14599
a9fd4f3f 14600static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
bdd148a3 14601{
a9fd4f3f
TI
14602 struct alc_spec *spec = codec->spec;
14603
14604 spec->autocfg.hp_pins[0] = 0x1b;
14605 spec->autocfg.speaker_pins[0] = 0x14;
14606 alc_automute_amp(codec);
bdd148a3
KY
14607 alc861vd_lenovo_mic_automute(codec);
14608}
14609
14610static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14611 unsigned int res)
14612{
14613 switch (res >> 26) {
bdd148a3
KY
14614 case ALC880_MIC_EVENT:
14615 alc861vd_lenovo_mic_automute(codec);
14616 break;
a9fd4f3f
TI
14617 default:
14618 alc_automute_amp_unsol_event(codec, res);
14619 break;
bdd148a3
KY
14620 }
14621}
14622
272a527c
KY
14623static struct hda_verb alc861vd_dallas_verbs[] = {
14624 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14625 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14626 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14627 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14628
14629 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14630 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14631 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14632 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14633 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14634 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14635 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14636 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 14637
272a527c
KY
14638 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14639 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14640 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14641 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14642 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14643 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14644 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14645 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14646
14647 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14648 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14649 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14650 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14651 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14652 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14653 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14654 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14655
14656 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14657 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14658 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14659 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14660
14661 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 14662 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
14663 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14664
14665 { } /* end */
14666};
14667
14668/* toggle speaker-output according to the hp-jack state */
a9fd4f3f 14669static void alc861vd_dallas_init_hook(struct hda_codec *codec)
272a527c 14670{
a9fd4f3f 14671 struct alc_spec *spec = codec->spec;
272a527c 14672
a9fd4f3f
TI
14673 spec->autocfg.hp_pins[0] = 0x15;
14674 spec->autocfg.speaker_pins[0] = 0x14;
14675 alc_automute_amp(codec);
272a527c
KY
14676}
14677
cb53c626
TI
14678#ifdef CONFIG_SND_HDA_POWER_SAVE
14679#define alc861vd_loopbacks alc880_loopbacks
14680#endif
14681
def319f9 14682/* pcm configuration: identical with ALC880 */
f32610ed
JS
14683#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14684#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14685#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14686#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14687
14688/*
14689 * configuration and preset
14690 */
14691static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14692 [ALC660VD_3ST] = "3stack-660",
983f8ae4 14693 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 14694 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
14695 [ALC861VD_3ST] = "3stack",
14696 [ALC861VD_3ST_DIG] = "3stack-digout",
14697 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 14698 [ALC861VD_LENOVO] = "lenovo",
272a527c 14699 [ALC861VD_DALLAS] = "dallas",
983f8ae4 14700 [ALC861VD_HP] = "hp",
f32610ed
JS
14701 [ALC861VD_AUTO] = "auto",
14702};
14703
14704static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
14705 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14706 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 14707 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f32610ed 14708 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
13c94744 14709 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 14710 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 14711 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 14712 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 14713 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
272a527c 14714 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
542d7c66 14715 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 14716 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 14717 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 14718 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 14719 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
14720 {}
14721};
14722
14723static struct alc_config_preset alc861vd_presets[] = {
14724 [ALC660VD_3ST] = {
14725 .mixers = { alc861vd_3st_mixer },
14726 .init_verbs = { alc861vd_volume_init_verbs,
14727 alc861vd_3stack_init_verbs },
14728 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14729 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
14730 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14731 .channel_mode = alc861vd_3stack_2ch_modes,
14732 .input_mux = &alc861vd_capture_source,
14733 },
6963f84c
MC
14734 [ALC660VD_3ST_DIG] = {
14735 .mixers = { alc861vd_3st_mixer },
14736 .init_verbs = { alc861vd_volume_init_verbs,
14737 alc861vd_3stack_init_verbs },
14738 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14739 .dac_nids = alc660vd_dac_nids,
14740 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
14741 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14742 .channel_mode = alc861vd_3stack_2ch_modes,
14743 .input_mux = &alc861vd_capture_source,
14744 },
f32610ed
JS
14745 [ALC861VD_3ST] = {
14746 .mixers = { alc861vd_3st_mixer },
14747 .init_verbs = { alc861vd_volume_init_verbs,
14748 alc861vd_3stack_init_verbs },
14749 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14750 .dac_nids = alc861vd_dac_nids,
14751 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14752 .channel_mode = alc861vd_3stack_2ch_modes,
14753 .input_mux = &alc861vd_capture_source,
14754 },
14755 [ALC861VD_3ST_DIG] = {
14756 .mixers = { alc861vd_3st_mixer },
14757 .init_verbs = { alc861vd_volume_init_verbs,
14758 alc861vd_3stack_init_verbs },
14759 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14760 .dac_nids = alc861vd_dac_nids,
14761 .dig_out_nid = ALC861VD_DIGOUT_NID,
14762 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14763 .channel_mode = alc861vd_3stack_2ch_modes,
14764 .input_mux = &alc861vd_capture_source,
14765 },
14766 [ALC861VD_6ST_DIG] = {
14767 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14768 .init_verbs = { alc861vd_volume_init_verbs,
14769 alc861vd_6stack_init_verbs },
14770 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14771 .dac_nids = alc861vd_dac_nids,
14772 .dig_out_nid = ALC861VD_DIGOUT_NID,
14773 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14774 .channel_mode = alc861vd_6stack_modes,
14775 .input_mux = &alc861vd_capture_source,
14776 },
bdd148a3
KY
14777 [ALC861VD_LENOVO] = {
14778 .mixers = { alc861vd_lenovo_mixer },
14779 .init_verbs = { alc861vd_volume_init_verbs,
14780 alc861vd_3stack_init_verbs,
14781 alc861vd_eapd_verbs,
14782 alc861vd_lenovo_unsol_verbs },
14783 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14784 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
14785 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14786 .channel_mode = alc861vd_3stack_2ch_modes,
14787 .input_mux = &alc861vd_capture_source,
14788 .unsol_event = alc861vd_lenovo_unsol_event,
a9fd4f3f 14789 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 14790 },
272a527c
KY
14791 [ALC861VD_DALLAS] = {
14792 .mixers = { alc861vd_dallas_mixer },
14793 .init_verbs = { alc861vd_dallas_verbs },
14794 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14795 .dac_nids = alc861vd_dac_nids,
272a527c
KY
14796 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14797 .channel_mode = alc861vd_3stack_2ch_modes,
14798 .input_mux = &alc861vd_dallas_capture_source,
a9fd4f3f
TI
14799 .unsol_event = alc_automute_amp_unsol_event,
14800 .init_hook = alc861vd_dallas_init_hook,
d1a991a6
KY
14801 },
14802 [ALC861VD_HP] = {
14803 .mixers = { alc861vd_hp_mixer },
14804 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14805 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14806 .dac_nids = alc861vd_dac_nids,
d1a991a6 14807 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
14808 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14809 .channel_mode = alc861vd_3stack_2ch_modes,
14810 .input_mux = &alc861vd_hp_capture_source,
a9fd4f3f
TI
14811 .unsol_event = alc_automute_amp_unsol_event,
14812 .init_hook = alc861vd_dallas_init_hook,
ea1fb29a 14813 },
13c94744
TI
14814 [ALC660VD_ASUS_V1S] = {
14815 .mixers = { alc861vd_lenovo_mixer },
14816 .init_verbs = { alc861vd_volume_init_verbs,
14817 alc861vd_3stack_init_verbs,
14818 alc861vd_eapd_verbs,
14819 alc861vd_lenovo_unsol_verbs },
14820 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14821 .dac_nids = alc660vd_dac_nids,
14822 .dig_out_nid = ALC861VD_DIGOUT_NID,
14823 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14824 .channel_mode = alc861vd_3stack_2ch_modes,
14825 .input_mux = &alc861vd_capture_source,
14826 .unsol_event = alc861vd_lenovo_unsol_event,
a9fd4f3f 14827 .init_hook = alc861vd_lenovo_init_hook,
13c94744 14828 },
f32610ed
JS
14829};
14830
14831/*
14832 * BIOS auto configuration
14833 */
14834static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14835 hda_nid_t nid, int pin_type, int dac_idx)
14836{
f6c7e546 14837 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
14838}
14839
14840static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14841{
14842 struct alc_spec *spec = codec->spec;
14843 int i;
14844
14845 for (i = 0; i <= HDA_SIDE; i++) {
14846 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 14847 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
14848 if (nid)
14849 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 14850 pin_type, i);
f32610ed
JS
14851 }
14852}
14853
14854
14855static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14856{
14857 struct alc_spec *spec = codec->spec;
14858 hda_nid_t pin;
14859
14860 pin = spec->autocfg.hp_pins[0];
def319f9 14861 if (pin) /* connect to front and use dac 0 */
f32610ed 14862 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
14863 pin = spec->autocfg.speaker_pins[0];
14864 if (pin)
14865 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
14866}
14867
14868#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14869#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14870
14871static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14872{
14873 struct alc_spec *spec = codec->spec;
14874 int i;
14875
14876 for (i = 0; i < AUTO_PIN_LAST; i++) {
14877 hda_nid_t nid = spec->autocfg.input_pins[i];
14878 if (alc861vd_is_input_pin(nid)) {
23f0c048 14879 alc_set_input_pin(codec, nid, i);
e82c025b
TI
14880 if (nid != ALC861VD_PIN_CD_NID &&
14881 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
14882 snd_hda_codec_write(codec, nid, 0,
14883 AC_VERB_SET_AMP_GAIN_MUTE,
14884 AMP_OUT_MUTE);
14885 }
14886 }
14887}
14888
f511b01c
TI
14889#define alc861vd_auto_init_input_src alc882_auto_init_input_src
14890
f32610ed
JS
14891#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14892#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14893
14894/* add playback controls from the parsed DAC table */
14895/* Based on ALC880 version. But ALC861VD has separate,
14896 * different NIDs for mute/unmute switch and volume control */
14897static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14898 const struct auto_pin_cfg *cfg)
14899{
14900 char name[32];
14901 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14902 hda_nid_t nid_v, nid_s;
14903 int i, err;
14904
14905 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 14906 if (!spec->multiout.dac_nids[i])
f32610ed
JS
14907 continue;
14908 nid_v = alc861vd_idx_to_mixer_vol(
14909 alc880_dac_to_idx(
14910 spec->multiout.dac_nids[i]));
14911 nid_s = alc861vd_idx_to_mixer_switch(
14912 alc880_dac_to_idx(
14913 spec->multiout.dac_nids[i]));
14914
14915 if (i == 2) {
14916 /* Center/LFE */
f12ab1e0
TI
14917 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14918 "Center Playback Volume",
14919 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14920 HDA_OUTPUT));
14921 if (err < 0)
f32610ed 14922 return err;
f12ab1e0
TI
14923 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14924 "LFE Playback Volume",
14925 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14926 HDA_OUTPUT));
14927 if (err < 0)
f32610ed 14928 return err;
f12ab1e0
TI
14929 err = add_control(spec, ALC_CTL_BIND_MUTE,
14930 "Center Playback Switch",
14931 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14932 HDA_INPUT));
14933 if (err < 0)
f32610ed 14934 return err;
f12ab1e0
TI
14935 err = add_control(spec, ALC_CTL_BIND_MUTE,
14936 "LFE Playback Switch",
14937 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14938 HDA_INPUT));
14939 if (err < 0)
f32610ed
JS
14940 return err;
14941 } else {
14942 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
14943 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14944 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14945 HDA_OUTPUT));
14946 if (err < 0)
f32610ed
JS
14947 return err;
14948 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0 14949 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
bdd148a3 14950 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
14951 HDA_INPUT));
14952 if (err < 0)
f32610ed
JS
14953 return err;
14954 }
14955 }
14956 return 0;
14957}
14958
14959/* add playback controls for speaker and HP outputs */
14960/* Based on ALC880 version. But ALC861VD has separate,
14961 * different NIDs for mute/unmute switch and volume control */
14962static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14963 hda_nid_t pin, const char *pfx)
14964{
14965 hda_nid_t nid_v, nid_s;
14966 int err;
14967 char name[32];
14968
f12ab1e0 14969 if (!pin)
f32610ed
JS
14970 return 0;
14971
14972 if (alc880_is_fixed_pin(pin)) {
14973 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14974 /* specify the DAC as the extra output */
f12ab1e0 14975 if (!spec->multiout.hp_nid)
f32610ed
JS
14976 spec->multiout.hp_nid = nid_v;
14977 else
14978 spec->multiout.extra_out_nid[0] = nid_v;
14979 /* control HP volume/switch on the output mixer amp */
14980 nid_v = alc861vd_idx_to_mixer_vol(
14981 alc880_fixed_pin_idx(pin));
14982 nid_s = alc861vd_idx_to_mixer_switch(
14983 alc880_fixed_pin_idx(pin));
14984
14985 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
14986 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14987 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14988 if (err < 0)
f32610ed
JS
14989 return err;
14990 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
14991 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14992 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14993 if (err < 0)
f32610ed
JS
14994 return err;
14995 } else if (alc880_is_multi_pin(pin)) {
14996 /* set manual connection */
14997 /* we have only a switch on HP-out PIN */
14998 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
14999 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15000 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15001 if (err < 0)
f32610ed
JS
15002 return err;
15003 }
15004 return 0;
15005}
15006
15007/* parse the BIOS configuration and set up the alc_spec
15008 * return 1 if successful, 0 if the proper config is not found,
15009 * or a negative error code
15010 * Based on ALC880 version - had to change it to override
15011 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15012static int alc861vd_parse_auto_config(struct hda_codec *codec)
15013{
15014 struct alc_spec *spec = codec->spec;
15015 int err;
15016 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15017
f12ab1e0
TI
15018 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15019 alc861vd_ignore);
15020 if (err < 0)
f32610ed 15021 return err;
f12ab1e0 15022 if (!spec->autocfg.line_outs)
f32610ed
JS
15023 return 0; /* can't find valid BIOS pin config */
15024
f12ab1e0
TI
15025 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15026 if (err < 0)
15027 return err;
15028 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15029 if (err < 0)
15030 return err;
15031 err = alc861vd_auto_create_extra_out(spec,
15032 spec->autocfg.speaker_pins[0],
15033 "Speaker");
15034 if (err < 0)
15035 return err;
15036 err = alc861vd_auto_create_extra_out(spec,
15037 spec->autocfg.hp_pins[0],
15038 "Headphone");
15039 if (err < 0)
15040 return err;
15041 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
15042 if (err < 0)
f32610ed
JS
15043 return err;
15044
15045 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15046
0852d7a6 15047 if (spec->autocfg.dig_outs)
f32610ed
JS
15048 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15049
603c4019 15050 if (spec->kctls.list)
d88897ea 15051 add_mixer(spec, spec->kctls.list);
f32610ed 15052
d88897ea 15053 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
15054
15055 spec->num_mux_defs = 1;
61b9b9b1 15056 spec->input_mux = &spec->private_imux[0];
f32610ed 15057
776e184e
TI
15058 err = alc_auto_add_mic_boost(codec);
15059 if (err < 0)
15060 return err;
15061
4a79ba34
TI
15062 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
15063
f32610ed
JS
15064 return 1;
15065}
15066
15067/* additional initialization for auto-configuration model */
15068static void alc861vd_auto_init(struct hda_codec *codec)
15069{
f6c7e546 15070 struct alc_spec *spec = codec->spec;
f32610ed
JS
15071 alc861vd_auto_init_multi_out(codec);
15072 alc861vd_auto_init_hp_out(codec);
15073 alc861vd_auto_init_analog_input(codec);
f511b01c 15074 alc861vd_auto_init_input_src(codec);
f6c7e546 15075 if (spec->unsol_event)
7fb0d78f 15076 alc_inithook(codec);
f32610ed
JS
15077}
15078
15079static int patch_alc861vd(struct hda_codec *codec)
15080{
15081 struct alc_spec *spec;
15082 int err, board_config;
15083
15084 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15085 if (spec == NULL)
15086 return -ENOMEM;
15087
15088 codec->spec = spec;
15089
15090 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15091 alc861vd_models,
15092 alc861vd_cfg_tbl);
15093
15094 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
6c627f39
TI
15095 printk(KERN_INFO "hda_codec: Unknown model for %s, "
15096 "trying auto-probe from BIOS...\n", codec->chip_name);
f32610ed
JS
15097 board_config = ALC861VD_AUTO;
15098 }
15099
15100 if (board_config == ALC861VD_AUTO) {
15101 /* automatic parse from the BIOS config */
15102 err = alc861vd_parse_auto_config(codec);
15103 if (err < 0) {
15104 alc_free(codec);
15105 return err;
f12ab1e0 15106 } else if (!err) {
f32610ed
JS
15107 printk(KERN_INFO
15108 "hda_codec: Cannot set up configuration "
15109 "from BIOS. Using base mode...\n");
15110 board_config = ALC861VD_3ST;
15111 }
15112 }
15113
680cd536
KK
15114 err = snd_hda_attach_beep_device(codec, 0x23);
15115 if (err < 0) {
15116 alc_free(codec);
15117 return err;
15118 }
15119
f32610ed
JS
15120 if (board_config != ALC861VD_AUTO)
15121 setup_preset(spec, &alc861vd_presets[board_config]);
15122
2f893286 15123 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 15124 /* always turn on EAPD */
d88897ea 15125 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
15126 }
15127
f32610ed
JS
15128 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15129 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15130
f32610ed
JS
15131 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15132 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15133
15134 spec->adc_nids = alc861vd_adc_nids;
15135 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
e1406348 15136 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 15137
f9e336f6 15138 set_capture_mixer(spec);
45bdd1c1 15139 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 15140
2134ea4f
TI
15141 spec->vmaster_nid = 0x02;
15142
f32610ed
JS
15143 codec->patch_ops = alc_patch_ops;
15144
15145 if (board_config == ALC861VD_AUTO)
15146 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
15147#ifdef CONFIG_SND_HDA_POWER_SAVE
15148 if (!spec->loopback.amplist)
15149 spec->loopback.amplist = alc861vd_loopbacks;
15150#endif
daead538 15151 codec->proc_widget_hook = print_realtek_coef;
f32610ed
JS
15152
15153 return 0;
15154}
15155
bc9f98a9
KY
15156/*
15157 * ALC662 support
15158 *
15159 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15160 * configuration. Each pin widget can choose any input DACs and a mixer.
15161 * Each ADC is connected from a mixer of all inputs. This makes possible
15162 * 6-channel independent captures.
15163 *
15164 * In addition, an independent DAC for the multi-playback (not used in this
15165 * driver yet).
15166 */
15167#define ALC662_DIGOUT_NID 0x06
15168#define ALC662_DIGIN_NID 0x0a
15169
15170static hda_nid_t alc662_dac_nids[4] = {
15171 /* front, rear, clfe, rear_surr */
15172 0x02, 0x03, 0x04
15173};
15174
622e84cd
KY
15175static hda_nid_t alc272_dac_nids[2] = {
15176 0x02, 0x03
15177};
15178
bc9f98a9
KY
15179static hda_nid_t alc662_adc_nids[1] = {
15180 /* ADC1-2 */
15181 0x09,
15182};
e1406348 15183
622e84cd
KY
15184static hda_nid_t alc272_adc_nids[1] = {
15185 /* ADC1-2 */
15186 0x08,
15187};
15188
77a261b7 15189static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
622e84cd
KY
15190static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15191
e1406348 15192
bc9f98a9
KY
15193/* input MUX */
15194/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
15195static struct hda_input_mux alc662_capture_source = {
15196 .num_items = 4,
15197 .items = {
15198 { "Mic", 0x0 },
15199 { "Front Mic", 0x1 },
15200 { "Line", 0x2 },
15201 { "CD", 0x4 },
15202 },
15203};
15204
15205static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15206 .num_items = 2,
15207 .items = {
15208 { "Mic", 0x1 },
15209 { "Line", 0x2 },
15210 },
15211};
291702f0
KY
15212
15213static struct hda_input_mux alc662_eeepc_capture_source = {
15214 .num_items = 2,
15215 .items = {
15216 { "i-Mic", 0x1 },
15217 { "e-Mic", 0x0 },
15218 },
15219};
15220
6dda9f4a
KY
15221static struct hda_input_mux alc663_capture_source = {
15222 .num_items = 3,
15223 .items = {
15224 { "Mic", 0x0 },
15225 { "Front Mic", 0x1 },
15226 { "Line", 0x2 },
15227 },
15228};
15229
15230static struct hda_input_mux alc663_m51va_capture_source = {
15231 .num_items = 2,
15232 .items = {
15233 { "Ext-Mic", 0x0 },
15234 { "D-Mic", 0x9 },
15235 },
15236};
15237
9541ba1d
CP
15238#if 1 /* set to 0 for testing other input sources below */
15239static struct hda_input_mux alc272_nc10_capture_source = {
15240 .num_items = 2,
15241 .items = {
15242 { "Autoselect Mic", 0x0 },
15243 { "Internal Mic", 0x1 },
15244 },
15245};
15246#else
15247static struct hda_input_mux alc272_nc10_capture_source = {
15248 .num_items = 16,
15249 .items = {
15250 { "Autoselect Mic", 0x0 },
15251 { "Internal Mic", 0x1 },
15252 { "In-0x02", 0x2 },
15253 { "In-0x03", 0x3 },
15254 { "In-0x04", 0x4 },
15255 { "In-0x05", 0x5 },
15256 { "In-0x06", 0x6 },
15257 { "In-0x07", 0x7 },
15258 { "In-0x08", 0x8 },
15259 { "In-0x09", 0x9 },
15260 { "In-0x0a", 0x0a },
15261 { "In-0x0b", 0x0b },
15262 { "In-0x0c", 0x0c },
15263 { "In-0x0d", 0x0d },
15264 { "In-0x0e", 0x0e },
15265 { "In-0x0f", 0x0f },
15266 },
15267};
15268#endif
15269
bc9f98a9
KY
15270/*
15271 * 2ch mode
15272 */
15273static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15274 { 2, NULL }
15275};
15276
15277/*
15278 * 2ch mode
15279 */
15280static struct hda_verb alc662_3ST_ch2_init[] = {
15281 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15282 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15283 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15284 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15285 { } /* end */
15286};
15287
15288/*
15289 * 6ch mode
15290 */
15291static struct hda_verb alc662_3ST_ch6_init[] = {
15292 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15293 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15294 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15295 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15296 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15297 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15298 { } /* end */
15299};
15300
15301static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15302 { 2, alc662_3ST_ch2_init },
15303 { 6, alc662_3ST_ch6_init },
15304};
15305
15306/*
15307 * 2ch mode
15308 */
15309static struct hda_verb alc662_sixstack_ch6_init[] = {
15310 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15311 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15312 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15313 { } /* end */
15314};
15315
15316/*
15317 * 6ch mode
15318 */
15319static struct hda_verb alc662_sixstack_ch8_init[] = {
15320 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15321 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15322 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15323 { } /* end */
15324};
15325
15326static struct hda_channel_mode alc662_5stack_modes[2] = {
15327 { 2, alc662_sixstack_ch6_init },
15328 { 6, alc662_sixstack_ch8_init },
15329};
15330
15331/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15332 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15333 */
15334
15335static struct snd_kcontrol_new alc662_base_mixer[] = {
15336 /* output mixer control */
15337 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 15338 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 15339 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 15340 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
15341 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15342 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
15343 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15344 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
15345 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15346
15347 /*Input mixer control */
15348 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15349 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15350 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15351 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15352 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15353 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15354 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15355 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
15356 { } /* end */
15357};
15358
15359static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15360 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 15361 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
15362 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15363 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15364 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15365 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15366 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15367 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15368 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15369 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15370 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
15371 { } /* end */
15372};
15373
15374static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15375 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 15376 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 15377 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 15378 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
15379 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15380 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
15381 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15382 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
15383 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15384 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15385 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15386 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15387 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15388 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15389 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15390 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15391 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
15392 { } /* end */
15393};
15394
15395static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15396 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15397 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
15398 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15399 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
15400 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15401 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15402 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15403 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15404 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
15405 { } /* end */
15406};
15407
291702f0 15408static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
15409 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15410 ALC262_HIPPO_MASTER_SWITCH,
291702f0
KY
15411
15412 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15413 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15414 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15415
15416 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15417 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15418 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15419 { } /* end */
15420};
15421
8c427226 15422static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
15423 ALC262_HIPPO_MASTER_SWITCH,
15424 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 15425 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
15426 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15427 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
15428 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15429 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15430 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15431 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15432 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15433 { } /* end */
15434};
15435
f1d4e28b
KY
15436static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15437 .ops = &snd_hda_bind_vol,
15438 .values = {
15439 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15440 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15441 0
15442 },
15443};
15444
15445static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15446 .ops = &snd_hda_bind_sw,
15447 .values = {
15448 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15449 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15450 0
15451 },
15452};
15453
6dda9f4a 15454static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
15455 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15456 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15457 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15458 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15459 { } /* end */
15460};
15461
15462static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15463 .ops = &snd_hda_bind_sw,
15464 .values = {
15465 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15466 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15467 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15468 0
15469 },
15470};
15471
15472static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15473 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15474 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15475 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15476 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15477 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15478 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15479
15480 { } /* end */
15481};
15482
15483static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15484 .ops = &snd_hda_bind_sw,
15485 .values = {
15486 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15487 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15488 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15489 0
15490 },
15491};
15492
15493static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15494 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15495 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15496 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15497 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15498 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15499 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15500 { } /* end */
15501};
15502
15503static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
15504 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15505 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
15506 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15507 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15508 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15509 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15510 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15511 { } /* end */
15512};
15513
15514static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15515 .ops = &snd_hda_bind_vol,
15516 .values = {
15517 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15518 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15519 0
15520 },
15521};
15522
15523static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15524 .ops = &snd_hda_bind_sw,
15525 .values = {
15526 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15527 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15528 0
15529 },
15530};
15531
15532static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15533 HDA_BIND_VOL("Master Playback Volume",
15534 &alc663_asus_two_bind_master_vol),
15535 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15536 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
15537 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15538 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15539 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
15540 { } /* end */
15541};
15542
15543static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15544 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15545 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15546 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15547 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15548 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15549 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
15550 { } /* end */
15551};
15552
15553static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15554 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15555 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15556 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15557 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15558 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15559
15560 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15561 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15562 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15563 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15564 { } /* end */
15565};
15566
15567static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15568 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15569 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15570 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15571
15572 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15573 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15574 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15575 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15576 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15577 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15578 { } /* end */
15579};
15580
bc9f98a9
KY
15581static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15582 {
15583 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15584 .name = "Channel Mode",
15585 .info = alc_ch_mode_info,
15586 .get = alc_ch_mode_get,
15587 .put = alc_ch_mode_put,
15588 },
15589 { } /* end */
15590};
15591
15592static struct hda_verb alc662_init_verbs[] = {
15593 /* ADC: mute amp left and right */
15594 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15595 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15596 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15597
cb53c626
TI
15598 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15599 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15600 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15601 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15602 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9 15603
b60dd394
KY
15604 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15605 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15606 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15607 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15608 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15609 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
15610
15611 /* Front Pin: output 0 (0x0c) */
15612 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15613 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15614
15615 /* Rear Pin: output 1 (0x0d) */
15616 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15617 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15618
15619 /* CLFE Pin: output 2 (0x0e) */
15620 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15621 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15622
15623 /* Mic (rear) pin: input vref at 80% */
15624 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15625 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15626 /* Front Mic pin: input vref at 80% */
15627 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15628 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15629 /* Line In pin: input */
15630 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15631 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15632 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15633 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15634 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15635 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15636 /* CD pin widget for input */
15637 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15638
15639 /* FIXME: use matrix-type input source selection */
15640 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15641 /* Input mixer */
15642 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 15643 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a
KY
15644
15645 /* always trun on EAPD */
15646 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15647 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15648
bc9f98a9
KY
15649 { }
15650};
15651
15652static struct hda_verb alc662_sue_init_verbs[] = {
15653 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15654 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
15655 {}
15656};
15657
15658static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15659 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15660 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15661 {}
bc9f98a9
KY
15662};
15663
8c427226
KY
15664/* Set Unsolicited Event*/
15665static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15666 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15667 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15668 {}
15669};
15670
bc9f98a9
KY
15671/*
15672 * generic initialization of ADC, input mixers and output mixers
15673 */
15674static struct hda_verb alc662_auto_init_verbs[] = {
15675 /*
15676 * Unmute ADC and set the default input to mic-in
15677 */
15678 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15679 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15680
15681 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15682 * mixer widget
15683 * Note: PASD motherboards uses the Line In 2 as the input for front
15684 * panel mic (mic 2)
15685 */
15686 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
15687 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15688 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15689 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15690 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15691 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9
KY
15692
15693 /*
15694 * Set up output mixers (0x0c - 0x0f)
15695 */
15696 /* set vol=0 to output mixers */
15697 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15698 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15699 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15700
15701 /* set up input amps for analog loopback */
15702 /* Amp Indices: DAC = 0, mixer = 1 */
b60dd394
KY
15703 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15704 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15705 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15706 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15707 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15708 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
15709
15710
15711 /* FIXME: use matrix-type input source selection */
15712 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15713 /* Input mixer */
15714 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
d1a991a6 15715 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
bc9f98a9
KY
15716 { }
15717};
15718
24fb9173
TI
15719/* additional verbs for ALC663 */
15720static struct hda_verb alc663_auto_init_verbs[] = {
15721 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15722 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15723 { }
15724};
15725
6dda9f4a 15726static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
15727 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15728 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
15729 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15730 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
15731 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15732 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15733 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15734 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15735 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15736 {}
15737};
15738
15739static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15740 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15741 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15742 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15743 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15744 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15745 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15746 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15747 {}
15748};
15749
15750static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15751 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15752 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15753 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15754 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15755 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15756 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15757 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15758 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15759 {}
15760};
6dda9f4a 15761
f1d4e28b
KY
15762static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15763 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15764 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15765 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15766 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15767 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15768 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15769 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15770 {}
15771};
6dda9f4a 15772
f1d4e28b
KY
15773static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15774 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15775 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15776 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15777 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15778 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15779 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15780 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15781 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15782 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
15783 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15784 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
15785 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15786 {}
15787};
15788
15789static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15790 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15791 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15792 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15793 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15794 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15795 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15796 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15797 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15798 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15799 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15800 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15801 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
15802 {}
15803};
15804
15805static struct hda_verb alc663_g71v_init_verbs[] = {
15806 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15807 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15808 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15809
15810 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15811 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15812 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15813
15814 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15815 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15816 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15817 {}
15818};
15819
15820static struct hda_verb alc663_g50v_init_verbs[] = {
15821 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15822 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15823 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15824
15825 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15826 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15827 {}
15828};
15829
f1d4e28b
KY
15830static struct hda_verb alc662_ecs_init_verbs[] = {
15831 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15832 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15833 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15834 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15835 {}
15836};
15837
622e84cd
KY
15838static struct hda_verb alc272_dell_zm1_init_verbs[] = {
15839 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15840 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15841 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15842 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15843 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15844 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15845 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15846 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15847 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15848 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15849 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15850 {}
15851};
15852
15853static struct hda_verb alc272_dell_init_verbs[] = {
15854 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15855 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15856 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15857 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15858 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15859 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15860 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15861 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15862 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15863 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15864 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15865 {}
15866};
15867
f1d4e28b
KY
15868static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15869 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15870 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15871 { } /* end */
15872};
15873
622e84cd
KY
15874static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
15875 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
15876 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
15877 { } /* end */
15878};
15879
bc9f98a9
KY
15880static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15881{
15882 unsigned int present;
f12ab1e0 15883 unsigned char bits;
bc9f98a9
KY
15884
15885 present = snd_hda_codec_read(codec, 0x14, 0,
15886 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
15887 bits = present ? HDA_AMP_MUTE : 0;
15888 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15889 HDA_AMP_MUTE, bits);
bc9f98a9
KY
15890}
15891
15892static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15893{
15894 unsigned int present;
f12ab1e0 15895 unsigned char bits;
bc9f98a9
KY
15896
15897 present = snd_hda_codec_read(codec, 0x1b, 0,
15898 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
15899 bits = present ? HDA_AMP_MUTE : 0;
15900 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15901 HDA_AMP_MUTE, bits);
15902 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15903 HDA_AMP_MUTE, bits);
bc9f98a9
KY
15904}
15905
15906static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15907 unsigned int res)
15908{
15909 if ((res >> 26) == ALC880_HP_EVENT)
15910 alc662_lenovo_101e_all_automute(codec);
15911 if ((res >> 26) == ALC880_FRONT_EVENT)
15912 alc662_lenovo_101e_ispeaker_automute(codec);
15913}
15914
291702f0
KY
15915static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15916{
15917 unsigned int present;
15918
15919 present = snd_hda_codec_read(codec, 0x18, 0,
15920 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15921 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15922 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15923 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15924 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15925 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15926 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15927 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15928 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15929}
15930
15931/* unsolicited event for HP jack sensing */
15932static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15933 unsigned int res)
15934{
291702f0
KY
15935 if ((res >> 26) == ALC880_MIC_EVENT)
15936 alc662_eeepc_mic_automute(codec);
42171c17
TI
15937 else
15938 alc262_hippo_unsol_event(codec, res);
291702f0
KY
15939}
15940
15941static void alc662_eeepc_inithook(struct hda_codec *codec)
15942{
42171c17 15943 alc262_hippo1_init_hook(codec);
291702f0
KY
15944 alc662_eeepc_mic_automute(codec);
15945}
15946
8c427226
KY
15947static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15948{
42171c17
TI
15949 struct alc_spec *spec = codec->spec;
15950
15951 spec->autocfg.hp_pins[0] = 0x14;
15952 spec->autocfg.speaker_pins[0] = 0x1b;
15953 alc262_hippo_master_update(codec);
8c427226
KY
15954}
15955
6dda9f4a
KY
15956static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15957{
15958 unsigned int present;
15959 unsigned char bits;
15960
15961 present = snd_hda_codec_read(codec, 0x21, 0,
f1d4e28b
KY
15962 AC_VERB_GET_PIN_SENSE, 0)
15963 & AC_PINSENSE_PRESENCE;
6dda9f4a 15964 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b
KY
15965 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15966 AMP_IN_MUTE(0), bits);
15967 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15968 AMP_IN_MUTE(0), bits);
15969}
15970
15971static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15972{
15973 unsigned int present;
15974 unsigned char bits;
15975
15976 present = snd_hda_codec_read(codec, 0x21, 0,
15977 AC_VERB_GET_PIN_SENSE, 0)
15978 & AC_PINSENSE_PRESENCE;
15979 bits = present ? HDA_AMP_MUTE : 0;
15980 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15981 AMP_IN_MUTE(0), bits);
15982 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15983 AMP_IN_MUTE(0), bits);
15984 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15985 AMP_IN_MUTE(0), bits);
15986 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15987 AMP_IN_MUTE(0), bits);
15988}
15989
15990static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15991{
15992 unsigned int present;
15993 unsigned char bits;
15994
15995 present = snd_hda_codec_read(codec, 0x15, 0,
15996 AC_VERB_GET_PIN_SENSE, 0)
15997 & AC_PINSENSE_PRESENCE;
15998 bits = present ? HDA_AMP_MUTE : 0;
15999 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16000 AMP_IN_MUTE(0), bits);
16001 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16002 AMP_IN_MUTE(0), bits);
16003 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16004 AMP_IN_MUTE(0), bits);
16005 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16006 AMP_IN_MUTE(0), bits);
16007}
16008
16009static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16010{
16011 unsigned int present;
16012 unsigned char bits;
16013
16014 present = snd_hda_codec_read(codec, 0x1b, 0,
16015 AC_VERB_GET_PIN_SENSE, 0)
16016 & AC_PINSENSE_PRESENCE;
16017 bits = present ? 0 : PIN_OUT;
16018 snd_hda_codec_write(codec, 0x14, 0,
16019 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16020}
16021
16022static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16023{
16024 unsigned int present1, present2;
16025
16026 present1 = snd_hda_codec_read(codec, 0x21, 0,
16027 AC_VERB_GET_PIN_SENSE, 0)
16028 & AC_PINSENSE_PRESENCE;
16029 present2 = snd_hda_codec_read(codec, 0x15, 0,
16030 AC_VERB_GET_PIN_SENSE, 0)
16031 & AC_PINSENSE_PRESENCE;
16032
16033 if (present1 || present2) {
16034 snd_hda_codec_write_cache(codec, 0x14, 0,
16035 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16036 } else {
16037 snd_hda_codec_write_cache(codec, 0x14, 0,
16038 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16039 }
16040}
16041
16042static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16043{
16044 unsigned int present1, present2;
16045
16046 present1 = snd_hda_codec_read(codec, 0x1b, 0,
16047 AC_VERB_GET_PIN_SENSE, 0)
16048 & AC_PINSENSE_PRESENCE;
16049 present2 = snd_hda_codec_read(codec, 0x15, 0,
16050 AC_VERB_GET_PIN_SENSE, 0)
16051 & AC_PINSENSE_PRESENCE;
16052
16053 if (present1 || present2) {
16054 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16055 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16056 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16057 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16058 } else {
16059 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16060 AMP_IN_MUTE(0), 0);
16061 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16062 AMP_IN_MUTE(0), 0);
16063 }
6dda9f4a
KY
16064}
16065
16066static void alc663_m51va_mic_automute(struct hda_codec *codec)
16067{
16068 unsigned int present;
16069
16070 present = snd_hda_codec_read(codec, 0x18, 0,
ea1fb29a
KY
16071 AC_VERB_GET_PIN_SENSE, 0)
16072 & AC_PINSENSE_PRESENCE;
6dda9f4a 16073 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 16074 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
6dda9f4a 16075 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 16076 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
6dda9f4a 16077 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 16078 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
6dda9f4a 16079 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 16080 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
6dda9f4a
KY
16081}
16082
16083static void alc663_m51va_unsol_event(struct hda_codec *codec,
16084 unsigned int res)
16085{
16086 switch (res >> 26) {
16087 case ALC880_HP_EVENT:
16088 alc663_m51va_speaker_automute(codec);
16089 break;
16090 case ALC880_MIC_EVENT:
16091 alc663_m51va_mic_automute(codec);
16092 break;
16093 }
16094}
16095
16096static void alc663_m51va_inithook(struct hda_codec *codec)
16097{
16098 alc663_m51va_speaker_automute(codec);
16099 alc663_m51va_mic_automute(codec);
16100}
16101
f1d4e28b
KY
16102/* ***************** Mode1 ******************************/
16103static void alc663_mode1_unsol_event(struct hda_codec *codec,
16104 unsigned int res)
16105{
16106 switch (res >> 26) {
16107 case ALC880_HP_EVENT:
16108 alc663_m51va_speaker_automute(codec);
16109 break;
16110 case ALC880_MIC_EVENT:
16111 alc662_eeepc_mic_automute(codec);
16112 break;
16113 }
16114}
16115
16116static void alc663_mode1_inithook(struct hda_codec *codec)
16117{
16118 alc663_m51va_speaker_automute(codec);
16119 alc662_eeepc_mic_automute(codec);
16120}
16121/* ***************** Mode2 ******************************/
16122static void alc662_mode2_unsol_event(struct hda_codec *codec,
16123 unsigned int res)
16124{
16125 switch (res >> 26) {
16126 case ALC880_HP_EVENT:
16127 alc662_f5z_speaker_automute(codec);
16128 break;
16129 case ALC880_MIC_EVENT:
16130 alc662_eeepc_mic_automute(codec);
16131 break;
16132 }
16133}
16134
16135static void alc662_mode2_inithook(struct hda_codec *codec)
16136{
16137 alc662_f5z_speaker_automute(codec);
16138 alc662_eeepc_mic_automute(codec);
16139}
16140/* ***************** Mode3 ******************************/
16141static void alc663_mode3_unsol_event(struct hda_codec *codec,
16142 unsigned int res)
16143{
16144 switch (res >> 26) {
16145 case ALC880_HP_EVENT:
16146 alc663_two_hp_m1_speaker_automute(codec);
16147 break;
16148 case ALC880_MIC_EVENT:
16149 alc662_eeepc_mic_automute(codec);
16150 break;
16151 }
16152}
16153
16154static void alc663_mode3_inithook(struct hda_codec *codec)
16155{
16156 alc663_two_hp_m1_speaker_automute(codec);
16157 alc662_eeepc_mic_automute(codec);
16158}
16159/* ***************** Mode4 ******************************/
16160static void alc663_mode4_unsol_event(struct hda_codec *codec,
16161 unsigned int res)
16162{
16163 switch (res >> 26) {
16164 case ALC880_HP_EVENT:
16165 alc663_21jd_two_speaker_automute(codec);
16166 break;
16167 case ALC880_MIC_EVENT:
16168 alc662_eeepc_mic_automute(codec);
16169 break;
16170 }
16171}
16172
16173static void alc663_mode4_inithook(struct hda_codec *codec)
16174{
16175 alc663_21jd_two_speaker_automute(codec);
16176 alc662_eeepc_mic_automute(codec);
16177}
16178/* ***************** Mode5 ******************************/
16179static void alc663_mode5_unsol_event(struct hda_codec *codec,
16180 unsigned int res)
16181{
16182 switch (res >> 26) {
16183 case ALC880_HP_EVENT:
16184 alc663_15jd_two_speaker_automute(codec);
16185 break;
16186 case ALC880_MIC_EVENT:
16187 alc662_eeepc_mic_automute(codec);
16188 break;
16189 }
16190}
16191
16192static void alc663_mode5_inithook(struct hda_codec *codec)
16193{
16194 alc663_15jd_two_speaker_automute(codec);
16195 alc662_eeepc_mic_automute(codec);
16196}
16197/* ***************** Mode6 ******************************/
16198static void alc663_mode6_unsol_event(struct hda_codec *codec,
16199 unsigned int res)
16200{
16201 switch (res >> 26) {
16202 case ALC880_HP_EVENT:
16203 alc663_two_hp_m2_speaker_automute(codec);
16204 break;
16205 case ALC880_MIC_EVENT:
16206 alc662_eeepc_mic_automute(codec);
16207 break;
16208 }
16209}
16210
16211static void alc663_mode6_inithook(struct hda_codec *codec)
16212{
16213 alc663_two_hp_m2_speaker_automute(codec);
16214 alc662_eeepc_mic_automute(codec);
16215}
16216
6dda9f4a
KY
16217static void alc663_g71v_hp_automute(struct hda_codec *codec)
16218{
16219 unsigned int present;
16220 unsigned char bits;
16221
16222 present = snd_hda_codec_read(codec, 0x21, 0,
16223 AC_VERB_GET_PIN_SENSE, 0)
16224 & AC_PINSENSE_PRESENCE;
16225 bits = present ? HDA_AMP_MUTE : 0;
16226 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16227 HDA_AMP_MUTE, bits);
16228 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16229 HDA_AMP_MUTE, bits);
16230}
16231
16232static void alc663_g71v_front_automute(struct hda_codec *codec)
16233{
16234 unsigned int present;
16235 unsigned char bits;
16236
16237 present = snd_hda_codec_read(codec, 0x15, 0,
16238 AC_VERB_GET_PIN_SENSE, 0)
16239 & AC_PINSENSE_PRESENCE;
16240 bits = present ? HDA_AMP_MUTE : 0;
16241 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16242 HDA_AMP_MUTE, bits);
16243}
16244
16245static void alc663_g71v_unsol_event(struct hda_codec *codec,
16246 unsigned int res)
16247{
16248 switch (res >> 26) {
16249 case ALC880_HP_EVENT:
16250 alc663_g71v_hp_automute(codec);
16251 break;
16252 case ALC880_FRONT_EVENT:
16253 alc663_g71v_front_automute(codec);
16254 break;
16255 case ALC880_MIC_EVENT:
16256 alc662_eeepc_mic_automute(codec);
16257 break;
16258 }
16259}
16260
16261static void alc663_g71v_inithook(struct hda_codec *codec)
16262{
16263 alc663_g71v_front_automute(codec);
16264 alc663_g71v_hp_automute(codec);
16265 alc662_eeepc_mic_automute(codec);
16266}
16267
16268static void alc663_g50v_unsol_event(struct hda_codec *codec,
16269 unsigned int res)
16270{
16271 switch (res >> 26) {
16272 case ALC880_HP_EVENT:
16273 alc663_m51va_speaker_automute(codec);
16274 break;
16275 case ALC880_MIC_EVENT:
16276 alc662_eeepc_mic_automute(codec);
16277 break;
16278 }
16279}
16280
16281static void alc663_g50v_inithook(struct hda_codec *codec)
16282{
16283 alc663_m51va_speaker_automute(codec);
16284 alc662_eeepc_mic_automute(codec);
16285}
16286
f1d4e28b
KY
16287static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16288 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 16289 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b
KY
16290
16291 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16292 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16293 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16294
16295 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16296 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16297 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16298 { } /* end */
16299};
16300
9541ba1d
CP
16301static struct snd_kcontrol_new alc272_nc10_mixer[] = {
16302 /* Master Playback automatically created from Speaker and Headphone */
16303 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16304 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16305 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16306 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16307
16308 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16309 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16310 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16311
16312 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16313 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16314 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16315 { } /* end */
16316};
16317
cb53c626
TI
16318#ifdef CONFIG_SND_HDA_POWER_SAVE
16319#define alc662_loopbacks alc880_loopbacks
16320#endif
16321
bc9f98a9 16322
def319f9 16323/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
16324#define alc662_pcm_analog_playback alc880_pcm_analog_playback
16325#define alc662_pcm_analog_capture alc880_pcm_analog_capture
16326#define alc662_pcm_digital_playback alc880_pcm_digital_playback
16327#define alc662_pcm_digital_capture alc880_pcm_digital_capture
16328
16329/*
16330 * configuration and preset
16331 */
16332static const char *alc662_models[ALC662_MODEL_LAST] = {
16333 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16334 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16335 [ALC662_3ST_6ch] = "3stack-6ch",
16336 [ALC662_5ST_DIG] = "6stack-dig",
16337 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 16338 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 16339 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 16340 [ALC662_ECS] = "ecs",
6dda9f4a
KY
16341 [ALC663_ASUS_M51VA] = "m51va",
16342 [ALC663_ASUS_G71V] = "g71v",
16343 [ALC663_ASUS_H13] = "h13",
16344 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
16345 [ALC663_ASUS_MODE1] = "asus-mode1",
16346 [ALC662_ASUS_MODE2] = "asus-mode2",
16347 [ALC663_ASUS_MODE3] = "asus-mode3",
16348 [ALC663_ASUS_MODE4] = "asus-mode4",
16349 [ALC663_ASUS_MODE5] = "asus-mode5",
16350 [ALC663_ASUS_MODE6] = "asus-mode6",
01f2bd48
TI
16351 [ALC272_DELL] = "dell",
16352 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 16353 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
16354 [ALC662_AUTO] = "auto",
16355};
16356
16357static struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 16358 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
16359 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16360 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 16361 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509
TI
16362 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16363 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 16364 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 16365 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 16366 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 16367 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
16368 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16369 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16370 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16371 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16372 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd
KY
16373 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16374 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16375 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 16376 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
16377 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16378 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16379 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 16380 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 16381 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
16382 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16383 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16384 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 16385 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 16386 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd
KY
16387 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16388 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16389 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
16390 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16391 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16392 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 16393 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
16394 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16395 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 16396 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
16397 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16398 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16399 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16400 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16401 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 16402 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 16403 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 16404 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
16405 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16406 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16407 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16408 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
16409 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16410 ALC662_3ST_6ch_DIG),
9541ba1d 16411 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
cb55974c
HRK
16412 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16413 ALC662_3ST_6ch_DIG),
19c009aa 16414 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 16415 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 16416 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 16417 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 16418 ALC662_3ST_6ch_DIG),
dea0a509
TI
16419 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16420 ALC663_ASUS_H13),
bc9f98a9
KY
16421 {}
16422};
16423
16424static struct alc_config_preset alc662_presets[] = {
16425 [ALC662_3ST_2ch_DIG] = {
f9e336f6 16426 .mixers = { alc662_3ST_2ch_mixer },
bc9f98a9
KY
16427 .init_verbs = { alc662_init_verbs },
16428 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16429 .dac_nids = alc662_dac_nids,
16430 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
16431 .dig_in_nid = ALC662_DIGIN_NID,
16432 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16433 .channel_mode = alc662_3ST_2ch_modes,
16434 .input_mux = &alc662_capture_source,
16435 },
16436 [ALC662_3ST_6ch_DIG] = {
f9e336f6 16437 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
16438 .init_verbs = { alc662_init_verbs },
16439 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16440 .dac_nids = alc662_dac_nids,
16441 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
16442 .dig_in_nid = ALC662_DIGIN_NID,
16443 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16444 .channel_mode = alc662_3ST_6ch_modes,
16445 .need_dac_fix = 1,
16446 .input_mux = &alc662_capture_source,
f12ab1e0 16447 },
bc9f98a9 16448 [ALC662_3ST_6ch] = {
f9e336f6 16449 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
bc9f98a9
KY
16450 .init_verbs = { alc662_init_verbs },
16451 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16452 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
16453 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16454 .channel_mode = alc662_3ST_6ch_modes,
16455 .need_dac_fix = 1,
16456 .input_mux = &alc662_capture_source,
f12ab1e0 16457 },
bc9f98a9 16458 [ALC662_5ST_DIG] = {
f9e336f6 16459 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
bc9f98a9
KY
16460 .init_verbs = { alc662_init_verbs },
16461 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16462 .dac_nids = alc662_dac_nids,
16463 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
16464 .dig_in_nid = ALC662_DIGIN_NID,
16465 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16466 .channel_mode = alc662_5stack_modes,
16467 .input_mux = &alc662_capture_source,
16468 },
16469 [ALC662_LENOVO_101E] = {
f9e336f6 16470 .mixers = { alc662_lenovo_101e_mixer },
bc9f98a9
KY
16471 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16472 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16473 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
16474 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16475 .channel_mode = alc662_3ST_2ch_modes,
16476 .input_mux = &alc662_lenovo_101e_capture_source,
16477 .unsol_event = alc662_lenovo_101e_unsol_event,
16478 .init_hook = alc662_lenovo_101e_all_automute,
16479 },
291702f0 16480 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 16481 .mixers = { alc662_eeepc_p701_mixer },
291702f0
KY
16482 .init_verbs = { alc662_init_verbs,
16483 alc662_eeepc_sue_init_verbs },
16484 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16485 .dac_nids = alc662_dac_nids,
291702f0
KY
16486 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16487 .channel_mode = alc662_3ST_2ch_modes,
16488 .input_mux = &alc662_eeepc_capture_source,
16489 .unsol_event = alc662_eeepc_unsol_event,
16490 .init_hook = alc662_eeepc_inithook,
16491 },
8c427226 16492 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 16493 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
16494 alc662_chmode_mixer },
16495 .init_verbs = { alc662_init_verbs,
16496 alc662_eeepc_ep20_sue_init_verbs },
16497 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16498 .dac_nids = alc662_dac_nids,
8c427226
KY
16499 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16500 .channel_mode = alc662_3ST_6ch_modes,
16501 .input_mux = &alc662_lenovo_101e_capture_source,
42171c17 16502 .unsol_event = alc662_eeepc_unsol_event,
8c427226
KY
16503 .init_hook = alc662_eeepc_ep20_inithook,
16504 },
f1d4e28b 16505 [ALC662_ECS] = {
f9e336f6 16506 .mixers = { alc662_ecs_mixer },
f1d4e28b
KY
16507 .init_verbs = { alc662_init_verbs,
16508 alc662_ecs_init_verbs },
16509 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16510 .dac_nids = alc662_dac_nids,
16511 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16512 .channel_mode = alc662_3ST_2ch_modes,
16513 .input_mux = &alc662_eeepc_capture_source,
16514 .unsol_event = alc662_eeepc_unsol_event,
16515 .init_hook = alc662_eeepc_inithook,
16516 },
6dda9f4a 16517 [ALC663_ASUS_M51VA] = {
f9e336f6 16518 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
16519 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16520 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16521 .dac_nids = alc662_dac_nids,
16522 .dig_out_nid = ALC662_DIGOUT_NID,
16523 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16524 .channel_mode = alc662_3ST_2ch_modes,
16525 .input_mux = &alc663_m51va_capture_source,
16526 .unsol_event = alc663_m51va_unsol_event,
16527 .init_hook = alc663_m51va_inithook,
16528 },
16529 [ALC663_ASUS_G71V] = {
f9e336f6 16530 .mixers = { alc663_g71v_mixer },
6dda9f4a
KY
16531 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16532 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16533 .dac_nids = alc662_dac_nids,
16534 .dig_out_nid = ALC662_DIGOUT_NID,
16535 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16536 .channel_mode = alc662_3ST_2ch_modes,
16537 .input_mux = &alc662_eeepc_capture_source,
16538 .unsol_event = alc663_g71v_unsol_event,
16539 .init_hook = alc663_g71v_inithook,
16540 },
16541 [ALC663_ASUS_H13] = {
f9e336f6 16542 .mixers = { alc663_m51va_mixer },
6dda9f4a
KY
16543 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16544 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16545 .dac_nids = alc662_dac_nids,
16546 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16547 .channel_mode = alc662_3ST_2ch_modes,
16548 .input_mux = &alc663_m51va_capture_source,
16549 .unsol_event = alc663_m51va_unsol_event,
16550 .init_hook = alc663_m51va_inithook,
16551 },
16552 [ALC663_ASUS_G50V] = {
f9e336f6 16553 .mixers = { alc663_g50v_mixer },
6dda9f4a
KY
16554 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16555 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16556 .dac_nids = alc662_dac_nids,
16557 .dig_out_nid = ALC662_DIGOUT_NID,
16558 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16559 .channel_mode = alc662_3ST_6ch_modes,
16560 .input_mux = &alc663_capture_source,
16561 .unsol_event = alc663_g50v_unsol_event,
16562 .init_hook = alc663_g50v_inithook,
16563 },
f1d4e28b 16564 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
16565 .mixers = { alc663_m51va_mixer },
16566 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16567 .init_verbs = { alc662_init_verbs,
16568 alc663_21jd_amic_init_verbs },
16569 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16570 .hp_nid = 0x03,
16571 .dac_nids = alc662_dac_nids,
16572 .dig_out_nid = ALC662_DIGOUT_NID,
16573 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16574 .channel_mode = alc662_3ST_2ch_modes,
16575 .input_mux = &alc662_eeepc_capture_source,
16576 .unsol_event = alc663_mode1_unsol_event,
16577 .init_hook = alc663_mode1_inithook,
16578 },
16579 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
16580 .mixers = { alc662_1bjd_mixer },
16581 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16582 .init_verbs = { alc662_init_verbs,
16583 alc662_1bjd_amic_init_verbs },
16584 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16585 .dac_nids = alc662_dac_nids,
16586 .dig_out_nid = ALC662_DIGOUT_NID,
16587 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16588 .channel_mode = alc662_3ST_2ch_modes,
16589 .input_mux = &alc662_eeepc_capture_source,
16590 .unsol_event = alc662_mode2_unsol_event,
16591 .init_hook = alc662_mode2_inithook,
16592 },
16593 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
16594 .mixers = { alc663_two_hp_m1_mixer },
16595 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16596 .init_verbs = { alc662_init_verbs,
16597 alc663_two_hp_amic_m1_init_verbs },
16598 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16599 .hp_nid = 0x03,
16600 .dac_nids = alc662_dac_nids,
16601 .dig_out_nid = ALC662_DIGOUT_NID,
16602 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16603 .channel_mode = alc662_3ST_2ch_modes,
16604 .input_mux = &alc662_eeepc_capture_source,
16605 .unsol_event = alc663_mode3_unsol_event,
16606 .init_hook = alc663_mode3_inithook,
16607 },
16608 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
16609 .mixers = { alc663_asus_21jd_clfe_mixer },
16610 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16611 .init_verbs = { alc662_init_verbs,
16612 alc663_21jd_amic_init_verbs},
16613 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16614 .hp_nid = 0x03,
16615 .dac_nids = alc662_dac_nids,
16616 .dig_out_nid = ALC662_DIGOUT_NID,
16617 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16618 .channel_mode = alc662_3ST_2ch_modes,
16619 .input_mux = &alc662_eeepc_capture_source,
16620 .unsol_event = alc663_mode4_unsol_event,
16621 .init_hook = alc663_mode4_inithook,
16622 },
16623 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
16624 .mixers = { alc663_asus_15jd_clfe_mixer },
16625 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16626 .init_verbs = { alc662_init_verbs,
16627 alc663_15jd_amic_init_verbs },
16628 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16629 .hp_nid = 0x03,
16630 .dac_nids = alc662_dac_nids,
16631 .dig_out_nid = ALC662_DIGOUT_NID,
16632 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16633 .channel_mode = alc662_3ST_2ch_modes,
16634 .input_mux = &alc662_eeepc_capture_source,
16635 .unsol_event = alc663_mode5_unsol_event,
16636 .init_hook = alc663_mode5_inithook,
16637 },
16638 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
16639 .mixers = { alc663_two_hp_m2_mixer },
16640 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b
KY
16641 .init_verbs = { alc662_init_verbs,
16642 alc663_two_hp_amic_m2_init_verbs },
16643 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16644 .hp_nid = 0x03,
16645 .dac_nids = alc662_dac_nids,
16646 .dig_out_nid = ALC662_DIGOUT_NID,
16647 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16648 .channel_mode = alc662_3ST_2ch_modes,
16649 .input_mux = &alc662_eeepc_capture_source,
16650 .unsol_event = alc663_mode6_unsol_event,
16651 .init_hook = alc663_mode6_inithook,
16652 },
622e84cd
KY
16653 [ALC272_DELL] = {
16654 .mixers = { alc663_m51va_mixer },
16655 .cap_mixer = alc272_auto_capture_mixer,
16656 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
16657 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16658 .dac_nids = alc662_dac_nids,
16659 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16660 .adc_nids = alc272_adc_nids,
16661 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
16662 .capsrc_nids = alc272_capsrc_nids,
16663 .channel_mode = alc662_3ST_2ch_modes,
16664 .input_mux = &alc663_m51va_capture_source,
16665 .unsol_event = alc663_m51va_unsol_event,
16666 .init_hook = alc663_m51va_inithook,
16667 },
16668 [ALC272_DELL_ZM1] = {
16669 .mixers = { alc663_m51va_mixer },
16670 .cap_mixer = alc662_auto_capture_mixer,
16671 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
16672 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16673 .dac_nids = alc662_dac_nids,
16674 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16675 .adc_nids = alc662_adc_nids,
16676 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
16677 .capsrc_nids = alc662_capsrc_nids,
16678 .channel_mode = alc662_3ST_2ch_modes,
16679 .input_mux = &alc663_m51va_capture_source,
16680 .unsol_event = alc663_m51va_unsol_event,
16681 .init_hook = alc663_m51va_inithook,
16682 },
9541ba1d
CP
16683 [ALC272_SAMSUNG_NC10] = {
16684 .mixers = { alc272_nc10_mixer },
16685 .init_verbs = { alc662_init_verbs,
16686 alc663_21jd_amic_init_verbs },
16687 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16688 .dac_nids = alc272_dac_nids,
16689 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16690 .channel_mode = alc662_3ST_2ch_modes,
16691 .input_mux = &alc272_nc10_capture_source,
16692 .unsol_event = alc663_mode4_unsol_event,
16693 .init_hook = alc663_mode4_inithook,
16694 },
bc9f98a9
KY
16695};
16696
16697
16698/*
16699 * BIOS auto configuration
16700 */
16701
16702/* add playback controls from the parsed DAC table */
16703static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16704 const struct auto_pin_cfg *cfg)
16705{
16706 char name[32];
16707 static const char *chname[4] = {
16708 "Front", "Surround", NULL /*CLFE*/, "Side"
16709 };
16710 hda_nid_t nid;
16711 int i, err;
16712
16713 for (i = 0; i < cfg->line_outs; i++) {
16714 if (!spec->multiout.dac_nids[i])
16715 continue;
b60dd394 16716 nid = alc880_idx_to_dac(i);
bc9f98a9
KY
16717 if (i == 2) {
16718 /* Center/LFE */
16719 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16720 "Center Playback Volume",
f12ab1e0
TI
16721 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16722 HDA_OUTPUT));
bc9f98a9
KY
16723 if (err < 0)
16724 return err;
16725 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16726 "LFE Playback Volume",
f12ab1e0
TI
16727 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16728 HDA_OUTPUT));
bc9f98a9
KY
16729 if (err < 0)
16730 return err;
b69ce01a 16731 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
bc9f98a9 16732 "Center Playback Switch",
b69ce01a 16733 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
f12ab1e0 16734 HDA_INPUT));
bc9f98a9
KY
16735 if (err < 0)
16736 return err;
b69ce01a 16737 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
bc9f98a9 16738 "LFE Playback Switch",
b69ce01a 16739 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
f12ab1e0 16740 HDA_INPUT));
bc9f98a9
KY
16741 if (err < 0)
16742 return err;
16743 } else {
16744 sprintf(name, "%s Playback Volume", chname[i]);
16745 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
f12ab1e0
TI
16746 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16747 HDA_OUTPUT));
bc9f98a9
KY
16748 if (err < 0)
16749 return err;
16750 sprintf(name, "%s Playback Switch", chname[i]);
b69ce01a
HRK
16751 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16752 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16753 3, 0, HDA_INPUT));
bc9f98a9
KY
16754 if (err < 0)
16755 return err;
16756 }
16757 }
16758 return 0;
16759}
16760
16761/* add playback controls for speaker and HP outputs */
16762static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16763 const char *pfx)
16764{
16765 hda_nid_t nid;
16766 int err;
16767 char name[32];
16768
16769 if (!pin)
16770 return 0;
16771
24fb9173
TI
16772 if (pin == 0x17) {
16773 /* ALC663 has a mono output pin on 0x17 */
16774 sprintf(name, "%s Playback Switch", pfx);
16775 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16776 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16777 return err;
16778 }
16779
bc9f98a9
KY
16780 if (alc880_is_fixed_pin(pin)) {
16781 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
939778ae 16782 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
bc9f98a9
KY
16783 /* specify the DAC as the extra output */
16784 if (!spec->multiout.hp_nid)
16785 spec->multiout.hp_nid = nid;
16786 else
16787 spec->multiout.extra_out_nid[0] = nid;
16788 /* control HP volume/switch on the output mixer amp */
16789 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16790 sprintf(name, "%s Playback Volume", pfx);
16791 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16792 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16793 if (err < 0)
16794 return err;
16795 sprintf(name, "%s Playback Switch", pfx);
16796 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16797 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16798 if (err < 0)
16799 return err;
16800 } else if (alc880_is_multi_pin(pin)) {
16801 /* set manual connection */
16802 /* we have only a switch on HP-out PIN */
16803 sprintf(name, "%s Playback Switch", pfx);
16804 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16805 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16806 if (err < 0)
16807 return err;
16808 }
16809 return 0;
16810}
16811
2d864c49
TI
16812/* return the index of the src widget from the connection list of the nid.
16813 * return -1 if not found
16814 */
16815static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid,
16816 hda_nid_t src)
16817{
16818 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
16819 int i, conns;
16820
16821 conns = snd_hda_get_connections(codec, nid, conn_list,
16822 ARRAY_SIZE(conn_list));
16823 if (conns < 0)
16824 return -1;
16825 for (i = 0; i < conns; i++)
16826 if (conn_list[i] == src)
16827 return i;
16828 return -1;
16829}
16830
16831static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
16832{
1327a32b 16833 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
2d864c49
TI
16834 return (pincap & AC_PINCAP_IN) != 0;
16835}
16836
bc9f98a9 16837/* create playback/capture controls for input pins */
2d864c49 16838static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec,
bc9f98a9
KY
16839 const struct auto_pin_cfg *cfg)
16840{
2d864c49 16841 struct alc_spec *spec = codec->spec;
61b9b9b1 16842 struct hda_input_mux *imux = &spec->private_imux[0];
bc9f98a9
KY
16843 int i, err, idx;
16844
16845 for (i = 0; i < AUTO_PIN_LAST; i++) {
2d864c49
TI
16846 if (alc662_is_input_pin(codec, cfg->input_pins[i])) {
16847 idx = alc662_input_pin_idx(codec, 0x0b,
16848 cfg->input_pins[i]);
16849 if (idx >= 0) {
16850 err = new_analog_input(spec, cfg->input_pins[i],
16851 auto_pin_cfg_labels[i],
16852 idx, 0x0b);
16853 if (err < 0)
16854 return err;
16855 }
16856 idx = alc662_input_pin_idx(codec, 0x22,
16857 cfg->input_pins[i]);
16858 if (idx >= 0) {
16859 imux->items[imux->num_items].label =
16860 auto_pin_cfg_labels[i];
16861 imux->items[imux->num_items].index = idx;
16862 imux->num_items++;
16863 }
bc9f98a9
KY
16864 }
16865 }
16866 return 0;
16867}
16868
16869static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16870 hda_nid_t nid, int pin_type,
16871 int dac_idx)
16872{
f6c7e546 16873 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9
KY
16874 /* need the manual connection? */
16875 if (alc880_is_multi_pin(nid)) {
16876 struct alc_spec *spec = codec->spec;
16877 int idx = alc880_multi_pin_idx(nid);
16878 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16879 AC_VERB_SET_CONNECT_SEL,
16880 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16881 }
16882}
16883
16884static void alc662_auto_init_multi_out(struct hda_codec *codec)
16885{
16886 struct alc_spec *spec = codec->spec;
16887 int i;
16888
16889 for (i = 0; i <= HDA_SIDE; i++) {
16890 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16891 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9 16892 if (nid)
baba8ee9 16893 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
bc9f98a9
KY
16894 i);
16895 }
16896}
16897
16898static void alc662_auto_init_hp_out(struct hda_codec *codec)
16899{
16900 struct alc_spec *spec = codec->spec;
16901 hda_nid_t pin;
16902
16903 pin = spec->autocfg.hp_pins[0];
16904 if (pin) /* connect to front */
16905 /* use dac 0 */
16906 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
16907 pin = spec->autocfg.speaker_pins[0];
16908 if (pin)
16909 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
bc9f98a9
KY
16910}
16911
bc9f98a9
KY
16912#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16913
16914static void alc662_auto_init_analog_input(struct hda_codec *codec)
16915{
16916 struct alc_spec *spec = codec->spec;
16917 int i;
16918
16919 for (i = 0; i < AUTO_PIN_LAST; i++) {
16920 hda_nid_t nid = spec->autocfg.input_pins[i];
2d864c49 16921 if (alc662_is_input_pin(codec, nid)) {
23f0c048 16922 alc_set_input_pin(codec, nid, i);
52ca15b7 16923 if (nid != ALC662_PIN_CD_NID &&
e82c025b 16924 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
16925 snd_hda_codec_write(codec, nid, 0,
16926 AC_VERB_SET_AMP_GAIN_MUTE,
16927 AMP_OUT_MUTE);
16928 }
16929 }
16930}
16931
f511b01c
TI
16932#define alc662_auto_init_input_src alc882_auto_init_input_src
16933
bc9f98a9
KY
16934static int alc662_parse_auto_config(struct hda_codec *codec)
16935{
16936 struct alc_spec *spec = codec->spec;
16937 int err;
16938 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16939
16940 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16941 alc662_ignore);
16942 if (err < 0)
16943 return err;
16944 if (!spec->autocfg.line_outs)
16945 return 0; /* can't find valid BIOS pin config */
16946
f12ab1e0
TI
16947 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16948 if (err < 0)
16949 return err;
16950 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16951 if (err < 0)
16952 return err;
16953 err = alc662_auto_create_extra_out(spec,
16954 spec->autocfg.speaker_pins[0],
16955 "Speaker");
16956 if (err < 0)
16957 return err;
16958 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16959 "Headphone");
16960 if (err < 0)
16961 return err;
2d864c49 16962 err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg);
f12ab1e0 16963 if (err < 0)
bc9f98a9
KY
16964 return err;
16965
16966 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16967
0852d7a6 16968 if (spec->autocfg.dig_outs)
bc9f98a9
KY
16969 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16970
603c4019 16971 if (spec->kctls.list)
d88897ea 16972 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
16973
16974 spec->num_mux_defs = 1;
61b9b9b1 16975 spec->input_mux = &spec->private_imux[0];
ea1fb29a 16976
d88897ea 16977 add_verb(spec, alc662_auto_init_verbs);
24fb9173 16978 if (codec->vendor_id == 0x10ec0663)
d88897ea 16979 add_verb(spec, alc663_auto_init_verbs);
ee979a14
TI
16980
16981 err = alc_auto_add_mic_boost(codec);
16982 if (err < 0)
16983 return err;
16984
4a79ba34
TI
16985 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
16986
8c87286f 16987 return 1;
bc9f98a9
KY
16988}
16989
16990/* additional initialization for auto-configuration model */
16991static void alc662_auto_init(struct hda_codec *codec)
16992{
f6c7e546 16993 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
16994 alc662_auto_init_multi_out(codec);
16995 alc662_auto_init_hp_out(codec);
16996 alc662_auto_init_analog_input(codec);
f511b01c 16997 alc662_auto_init_input_src(codec);
f6c7e546 16998 if (spec->unsol_event)
7fb0d78f 16999 alc_inithook(codec);
bc9f98a9
KY
17000}
17001
17002static int patch_alc662(struct hda_codec *codec)
17003{
17004 struct alc_spec *spec;
17005 int err, board_config;
17006
17007 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17008 if (!spec)
17009 return -ENOMEM;
17010
17011 codec->spec = spec;
17012
2c3bf9ab
TI
17013 alc_fix_pll_init(codec, 0x20, 0x04, 15);
17014
bc9f98a9
KY
17015 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17016 alc662_models,
17017 alc662_cfg_tbl);
17018 if (board_config < 0) {
6c627f39
TI
17019 printk(KERN_INFO "hda_codec: Unknown model for %s, "
17020 "trying auto-probe from BIOS...\n", codec->chip_name);
bc9f98a9
KY
17021 board_config = ALC662_AUTO;
17022 }
17023
17024 if (board_config == ALC662_AUTO) {
17025 /* automatic parse from the BIOS config */
17026 err = alc662_parse_auto_config(codec);
17027 if (err < 0) {
17028 alc_free(codec);
17029 return err;
8c87286f 17030 } else if (!err) {
bc9f98a9
KY
17031 printk(KERN_INFO
17032 "hda_codec: Cannot set up configuration "
17033 "from BIOS. Using base mode...\n");
17034 board_config = ALC662_3ST_2ch_DIG;
17035 }
17036 }
17037
680cd536
KK
17038 err = snd_hda_attach_beep_device(codec, 0x1);
17039 if (err < 0) {
17040 alc_free(codec);
17041 return err;
17042 }
17043
bc9f98a9
KY
17044 if (board_config != ALC662_AUTO)
17045 setup_preset(spec, &alc662_presets[board_config]);
17046
bc9f98a9
KY
17047 spec->stream_analog_playback = &alc662_pcm_analog_playback;
17048 spec->stream_analog_capture = &alc662_pcm_analog_capture;
17049
bc9f98a9
KY
17050 spec->stream_digital_playback = &alc662_pcm_digital_playback;
17051 spec->stream_digital_capture = &alc662_pcm_digital_capture;
17052
e1406348
TI
17053 spec->adc_nids = alc662_adc_nids;
17054 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
17055 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 17056
f9e336f6
TI
17057 if (!spec->cap_mixer)
17058 set_capture_mixer(spec);
b9591448
TI
17059 if (codec->vendor_id == 0x10ec0662)
17060 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17061 else
17062 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f9e336f6 17063
2134ea4f
TI
17064 spec->vmaster_nid = 0x02;
17065
bc9f98a9
KY
17066 codec->patch_ops = alc_patch_ops;
17067 if (board_config == ALC662_AUTO)
17068 spec->init_hook = alc662_auto_init;
cb53c626
TI
17069#ifdef CONFIG_SND_HDA_POWER_SAVE
17070 if (!spec->loopback.amplist)
17071 spec->loopback.amplist = alc662_loopbacks;
17072#endif
daead538 17073 codec->proc_widget_hook = print_realtek_coef;
bc9f98a9
KY
17074
17075 return 0;
17076}
17077
1da177e4
LT
17078/*
17079 * patch entries
17080 */
1289e9e8 17081static struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 17082 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 17083 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 17084 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 17085 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 17086 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
01afd41f 17087 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
f32610ed 17088 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 17089 .patch = patch_alc861 },
f32610ed
JS
17090 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
17091 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17092 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 17093 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 17094 .patch = patch_alc882 },
bc9f98a9
KY
17095 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17096 .patch = patch_alc662 },
6dda9f4a 17097 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
f32610ed 17098 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 17099 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 17100 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 17101 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 17102 .patch = patch_alc882 },
cb308f97 17103 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 17104 .patch = patch_alc882 },
df694daa 17105 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
4953550a 17106 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
4442608d 17107 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a
TI
17108 .patch = patch_alc882 },
17109 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
17110 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
1da177e4
LT
17111 {} /* terminator */
17112};
1289e9e8
TI
17113
17114MODULE_ALIAS("snd-hda-codec-id:10ec*");
17115
17116MODULE_LICENSE("GPL");
17117MODULE_DESCRIPTION("Realtek HD-audio codec");
17118
17119static struct hda_codec_preset_list realtek_list = {
17120 .preset = snd_hda_preset_realtek,
17121 .owner = THIS_MODULE,
17122};
17123
17124static int __init patch_realtek_init(void)
17125{
17126 return snd_hda_add_codec_preset(&realtek_list);
17127}
17128
17129static void __exit patch_realtek_exit(void)
17130{
17131 snd_hda_delete_codec_preset(&realtek_list);
17132}
17133
17134module_init(patch_realtek_init)
17135module_exit(patch_realtek_exit)