]> git.ipfire.org Git - thirdparty/kernel/stable.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Use macros to check array overflow
[thirdparty/kernel/stable.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"
3c9a3203 33#include "hda_patch.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,
7cf51e48
JW
81#ifdef CONFIG_SND_DEBUG
82 ALC260_TEST,
83#endif
df694daa 84 ALC260_AUTO,
16ded525 85 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
86};
87
df694daa
KY
88/* ALC262 models */
89enum {
90 ALC262_BASIC,
ccc656ce
KY
91 ALC262_HIPPO,
92 ALC262_HIPPO_1,
834be88d 93 ALC262_FUJITSU,
9c7f852e 94 ALC262_HP_BPC,
cd7509a4
KY
95 ALC262_HP_BPC_D7000_WL,
96 ALC262_HP_BPC_D7000_WF,
66d2a9d6 97 ALC262_HP_TC_T5735,
8c427226 98 ALC262_HP_RP5700,
304dcaac 99 ALC262_BENQ_ED8,
272a527c 100 ALC262_SONY_ASSAMD,
83c34218 101 ALC262_BENQ_T31,
f651b50b 102 ALC262_ULTRA,
0e31daf7 103 ALC262_LENOVO_3000,
e8f9ae2a 104 ALC262_NEC,
4e555fe5 105 ALC262_TOSHIBA_S06,
9f99a638 106 ALC262_TOSHIBA_RX1,
df694daa
KY
107 ALC262_AUTO,
108 ALC262_MODEL_LAST /* last tag */
109};
110
a361d84b
KY
111/* ALC268 models */
112enum {
eb5a6621 113 ALC267_QUANTA_IL1,
a361d84b 114 ALC268_3ST,
d1a991a6 115 ALC268_TOSHIBA,
d273809e 116 ALC268_ACER,
8ef355da 117 ALC268_ACER_ASPIRE_ONE,
3866f0b0 118 ALC268_DELL,
f12462c5 119 ALC268_ZEPTO,
86c53bd2
JW
120#ifdef CONFIG_SND_DEBUG
121 ALC268_TEST,
122#endif
a361d84b
KY
123 ALC268_AUTO,
124 ALC268_MODEL_LAST /* last tag */
125};
126
f6a92248
KY
127/* ALC269 models */
128enum {
129 ALC269_BASIC,
60db6b53 130 ALC269_QUANTA_FL1,
f53281e6
KY
131 ALC269_ASUS_EEEPC_P703,
132 ALC269_ASUS_EEEPC_P901,
f6a92248
KY
133 ALC269_AUTO,
134 ALC269_MODEL_LAST /* last tag */
135};
136
df694daa
KY
137/* ALC861 models */
138enum {
139 ALC861_3ST,
9c7f852e 140 ALC660_3ST,
df694daa
KY
141 ALC861_3ST_DIG,
142 ALC861_6ST_DIG,
22309c3e 143 ALC861_UNIWILL_M31,
a53d1aec 144 ALC861_TOSHIBA,
7cdbff94 145 ALC861_ASUS,
56bb0cab 146 ALC861_ASUS_LAPTOP,
df694daa
KY
147 ALC861_AUTO,
148 ALC861_MODEL_LAST,
149};
150
f32610ed
JS
151/* ALC861-VD models */
152enum {
153 ALC660VD_3ST,
6963f84c 154 ALC660VD_3ST_DIG,
f32610ed
JS
155 ALC861VD_3ST,
156 ALC861VD_3ST_DIG,
157 ALC861VD_6ST_DIG,
bdd148a3 158 ALC861VD_LENOVO,
272a527c 159 ALC861VD_DALLAS,
d1a991a6 160 ALC861VD_HP,
f32610ed
JS
161 ALC861VD_AUTO,
162 ALC861VD_MODEL_LAST,
163};
164
bc9f98a9
KY
165/* ALC662 models */
166enum {
167 ALC662_3ST_2ch_DIG,
168 ALC662_3ST_6ch_DIG,
169 ALC662_3ST_6ch,
170 ALC662_5ST_DIG,
171 ALC662_LENOVO_101E,
291702f0 172 ALC662_ASUS_EEEPC_P701,
8c427226 173 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
174 ALC663_ASUS_M51VA,
175 ALC663_ASUS_G71V,
176 ALC663_ASUS_H13,
177 ALC663_ASUS_G50V,
f1d4e28b
KY
178 ALC662_ECS,
179 ALC663_ASUS_MODE1,
180 ALC662_ASUS_MODE2,
181 ALC663_ASUS_MODE3,
182 ALC663_ASUS_MODE4,
183 ALC663_ASUS_MODE5,
184 ALC663_ASUS_MODE6,
bc9f98a9
KY
185 ALC662_AUTO,
186 ALC662_MODEL_LAST,
187};
188
df694daa
KY
189/* ALC882 models */
190enum {
191 ALC882_3ST_DIG,
192 ALC882_6ST_DIG,
4b146cb0 193 ALC882_ARIMA,
bdd148a3 194 ALC882_W2JC,
272a527c
KY
195 ALC882_TARGA,
196 ALC882_ASUS_A7J,
914759b7 197 ALC882_ASUS_A7M,
9102cd1c 198 ALC885_MACPRO,
87350ad0 199 ALC885_MBP3,
c54728d8 200 ALC885_IMAC24,
272a527c 201 ALC882_AUTO,
df694daa
KY
202 ALC882_MODEL_LAST,
203};
204
9c7f852e
TI
205/* ALC883 models */
206enum {
207 ALC883_3ST_2ch_DIG,
208 ALC883_3ST_6ch_DIG,
209 ALC883_3ST_6ch,
210 ALC883_6ST_DIG,
ccc656ce
KY
211 ALC883_TARGA_DIG,
212 ALC883_TARGA_2ch_DIG,
bab282b9 213 ALC883_ACER,
2880a867 214 ALC883_ACER_ASPIRE,
c07584c8 215 ALC883_MEDION,
ea1fb29a 216 ALC883_MEDION_MD2,
b373bdeb 217 ALC883_LAPTOP_EAPD,
bc9f98a9 218 ALC883_LENOVO_101E_2ch,
272a527c 219 ALC883_LENOVO_NB0763,
189609ae 220 ALC888_LENOVO_MS7195_DIG,
e2757d5e 221 ALC888_LENOVO_SKY,
ea1fb29a 222 ALC883_HAIER_W66,
4723c022 223 ALC888_3ST_HP,
5795b9e6 224 ALC888_6ST_DELL,
a8848bd6 225 ALC883_MITAC,
0c4cc443 226 ALC883_CLEVO_M720,
fb97dc67 227 ALC883_FUJITSU_PI2515,
17bba1b7 228 ALC883_3ST_6ch_INTEL,
e2757d5e
KY
229 ALC888_ASUS_M90V,
230 ALC888_ASUS_EEE1601,
9c7f852e
TI
231 ALC883_AUTO,
232 ALC883_MODEL_LAST,
233};
234
df694daa
KY
235/* for GPIO Poll */
236#define GPIO_MASK 0x03
237
1da177e4
LT
238struct alc_spec {
239 /* codec parameterization */
df694daa 240 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4
LT
241 unsigned int num_mixers;
242
df694daa 243 const struct hda_verb *init_verbs[5]; /* initialization verbs
9c7f852e
TI
244 * don't forget NULL
245 * termination!
e9edcee0
TI
246 */
247 unsigned int num_init_verbs;
1da177e4 248
16ded525 249 char *stream_name_analog; /* analog PCM stream */
1da177e4
LT
250 struct hda_pcm_stream *stream_analog_playback;
251 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
252 struct hda_pcm_stream *stream_analog_alt_playback;
253 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 254
f12ab1e0 255 char *stream_name_digital; /* digital PCM stream */
1da177e4
LT
256 struct hda_pcm_stream *stream_digital_playback;
257 struct hda_pcm_stream *stream_digital_capture;
258
259 /* playback */
16ded525
TI
260 struct hda_multi_out multiout; /* playback set-up
261 * max_channels, dacs must be set
262 * dig_out_nid and hp_nid are optional
263 */
6330079f 264 hda_nid_t alt_dac_nid;
1da177e4
LT
265
266 /* capture */
267 unsigned int num_adc_nids;
268 hda_nid_t *adc_nids;
e1406348 269 hda_nid_t *capsrc_nids;
16ded525 270 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4
LT
271
272 /* capture source */
a1e8d2da 273 unsigned int num_mux_defs;
1da177e4
LT
274 const struct hda_input_mux *input_mux;
275 unsigned int cur_mux[3];
276
277 /* channel model */
d2a6d7dc 278 const struct hda_channel_mode *channel_mode;
1da177e4 279 int num_channel_mode;
4e195a7b 280 int need_dac_fix;
1da177e4
LT
281
282 /* PCM information */
4c5186ed 283 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 284
e9edcee0
TI
285 /* dynamic controls, init_verbs and input_mux */
286 struct auto_pin_cfg autocfg;
603c4019 287 struct snd_array kctls;
e9edcee0 288 struct hda_input_mux private_imux;
41923e44 289 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
834be88d 290
ae6b813a
TI
291 /* hooks */
292 void (*init_hook)(struct hda_codec *codec);
293 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
294
834be88d
TI
295 /* for pin sensing */
296 unsigned int sense_updated: 1;
297 unsigned int jack_present: 1;
bec15c3a 298 unsigned int master_sw: 1;
cb53c626 299
2134ea4f
TI
300 /* for virtual master */
301 hda_nid_t vmaster_nid;
cb53c626
TI
302#ifdef CONFIG_SND_HDA_POWER_SAVE
303 struct hda_loopback_check loopback;
304#endif
2c3bf9ab
TI
305
306 /* for PLL fix */
307 hda_nid_t pll_nid;
308 unsigned int pll_coef_idx, pll_coef_bit;
e044c39a
TI
309
310#ifdef SND_HDA_NEEDS_RESUME
311#define ALC_MAX_PINS 16
312 unsigned int num_pins;
313 hda_nid_t pin_nids[ALC_MAX_PINS];
314 unsigned int pin_cfgs[ALC_MAX_PINS];
315#endif
df694daa
KY
316};
317
318/*
319 * configuration template - to be copied to the spec instance
320 */
321struct alc_config_preset {
9c7f852e
TI
322 struct snd_kcontrol_new *mixers[5]; /* should be identical size
323 * with spec
324 */
df694daa
KY
325 const struct hda_verb *init_verbs[5];
326 unsigned int num_dacs;
327 hda_nid_t *dac_nids;
328 hda_nid_t dig_out_nid; /* optional */
329 hda_nid_t hp_nid; /* optional */
330 unsigned int num_adc_nids;
331 hda_nid_t *adc_nids;
e1406348 332 hda_nid_t *capsrc_nids;
df694daa
KY
333 hda_nid_t dig_in_nid;
334 unsigned int num_channel_mode;
335 const struct hda_channel_mode *channel_mode;
4e195a7b 336 int need_dac_fix;
a1e8d2da 337 unsigned int num_mux_defs;
df694daa 338 const struct hda_input_mux *input_mux;
ae6b813a
TI
339 void (*unsol_event)(struct hda_codec *, unsigned int);
340 void (*init_hook)(struct hda_codec *);
cb53c626
TI
341#ifdef CONFIG_SND_HDA_POWER_SAVE
342 struct hda_amp_list *loopbacks;
343#endif
1da177e4
LT
344};
345
1da177e4
LT
346
347/*
348 * input MUX handling
349 */
9c7f852e
TI
350static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
351 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
352{
353 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
354 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
355 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
356 if (mux_idx >= spec->num_mux_defs)
357 mux_idx = 0;
358 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
359}
360
9c7f852e
TI
361static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
362 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
363{
364 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
365 struct alc_spec *spec = codec->spec;
366 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
367
368 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
369 return 0;
370}
371
9c7f852e
TI
372static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
373 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
374{
375 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
376 struct alc_spec *spec = codec->spec;
377 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
a1e8d2da 378 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
e1406348
TI
379 hda_nid_t nid = spec->capsrc_nids ?
380 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
a1e8d2da 381 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
e1406348 382 nid, &spec->cur_mux[adc_idx]);
1da177e4
LT
383}
384
e9edcee0 385
1da177e4
LT
386/*
387 * channel mode setting
388 */
9c7f852e
TI
389static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
390 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
391{
392 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
393 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
394 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
395 spec->num_channel_mode);
1da177e4
LT
396}
397
9c7f852e
TI
398static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
399 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
400{
401 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
402 struct alc_spec *spec = codec->spec;
d2a6d7dc 403 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e
TI
404 spec->num_channel_mode,
405 spec->multiout.max_channels);
1da177e4
LT
406}
407
9c7f852e
TI
408static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
409 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
410{
411 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
412 struct alc_spec *spec = codec->spec;
4e195a7b
TI
413 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
414 spec->num_channel_mode,
415 &spec->multiout.max_channels);
bd2033f2 416 if (err >= 0 && spec->need_dac_fix)
4e195a7b
TI
417 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
418 return err;
1da177e4
LT
419}
420
a9430dd8 421/*
4c5186ed 422 * Control the mode of pin widget settings via the mixer. "pc" is used
ea1fb29a 423 * instead of "%" to avoid consequences of accidently treating the % as
4c5186ed
JW
424 * being part of a format specifier. Maximum allowed length of a value is
425 * 63 characters plus NULL terminator.
7cf51e48
JW
426 *
427 * Note: some retasking pin complexes seem to ignore requests for input
428 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
429 * are requested. Therefore order this list so that this behaviour will not
430 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
431 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
432 * March 2006.
4c5186ed
JW
433 */
434static char *alc_pin_mode_names[] = {
7cf51e48
JW
435 "Mic 50pc bias", "Mic 80pc bias",
436 "Line in", "Line out", "Headphone out",
4c5186ed
JW
437};
438static unsigned char alc_pin_mode_values[] = {
7cf51e48 439 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
440};
441/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
442 * in the pin being assumed to be exclusively an input or an output pin. In
443 * addition, "input" pins may or may not process the mic bias option
444 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
445 * accept requests for bias as of chip versions up to March 2006) and/or
446 * wiring in the computer.
a9430dd8 447 */
a1e8d2da
JW
448#define ALC_PIN_DIR_IN 0x00
449#define ALC_PIN_DIR_OUT 0x01
450#define ALC_PIN_DIR_INOUT 0x02
451#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
452#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 453
ea1fb29a 454/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
455 * For each direction the minimum and maximum values are given.
456 */
a1e8d2da 457static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
458 { 0, 2 }, /* ALC_PIN_DIR_IN */
459 { 3, 4 }, /* ALC_PIN_DIR_OUT */
460 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
461 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
462 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
463};
464#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
465#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
466#define alc_pin_mode_n_items(_dir) \
467 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
468
9c7f852e
TI
469static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
470 struct snd_ctl_elem_info *uinfo)
a9430dd8 471{
4c5186ed
JW
472 unsigned int item_num = uinfo->value.enumerated.item;
473 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
474
475 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 476 uinfo->count = 1;
4c5186ed
JW
477 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
478
479 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
480 item_num = alc_pin_mode_min(dir);
481 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
482 return 0;
483}
484
9c7f852e
TI
485static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
486 struct snd_ctl_elem_value *ucontrol)
a9430dd8 487{
4c5186ed 488 unsigned int i;
a9430dd8
JW
489 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
490 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 491 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 492 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
493 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
494 AC_VERB_GET_PIN_WIDGET_CONTROL,
495 0x00);
a9430dd8 496
4c5186ed
JW
497 /* Find enumerated value for current pinctl setting */
498 i = alc_pin_mode_min(dir);
9c7f852e 499 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
4c5186ed 500 i++;
9c7f852e 501 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
502 return 0;
503}
504
9c7f852e
TI
505static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
506 struct snd_ctl_elem_value *ucontrol)
a9430dd8 507{
4c5186ed 508 signed int change;
a9430dd8
JW
509 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
510 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
511 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
512 long val = *ucontrol->value.integer.value;
9c7f852e
TI
513 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
514 AC_VERB_GET_PIN_WIDGET_CONTROL,
515 0x00);
a9430dd8 516
f12ab1e0 517 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
518 val = alc_pin_mode_min(dir);
519
520 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
521 if (change) {
522 /* Set pin mode to that requested */
82beb8fd
TI
523 snd_hda_codec_write_cache(codec, nid, 0,
524 AC_VERB_SET_PIN_WIDGET_CONTROL,
525 alc_pin_mode_values[val]);
cdcd9268 526
ea1fb29a 527 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
528 * for the requested pin mode. Enum values of 2 or less are
529 * input modes.
530 *
531 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
532 * reduces noise slightly (particularly on input) so we'll
533 * do it. However, having both input and output buffers
534 * enabled simultaneously doesn't seem to be problematic if
535 * this turns out to be necessary in the future.
cdcd9268
JW
536 */
537 if (val <= 2) {
47fd830a
TI
538 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
539 HDA_AMP_MUTE, HDA_AMP_MUTE);
540 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
541 HDA_AMP_MUTE, 0);
cdcd9268 542 } else {
47fd830a
TI
543 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
544 HDA_AMP_MUTE, HDA_AMP_MUTE);
545 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
546 HDA_AMP_MUTE, 0);
cdcd9268
JW
547 }
548 }
a9430dd8
JW
549 return change;
550}
551
4c5186ed 552#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 553 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
4c5186ed
JW
554 .info = alc_pin_mode_info, \
555 .get = alc_pin_mode_get, \
556 .put = alc_pin_mode_put, \
557 .private_value = nid | (dir<<16) }
df694daa 558
5c8f858d
JW
559/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
560 * together using a mask with more than one bit set. This control is
561 * currently used only by the ALC260 test model. At this stage they are not
562 * needed for any "production" models.
563 */
564#ifdef CONFIG_SND_DEBUG
a5ce8890 565#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 566
9c7f852e
TI
567static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
568 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
569{
570 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
571 hda_nid_t nid = kcontrol->private_value & 0xffff;
572 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
573 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
574 unsigned int val = snd_hda_codec_read(codec, nid, 0,
575 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
576
577 *valp = (val & mask) != 0;
578 return 0;
579}
9c7f852e
TI
580static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
581 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
582{
583 signed int change;
584 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
585 hda_nid_t nid = kcontrol->private_value & 0xffff;
586 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
587 long val = *ucontrol->value.integer.value;
9c7f852e
TI
588 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
589 AC_VERB_GET_GPIO_DATA,
590 0x00);
5c8f858d
JW
591
592 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
593 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
594 if (val == 0)
5c8f858d
JW
595 gpio_data &= ~mask;
596 else
597 gpio_data |= mask;
82beb8fd
TI
598 snd_hda_codec_write_cache(codec, nid, 0,
599 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
600
601 return change;
602}
603#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
604 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
605 .info = alc_gpio_data_info, \
606 .get = alc_gpio_data_get, \
607 .put = alc_gpio_data_put, \
608 .private_value = nid | (mask<<16) }
609#endif /* CONFIG_SND_DEBUG */
610
92621f13
JW
611/* A switch control to allow the enabling of the digital IO pins on the
612 * ALC260. This is incredibly simplistic; the intention of this control is
613 * to provide something in the test model allowing digital outputs to be
614 * identified if present. If models are found which can utilise these
615 * outputs a more complete mixer control can be devised for those models if
616 * necessary.
617 */
618#ifdef CONFIG_SND_DEBUG
a5ce8890 619#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 620
9c7f852e
TI
621static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
622 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
623{
624 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
625 hda_nid_t nid = kcontrol->private_value & 0xffff;
626 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
627 long *valp = ucontrol->value.integer.value;
9c7f852e 628 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 629 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
630
631 *valp = (val & mask) != 0;
632 return 0;
633}
9c7f852e
TI
634static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
635 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
636{
637 signed int change;
638 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
639 hda_nid_t nid = kcontrol->private_value & 0xffff;
640 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
641 long val = *ucontrol->value.integer.value;
9c7f852e 642 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 643 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 644 0x00);
92621f13
JW
645
646 /* Set/unset the masked control bit(s) as needed */
9c7f852e 647 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
648 if (val==0)
649 ctrl_data &= ~mask;
650 else
651 ctrl_data |= mask;
82beb8fd
TI
652 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
653 ctrl_data);
92621f13
JW
654
655 return change;
656}
657#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
658 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
659 .info = alc_spdif_ctrl_info, \
660 .get = alc_spdif_ctrl_get, \
661 .put = alc_spdif_ctrl_put, \
662 .private_value = nid | (mask<<16) }
663#endif /* CONFIG_SND_DEBUG */
664
f8225f6d
JW
665/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
666 * Again, this is only used in the ALC26x test models to help identify when
667 * the EAPD line must be asserted for features to work.
668 */
669#ifdef CONFIG_SND_DEBUG
670#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
671
672static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
673 struct snd_ctl_elem_value *ucontrol)
674{
675 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
676 hda_nid_t nid = kcontrol->private_value & 0xffff;
677 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
678 long *valp = ucontrol->value.integer.value;
679 unsigned int val = snd_hda_codec_read(codec, nid, 0,
680 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
681
682 *valp = (val & mask) != 0;
683 return 0;
684}
685
686static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
687 struct snd_ctl_elem_value *ucontrol)
688{
689 int change;
690 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
691 hda_nid_t nid = kcontrol->private_value & 0xffff;
692 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
693 long val = *ucontrol->value.integer.value;
694 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
695 AC_VERB_GET_EAPD_BTLENABLE,
696 0x00);
697
698 /* Set/unset the masked control bit(s) as needed */
699 change = (!val ? 0 : mask) != (ctrl_data & mask);
700 if (!val)
701 ctrl_data &= ~mask;
702 else
703 ctrl_data |= mask;
704 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
705 ctrl_data);
706
707 return change;
708}
709
710#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
711 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
712 .info = alc_eapd_ctrl_info, \
713 .get = alc_eapd_ctrl_get, \
714 .put = alc_eapd_ctrl_put, \
715 .private_value = nid | (mask<<16) }
716#endif /* CONFIG_SND_DEBUG */
717
d88897ea
TI
718/*
719 */
720static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
721{
722 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
723 return;
724 spec->mixers[spec->num_mixers++] = mix;
725}
726
727static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
728{
729 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
730 return;
731 spec->init_verbs[spec->num_init_verbs++] = verb;
732}
733
df694daa
KY
734/*
735 * set up from the preset table
736 */
9c7f852e
TI
737static void setup_preset(struct alc_spec *spec,
738 const struct alc_config_preset *preset)
df694daa
KY
739{
740 int i;
741
742 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 743 add_mixer(spec, preset->mixers[i]);
9c7f852e
TI
744 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
745 i++)
d88897ea 746 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 747
df694daa
KY
748 spec->channel_mode = preset->channel_mode;
749 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 750 spec->need_dac_fix = preset->need_dac_fix;
df694daa
KY
751
752 spec->multiout.max_channels = spec->channel_mode[0].channels;
753
754 spec->multiout.num_dacs = preset->num_dacs;
755 spec->multiout.dac_nids = preset->dac_nids;
756 spec->multiout.dig_out_nid = preset->dig_out_nid;
757 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 758
a1e8d2da 759 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 760 if (!spec->num_mux_defs)
a1e8d2da 761 spec->num_mux_defs = 1;
df694daa
KY
762 spec->input_mux = preset->input_mux;
763
764 spec->num_adc_nids = preset->num_adc_nids;
765 spec->adc_nids = preset->adc_nids;
e1406348 766 spec->capsrc_nids = preset->capsrc_nids;
df694daa 767 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
768
769 spec->unsol_event = preset->unsol_event;
770 spec->init_hook = preset->init_hook;
cb53c626
TI
771#ifdef CONFIG_SND_HDA_POWER_SAVE
772 spec->loopback.amplist = preset->loopbacks;
773#endif
df694daa
KY
774}
775
bc9f98a9
KY
776/* Enable GPIO mask and set output */
777static struct hda_verb alc_gpio1_init_verbs[] = {
778 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
779 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
780 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
781 { }
782};
783
784static struct hda_verb alc_gpio2_init_verbs[] = {
785 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
786 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
787 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
788 { }
789};
790
bdd148a3
KY
791static struct hda_verb alc_gpio3_init_verbs[] = {
792 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
793 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
794 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
795 { }
796};
797
2c3bf9ab
TI
798/*
799 * Fix hardware PLL issue
800 * On some codecs, the analog PLL gating control must be off while
801 * the default value is 1.
802 */
803static void alc_fix_pll(struct hda_codec *codec)
804{
805 struct alc_spec *spec = codec->spec;
806 unsigned int val;
807
808 if (!spec->pll_nid)
809 return;
810 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
811 spec->pll_coef_idx);
812 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
813 AC_VERB_GET_PROC_COEF, 0);
814 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
815 spec->pll_coef_idx);
816 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
817 val & ~(1 << spec->pll_coef_bit));
818}
819
820static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
821 unsigned int coef_idx, unsigned int coef_bit)
822{
823 struct alc_spec *spec = codec->spec;
824 spec->pll_nid = nid;
825 spec->pll_coef_idx = coef_idx;
826 spec->pll_coef_bit = coef_bit;
827 alc_fix_pll(codec);
828}
829
c9b58006
KY
830static void alc_sku_automute(struct hda_codec *codec)
831{
832 struct alc_spec *spec = codec->spec;
c9b58006
KY
833 unsigned int present;
834 unsigned int hp_nid = spec->autocfg.hp_pins[0];
835 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
836
837 /* need to execute and sync at first */
838 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
839 present = snd_hda_codec_read(codec, hp_nid, 0,
840 AC_VERB_GET_PIN_SENSE, 0);
841 spec->jack_present = (present & 0x80000000) != 0;
f6c7e546
TI
842 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
843 spec->jack_present ? 0 : PIN_OUT);
c9b58006
KY
844}
845
4605b718 846#if 0 /* it's broken in some acses -- temporarily disabled */
7fb0d78f
KY
847static void alc_mic_automute(struct hda_codec *codec)
848{
849 struct alc_spec *spec = codec->spec;
850 unsigned int present;
851 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
852 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
853 unsigned int mix_nid = spec->capsrc_nids[0];
854 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
855
856 capsrc_idx_mic = mic_nid - 0x18;
857 capsrc_idx_fmic = fmic_nid - 0x18;
858 present = snd_hda_codec_read(codec, mic_nid, 0,
859 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
860 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
861 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
862 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
863 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
864 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
865 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
866}
4605b718
TI
867#else
868#define alc_mic_automute(codec) /* NOP */
869#endif /* disabled */
7fb0d78f 870
c9b58006
KY
871/* unsolicited event for HP jack sensing */
872static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
873{
874 if (codec->vendor_id == 0x10ec0880)
875 res >>= 28;
876 else
877 res >>= 26;
7fb0d78f
KY
878 if (res == ALC880_HP_EVENT)
879 alc_sku_automute(codec);
c9b58006 880
7fb0d78f
KY
881 if (res == ALC880_MIC_EVENT)
882 alc_mic_automute(codec);
883}
884
885static void alc_inithook(struct hda_codec *codec)
886{
c9b58006 887 alc_sku_automute(codec);
7fb0d78f 888 alc_mic_automute(codec);
c9b58006
KY
889}
890
f9423e7a
KY
891/* additional initialization for ALC888 variants */
892static void alc888_coef_init(struct hda_codec *codec)
893{
894 unsigned int tmp;
895
896 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
897 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
898 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
899 if ((tmp & 0xf0) == 2)
900 /* alc888S-VC */
901 snd_hda_codec_read(codec, 0x20, 0,
902 AC_VERB_SET_PROC_COEF, 0x830);
903 else
904 /* alc888-VB */
905 snd_hda_codec_read(codec, 0x20, 0,
906 AC_VERB_SET_PROC_COEF, 0x3030);
907}
908
bc9f98a9
KY
909/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
910 * 31 ~ 16 : Manufacture ID
911 * 15 ~ 8 : SKU ID
912 * 7 ~ 0 : Assembly ID
913 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
914 */
915static void alc_subsystem_id(struct hda_codec *codec,
916 unsigned int porta, unsigned int porte,
917 unsigned int portd)
918{
c9b58006
KY
919 unsigned int ass, tmp, i;
920 unsigned nid;
921 struct alc_spec *spec = codec->spec;
bc9f98a9 922
c9b58006
KY
923 ass = codec->subsystem_id & 0xffff;
924 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
925 goto do_sku;
926
ea1fb29a 927 /*
c9b58006
KY
928 * 31~30 : port conetcivity
929 * 29~21 : reserve
930 * 20 : PCBEEP input
931 * 19~16 : Check sum (15:1)
932 * 15~1 : Custom
933 * 0 : override
934 */
935 nid = 0x1d;
936 if (codec->vendor_id == 0x10ec0260)
937 nid = 0x17;
938 ass = snd_hda_codec_read(codec, nid, 0,
939 AC_VERB_GET_CONFIG_DEFAULT, 0);
940 if (!(ass & 1) && !(ass & 0x100000))
941 return;
942 if ((ass >> 30) != 1) /* no physical connection */
bc9f98a9
KY
943 return;
944
c9b58006
KY
945 /* check sum */
946 tmp = 0;
947 for (i = 1; i < 16; i++) {
8c427226 948 if ((ass >> i) & 1)
c9b58006
KY
949 tmp++;
950 }
951 if (((ass >> 16) & 0xf) != tmp)
952 return;
953do_sku:
954 /*
955 * 0 : override
956 * 1 : Swap Jack
957 * 2 : 0 --> Desktop, 1 --> Laptop
958 * 3~5 : External Amplifier control
959 * 7~6 : Reserved
960 */
bc9f98a9
KY
961 tmp = (ass & 0x38) >> 3; /* external Amp control */
962 switch (tmp) {
963 case 1:
964 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
965 break;
966 case 3:
967 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
968 break;
bdd148a3
KY
969 case 7:
970 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
971 break;
c9b58006 972 case 5: /* set EAPD output high */
bdd148a3 973 switch (codec->vendor_id) {
c9b58006
KY
974 case 0x10ec0260:
975 snd_hda_codec_write(codec, 0x0f, 0,
976 AC_VERB_SET_EAPD_BTLENABLE, 2);
977 snd_hda_codec_write(codec, 0x10, 0,
978 AC_VERB_SET_EAPD_BTLENABLE, 2);
979 break;
980 case 0x10ec0262:
bdd148a3
KY
981 case 0x10ec0267:
982 case 0x10ec0268:
c9b58006 983 case 0x10ec0269:
f9423e7a
KY
984 case 0x10ec0660:
985 case 0x10ec0662:
986 case 0x10ec0663:
c9b58006 987 case 0x10ec0862:
20a3a05d 988 case 0x10ec0889:
bdd148a3
KY
989 snd_hda_codec_write(codec, 0x14, 0,
990 AC_VERB_SET_EAPD_BTLENABLE, 2);
991 snd_hda_codec_write(codec, 0x15, 0,
992 AC_VERB_SET_EAPD_BTLENABLE, 2);
c9b58006 993 break;
bdd148a3 994 }
c9b58006
KY
995 switch (codec->vendor_id) {
996 case 0x10ec0260:
997 snd_hda_codec_write(codec, 0x1a, 0,
998 AC_VERB_SET_COEF_INDEX, 7);
999 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1000 AC_VERB_GET_PROC_COEF, 0);
1001 snd_hda_codec_write(codec, 0x1a, 0,
1002 AC_VERB_SET_COEF_INDEX, 7);
1003 snd_hda_codec_write(codec, 0x1a, 0,
1004 AC_VERB_SET_PROC_COEF,
1005 tmp | 0x2010);
1006 break;
1007 case 0x10ec0262:
1008 case 0x10ec0880:
1009 case 0x10ec0882:
1010 case 0x10ec0883:
1011 case 0x10ec0885:
20a3a05d 1012 case 0x10ec0889:
c9b58006
KY
1013 snd_hda_codec_write(codec, 0x20, 0,
1014 AC_VERB_SET_COEF_INDEX, 7);
1015 tmp = snd_hda_codec_read(codec, 0x20, 0,
1016 AC_VERB_GET_PROC_COEF, 0);
1017 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1018 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1019 snd_hda_codec_write(codec, 0x20, 0,
1020 AC_VERB_SET_PROC_COEF,
1021 tmp | 0x2010);
1022 break;
f9423e7a 1023 case 0x10ec0888:
1082c748 1024 /*alc888_coef_init(codec);*/ /* called in alc_init() */
f9423e7a 1025 break;
c9b58006
KY
1026 case 0x10ec0267:
1027 case 0x10ec0268:
1028 snd_hda_codec_write(codec, 0x20, 0,
1029 AC_VERB_SET_COEF_INDEX, 7);
1030 tmp = snd_hda_codec_read(codec, 0x20, 0,
1031 AC_VERB_GET_PROC_COEF, 0);
1032 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1033 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1034 snd_hda_codec_write(codec, 0x20, 0,
1035 AC_VERB_SET_PROC_COEF,
1036 tmp | 0x3000);
1037 break;
bc9f98a9 1038 }
c9b58006 1039 default:
bc9f98a9
KY
1040 break;
1041 }
ea1fb29a 1042
8c427226 1043 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1044 * when the external headphone out jack is plugged"
1045 */
8c427226 1046 if (!(ass & 0x8000))
c9b58006
KY
1047 return;
1048 /*
1049 * 10~8 : Jack location
1050 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1051 * 14~13: Resvered
1052 * 15 : 1 --> enable the function "Mute internal speaker
1053 * when the external headphone out jack is plugged"
1054 */
1055 if (!spec->autocfg.speaker_pins[0]) {
8c427226 1056 if (spec->autocfg.line_out_pins[0])
c9b58006 1057 spec->autocfg.speaker_pins[0] =
8c427226 1058 spec->autocfg.line_out_pins[0];
c9b58006
KY
1059 else
1060 return;
1061 }
1062
1063 if (!spec->autocfg.hp_pins[0]) {
1064 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1065 if (tmp == 0)
1066 spec->autocfg.hp_pins[0] = porta;
1067 else if (tmp == 1)
1068 spec->autocfg.hp_pins[0] = porte;
1069 else if (tmp == 2)
1070 spec->autocfg.hp_pins[0] = portd;
1071 else
1072 return;
1073 }
7fb0d78f
KY
1074 if (spec->autocfg.hp_pins[0])
1075 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1076 AC_VERB_SET_UNSOLICITED_ENABLE,
1077 AC_USRSP_EN | ALC880_HP_EVENT);
c9b58006 1078
4605b718 1079#if 0 /* it's broken in some acses -- temporarily disabled */
7fb0d78f
KY
1080 if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
1081 spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
1082 snd_hda_codec_write(codec,
1083 spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
1084 AC_VERB_SET_UNSOLICITED_ENABLE,
1085 AC_USRSP_EN | ALC880_MIC_EVENT);
4605b718 1086#endif /* disabled */
ea1fb29a 1087
c9b58006 1088 spec->unsol_event = alc_sku_unsol_event;
bc9f98a9
KY
1089}
1090
f95474ec
TI
1091/*
1092 * Fix-up pin default configurations
1093 */
1094
1095struct alc_pincfg {
1096 hda_nid_t nid;
1097 u32 val;
1098};
1099
1100static void alc_fix_pincfg(struct hda_codec *codec,
1101 const struct snd_pci_quirk *quirk,
1102 const struct alc_pincfg **pinfix)
1103{
1104 const struct alc_pincfg *cfg;
1105
1106 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1107 if (!quirk)
1108 return;
1109
1110 cfg = pinfix[quirk->value];
1111 for (; cfg->nid; cfg++) {
1112 int i;
1113 u32 val = cfg->val;
1114 for (i = 0; i < 4; i++) {
1115 snd_hda_codec_write(codec, cfg->nid, 0,
1116 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
1117 val & 0xff);
1118 val >>= 8;
1119 }
1120 }
1121}
1122
1da177e4 1123/*
e9edcee0
TI
1124 * ALC880 3-stack model
1125 *
1126 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
1127 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1128 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
1129 */
1130
e9edcee0
TI
1131static hda_nid_t alc880_dac_nids[4] = {
1132 /* front, rear, clfe, rear_surr */
1133 0x02, 0x05, 0x04, 0x03
1134};
1135
1136static hda_nid_t alc880_adc_nids[3] = {
1137 /* ADC0-2 */
1138 0x07, 0x08, 0x09,
1139};
1140
1141/* The datasheet says the node 0x07 is connected from inputs,
1142 * but it shows zero connection in the real implementation on some devices.
df694daa 1143 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 1144 */
e9edcee0
TI
1145static hda_nid_t alc880_adc_nids_alt[2] = {
1146 /* ADC1-2 */
1147 0x08, 0x09,
1148};
1149
1150#define ALC880_DIGOUT_NID 0x06
1151#define ALC880_DIGIN_NID 0x0a
1152
1153static struct hda_input_mux alc880_capture_source = {
1154 .num_items = 4,
1155 .items = {
1156 { "Mic", 0x0 },
1157 { "Front Mic", 0x3 },
1158 { "Line", 0x2 },
1159 { "CD", 0x4 },
1160 },
1161};
1162
1163/* channel source setting (2/6 channel selection for 3-stack) */
1164/* 2ch mode */
1165static struct hda_verb alc880_threestack_ch2_init[] = {
1166 /* set line-in to input, mute it */
1167 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1168 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1169 /* set mic-in to input vref 80%, mute it */
1170 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1171 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1172 { } /* end */
1173};
1174
1175/* 6ch mode */
1176static struct hda_verb alc880_threestack_ch6_init[] = {
1177 /* set line-in to output, unmute it */
1178 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1179 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1180 /* set mic-in to output, unmute it */
1181 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1182 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1183 { } /* end */
1184};
1185
d2a6d7dc 1186static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
1187 { 2, alc880_threestack_ch2_init },
1188 { 6, alc880_threestack_ch6_init },
1189};
1190
c8b6bf9b 1191static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 1192 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1193 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 1194 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1195 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
1196 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1197 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1198 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1199 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
1200 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1201 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1202 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1203 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1204 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1205 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1206 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1207 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1208 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1209 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
e9edcee0
TI
1210 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1211 {
1212 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1213 .name = "Channel Mode",
df694daa
KY
1214 .info = alc_ch_mode_info,
1215 .get = alc_ch_mode_get,
1216 .put = alc_ch_mode_put,
e9edcee0
TI
1217 },
1218 { } /* end */
1219};
1220
1221/* capture mixer elements */
c8b6bf9b 1222static struct snd_kcontrol_new alc880_capture_mixer[] = {
e9edcee0
TI
1223 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1224 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1225 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1226 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1227 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1228 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1da177e4
LT
1229 {
1230 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1231 /* The multiple "Capture Source" controls confuse alsamixer
1232 * So call somewhat different..
1da177e4
LT
1233 */
1234 /* .name = "Capture Source", */
1235 .name = "Input Source",
e9edcee0 1236 .count = 3,
1da177e4
LT
1237 .info = alc_mux_enum_info,
1238 .get = alc_mux_enum_get,
1239 .put = alc_mux_enum_put,
1240 },
1da177e4
LT
1241 { } /* end */
1242};
1243
e9edcee0 1244/* capture mixer elements (in case NID 0x07 not available) */
c8b6bf9b 1245static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
71fe7b82
TI
1246 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1247 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1248 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1249 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1da177e4
LT
1250 {
1251 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1252 /* The multiple "Capture Source" controls confuse alsamixer
1253 * So call somewhat different..
1da177e4
LT
1254 */
1255 /* .name = "Capture Source", */
1256 .name = "Input Source",
1257 .count = 2,
1258 .info = alc_mux_enum_info,
1259 .get = alc_mux_enum_get,
1260 .put = alc_mux_enum_put,
1261 },
1da177e4
LT
1262};
1263
e9edcee0
TI
1264
1265
1266/*
1267 * ALC880 5-stack model
1268 *
9c7f852e
TI
1269 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1270 * Side = 0x02 (0xd)
e9edcee0
TI
1271 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1272 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1273 */
1274
1275/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 1276static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 1277 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1278 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
1279 { } /* end */
1280};
1281
e9edcee0
TI
1282/* channel source setting (6/8 channel selection for 5-stack) */
1283/* 6ch mode */
1284static struct hda_verb alc880_fivestack_ch6_init[] = {
1285 /* set line-in to input, mute it */
1286 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1287 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
1288 { } /* end */
1289};
1290
e9edcee0
TI
1291/* 8ch mode */
1292static struct hda_verb alc880_fivestack_ch8_init[] = {
1293 /* set line-in to output, unmute it */
1294 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1295 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1296 { } /* end */
1297};
1298
d2a6d7dc 1299static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
1300 { 6, alc880_fivestack_ch6_init },
1301 { 8, alc880_fivestack_ch8_init },
1302};
1303
1304
1305/*
1306 * ALC880 6-stack model
1307 *
9c7f852e
TI
1308 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1309 * Side = 0x05 (0x0f)
e9edcee0
TI
1310 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1311 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1312 */
1313
1314static hda_nid_t alc880_6st_dac_nids[4] = {
1315 /* front, rear, clfe, rear_surr */
1316 0x02, 0x03, 0x04, 0x05
f12ab1e0 1317};
e9edcee0
TI
1318
1319static struct hda_input_mux alc880_6stack_capture_source = {
1320 .num_items = 4,
1321 .items = {
1322 { "Mic", 0x0 },
1323 { "Front Mic", 0x1 },
1324 { "Line", 0x2 },
1325 { "CD", 0x4 },
1326 },
1327};
1328
1329/* fixed 8-channels */
d2a6d7dc 1330static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
1331 { 8, NULL },
1332};
1333
c8b6bf9b 1334static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 1335 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1336 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1337 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1338 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1339 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1340 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1341 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1342 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 1343 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1344 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
1345 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1346 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1347 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1348 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1349 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1350 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1351 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1352 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1353 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1354 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
16ded525
TI
1355 {
1356 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1357 .name = "Channel Mode",
df694daa
KY
1358 .info = alc_ch_mode_info,
1359 .get = alc_ch_mode_get,
1360 .put = alc_ch_mode_put,
16ded525
TI
1361 },
1362 { } /* end */
1363};
1364
e9edcee0
TI
1365
1366/*
1367 * ALC880 W810 model
1368 *
1369 * W810 has rear IO for:
1370 * Front (DAC 02)
1371 * Surround (DAC 03)
1372 * Center/LFE (DAC 04)
1373 * Digital out (06)
1374 *
1375 * The system also has a pair of internal speakers, and a headphone jack.
1376 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 1377 *
e9edcee0
TI
1378 * There is a variable resistor to control the speaker or headphone
1379 * volume. This is a hardware-only device without a software API.
1380 *
1381 * Plugging headphones in will disable the internal speakers. This is
1382 * implemented in hardware, not via the driver using jack sense. In
1383 * a similar fashion, plugging into the rear socket marked "front" will
1384 * disable both the speakers and headphones.
1385 *
1386 * For input, there's a microphone jack, and an "audio in" jack.
1387 * These may not do anything useful with this driver yet, because I
1388 * haven't setup any initialization verbs for these yet...
1389 */
1390
1391static hda_nid_t alc880_w810_dac_nids[3] = {
1392 /* front, rear/surround, clfe */
1393 0x02, 0x03, 0x04
16ded525
TI
1394};
1395
e9edcee0 1396/* fixed 6 channels */
d2a6d7dc 1397static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
1398 { 6, NULL }
1399};
1400
1401/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 1402static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 1403 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1404 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1405 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1406 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1407 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1408 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1409 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1410 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
1411 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1412 { } /* end */
1413};
1414
1415
1416/*
1417 * Z710V model
1418 *
1419 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
1420 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1421 * Line = 0x1a
e9edcee0
TI
1422 */
1423
1424static hda_nid_t alc880_z71v_dac_nids[1] = {
1425 0x02
1426};
1427#define ALC880_Z71V_HP_DAC 0x03
1428
1429/* fixed 2 channels */
d2a6d7dc 1430static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
1431 { 2, NULL }
1432};
1433
c8b6bf9b 1434static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 1435 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1436 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 1437 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1438 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1439 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1440 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
1441 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1442 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
1443 { } /* end */
1444};
1445
e9edcee0 1446
e9edcee0
TI
1447/*
1448 * ALC880 F1734 model
1449 *
1450 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1451 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1452 */
1453
1454static hda_nid_t alc880_f1734_dac_nids[1] = {
1455 0x03
1456};
1457#define ALC880_F1734_HP_DAC 0x02
1458
c8b6bf9b 1459static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 1460 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1461 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
1462 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1463 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
1464 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1465 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
1466 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1467 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
1468 { } /* end */
1469};
1470
937b4160
TI
1471static struct hda_input_mux alc880_f1734_capture_source = {
1472 .num_items = 2,
1473 .items = {
1474 { "Mic", 0x1 },
1475 { "CD", 0x4 },
1476 },
1477};
1478
e9edcee0 1479
e9edcee0
TI
1480/*
1481 * ALC880 ASUS model
1482 *
1483 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1484 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1485 * Mic = 0x18, Line = 0x1a
1486 */
1487
1488#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1489#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1490
c8b6bf9b 1491static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 1492 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1493 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1494 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1495 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1496 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1497 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1498 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1499 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
1500 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1501 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1502 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1503 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
1504 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1505 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
1506 {
1507 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1508 .name = "Channel Mode",
df694daa
KY
1509 .info = alc_ch_mode_info,
1510 .get = alc_ch_mode_get,
1511 .put = alc_ch_mode_put,
16ded525
TI
1512 },
1513 { } /* end */
1514};
e9edcee0 1515
e9edcee0
TI
1516/*
1517 * ALC880 ASUS W1V model
1518 *
1519 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1520 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1521 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1522 */
1523
1524/* additional mixers to alc880_asus_mixer */
c8b6bf9b 1525static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
1526 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1527 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1528 { } /* end */
1529};
1530
3c10a9d9 1531/* additional mixers to alc880_asus_mixer */
c8b6bf9b 1532static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
3c10a9d9
TI
1533 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1534 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1535 { } /* end */
1536};
e9edcee0 1537
df694daa
KY
1538/* TCL S700 */
1539static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1540 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1541 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1542 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1543 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1544 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1545 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1546 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1547 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1548 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1549 {
1550 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1551 /* The multiple "Capture Source" controls confuse alsamixer
1552 * So call somewhat different..
df694daa
KY
1553 */
1554 /* .name = "Capture Source", */
1555 .name = "Input Source",
1556 .count = 1,
1557 .info = alc_mux_enum_info,
1558 .get = alc_mux_enum_get,
1559 .put = alc_mux_enum_put,
1560 },
1561 { } /* end */
1562};
1563
ccc656ce
KY
1564/* Uniwill */
1565static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
1566 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1567 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1568 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1569 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
1570 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1571 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1572 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1573 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1574 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1575 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1576 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1577 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1578 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1579 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1580 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1581 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1582 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1583 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1584 {
1585 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1586 .name = "Channel Mode",
1587 .info = alc_ch_mode_info,
1588 .get = alc_ch_mode_get,
1589 .put = alc_ch_mode_put,
1590 },
1591 { } /* end */
1592};
1593
2cf9f0fc
TD
1594static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1595 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1596 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1597 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1598 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1599 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1600 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1601 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1602 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1603 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1604 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1605 { } /* end */
1606};
1607
ccc656ce 1608static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
1609 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1610 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1611 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1612 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
1613 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1614 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1615 { } /* end */
1616};
1617
2134ea4f
TI
1618/*
1619 * virtual master controls
1620 */
1621
1622/*
1623 * slave controls for virtual master
1624 */
1625static const char *alc_slave_vols[] = {
1626 "Front Playback Volume",
1627 "Surround Playback Volume",
1628 "Center Playback Volume",
1629 "LFE Playback Volume",
1630 "Side Playback Volume",
1631 "Headphone Playback Volume",
1632 "Speaker Playback Volume",
1633 "Mono Playback Volume",
2134ea4f
TI
1634 "Line-Out Playback Volume",
1635 NULL,
1636};
1637
1638static const char *alc_slave_sws[] = {
1639 "Front Playback Switch",
1640 "Surround Playback Switch",
1641 "Center Playback Switch",
1642 "LFE Playback Switch",
1643 "Side Playback Switch",
1644 "Headphone Playback Switch",
1645 "Speaker Playback Switch",
1646 "Mono Playback Switch",
edb54a55 1647 "IEC958 Playback Switch",
2134ea4f
TI
1648 NULL,
1649};
1650
1da177e4 1651/*
e9edcee0 1652 * build control elements
1da177e4 1653 */
603c4019
TI
1654
1655static void alc_free_kctls(struct hda_codec *codec);
1656
1da177e4
LT
1657static int alc_build_controls(struct hda_codec *codec)
1658{
1659 struct alc_spec *spec = codec->spec;
1660 int err;
1661 int i;
1662
1663 for (i = 0; i < spec->num_mixers; i++) {
1664 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1665 if (err < 0)
1666 return err;
1667 }
1668
1669 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
1670 err = snd_hda_create_spdif_out_ctls(codec,
1671 spec->multiout.dig_out_nid);
1da177e4
LT
1672 if (err < 0)
1673 return err;
9a08160b
TI
1674 err = snd_hda_create_spdif_share_sw(codec,
1675 &spec->multiout);
1676 if (err < 0)
1677 return err;
1678 spec->multiout.share_spdif = 1;
1da177e4
LT
1679 }
1680 if (spec->dig_in_nid) {
1681 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1682 if (err < 0)
1683 return err;
1684 }
2134ea4f
TI
1685
1686 /* if we have no master control, let's create it */
1687 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 1688 unsigned int vmaster_tlv[4];
2134ea4f 1689 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 1690 HDA_OUTPUT, vmaster_tlv);
2134ea4f 1691 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 1692 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
1693 if (err < 0)
1694 return err;
1695 }
1696 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1697 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1698 NULL, alc_slave_sws);
1699 if (err < 0)
1700 return err;
1701 }
1702
603c4019 1703 alc_free_kctls(codec); /* no longer needed */
1da177e4
LT
1704 return 0;
1705}
1706
e9edcee0 1707
1da177e4
LT
1708/*
1709 * initialize the codec volumes, etc
1710 */
1711
e9edcee0
TI
1712/*
1713 * generic initialization of ADC, input mixers and output mixers
1714 */
1715static struct hda_verb alc880_volume_init_verbs[] = {
1716 /*
1717 * Unmute ADC0-2 and set the default input to mic-in
1718 */
71fe7b82 1719 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1720 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 1721 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1722 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 1723 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1724 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 1725
e9edcee0
TI
1726 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1727 * mixer widget
9c7f852e
TI
1728 * Note: PASD motherboards uses the Line In 2 as the input for front
1729 * panel mic (mic 2)
1da177e4 1730 */
e9edcee0 1731 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
1732 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1733 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1734 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1735 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1736 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1737 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1738 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 1739
e9edcee0
TI
1740 /*
1741 * Set up output mixers (0x0c - 0x0f)
1da177e4 1742 */
e9edcee0
TI
1743 /* set vol=0 to output mixers */
1744 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1745 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1746 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1747 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1748 /* set up input amps for analog loopback */
1749 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
1750 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1751 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1752 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1753 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1754 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1755 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1756 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1757 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
1758
1759 { }
1760};
1761
e9edcee0
TI
1762/*
1763 * 3-stack pin configuration:
1764 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1765 */
1766static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1767 /*
1768 * preset connection lists of input pins
1769 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1770 */
1771 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1772 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1773 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1774
1775 /*
1776 * Set pin mode and muting
1777 */
1778 /* set front pin widgets 0x14 for output */
05acb863 1779 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1780 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1781 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1782 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1783 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1784 /* Mic2 (as headphone out) for HP output */
1785 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1786 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 1787 /* Line In pin widget for input */
05acb863 1788 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
1789 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1790 /* Line2 (as front mic) pin widget for input and vref at 80% */
1791 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1792 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 1793 /* CD pin widget for input */
05acb863 1794 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 1795
e9edcee0
TI
1796 { }
1797};
1da177e4 1798
e9edcee0
TI
1799/*
1800 * 5-stack pin configuration:
1801 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1802 * line-in/side = 0x1a, f-mic = 0x1b
1803 */
1804static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1805 /*
1806 * preset connection lists of input pins
1807 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 1808 */
e9edcee0
TI
1809 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1810 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 1811
e9edcee0
TI
1812 /*
1813 * Set pin mode and muting
1da177e4 1814 */
e9edcee0
TI
1815 /* set pin widgets 0x14-0x17 for output */
1816 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1817 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1818 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1819 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1820 /* unmute pins for output (no gain on this amp) */
1821 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1822 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1823 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1824 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1825
1826 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1827 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1828 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1829 /* Mic2 (as headphone out) for HP output */
1830 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1831 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1832 /* Line In pin widget for input */
1833 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1834 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1835 /* Line2 (as front mic) pin widget for input and vref at 80% */
1836 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1837 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1838 /* CD pin widget for input */
1839 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
1840
1841 { }
1842};
1843
e9edcee0
TI
1844/*
1845 * W810 pin configuration:
1846 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1847 */
1848static struct hda_verb alc880_pin_w810_init_verbs[] = {
1849 /* hphone/speaker input selector: front DAC */
1850 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 1851
05acb863 1852 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1853 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1854 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1855 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1856 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1857 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 1858
e9edcee0 1859 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 1860 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 1861
1da177e4
LT
1862 { }
1863};
1864
e9edcee0
TI
1865/*
1866 * Z71V pin configuration:
1867 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1868 */
1869static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 1870 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1871 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1872 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1873 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 1874
16ded525 1875 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1876 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 1877 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1878 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
1879
1880 { }
1881};
1882
e9edcee0
TI
1883/*
1884 * 6-stack pin configuration:
9c7f852e
TI
1885 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1886 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
1887 */
1888static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1889 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1890
16ded525 1891 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1892 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1893 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1894 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1895 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1896 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1897 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1898 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1899
16ded525 1900 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1901 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1902 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1903 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1904 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 1905 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1906 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1907 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1908 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 1909
e9edcee0
TI
1910 { }
1911};
1912
ccc656ce
KY
1913/*
1914 * Uniwill pin configuration:
1915 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1916 * line = 0x1a
1917 */
1918static struct hda_verb alc880_uniwill_init_verbs[] = {
1919 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1920
1921 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1922 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1923 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1924 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1925 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1926 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1927 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1928 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1929 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1930 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1931 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1932 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1933 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1934 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1935
1936 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1937 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1938 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1939 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1940 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1941 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1942 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1943 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1944 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1945
1946 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1947 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1948
1949 { }
1950};
1951
1952/*
1953* Uniwill P53
ea1fb29a 1954* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce
KY
1955 */
1956static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1957 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1958
1959 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1960 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1961 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1962 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1963 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1964 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1965 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1966 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1967 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1968 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1969 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1970 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1971
1972 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1973 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1974 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1975 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1976 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1977 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1978
1979 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1980 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1981
1982 { }
1983};
1984
2cf9f0fc
TD
1985static struct hda_verb alc880_beep_init_verbs[] = {
1986 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1987 { }
1988};
1989
ccc656ce 1990/* toggle speaker-output according to the hp-jack state */
458a4fab 1991static void alc880_uniwill_hp_automute(struct hda_codec *codec)
ccc656ce
KY
1992{
1993 unsigned int present;
f12ab1e0 1994 unsigned char bits;
ccc656ce
KY
1995
1996 present = snd_hda_codec_read(codec, 0x14, 0,
1997 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1998 bits = present ? HDA_AMP_MUTE : 0;
1999 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
2000 HDA_AMP_MUTE, bits);
2001 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
2002 HDA_AMP_MUTE, bits);
458a4fab
TI
2003}
2004
2005/* auto-toggle front mic */
2006static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2007{
2008 unsigned int present;
2009 unsigned char bits;
ccc656ce
KY
2010
2011 present = snd_hda_codec_read(codec, 0x18, 0,
2012 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2013 bits = present ? HDA_AMP_MUTE : 0;
2014 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
2015}
2016
2017static void alc880_uniwill_automute(struct hda_codec *codec)
2018{
2019 alc880_uniwill_hp_automute(codec);
2020 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
2021}
2022
2023static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2024 unsigned int res)
2025{
2026 /* Looks like the unsol event is incompatible with the standard
2027 * definition. 4bit tag is placed at 28 bit!
2028 */
458a4fab
TI
2029 switch (res >> 28) {
2030 case ALC880_HP_EVENT:
2031 alc880_uniwill_hp_automute(codec);
2032 break;
2033 case ALC880_MIC_EVENT:
2034 alc880_uniwill_mic_automute(codec);
2035 break;
2036 }
ccc656ce
KY
2037}
2038
2039static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
2040{
2041 unsigned int present;
f12ab1e0 2042 unsigned char bits;
ccc656ce
KY
2043
2044 present = snd_hda_codec_read(codec, 0x14, 0,
2045 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a 2046 bits = present ? HDA_AMP_MUTE : 0;
64654c2f 2047 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
ccc656ce
KY
2048}
2049
2050static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2051{
2052 unsigned int present;
ea1fb29a 2053
ccc656ce 2054 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
2055 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2056 present &= HDA_AMP_VOLMASK;
2057 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2058 HDA_AMP_VOLMASK, present);
2059 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2060 HDA_AMP_VOLMASK, present);
ccc656ce 2061}
47fd830a 2062
ccc656ce
KY
2063static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2064 unsigned int res)
2065{
2066 /* Looks like the unsol event is incompatible with the standard
2067 * definition. 4bit tag is placed at 28 bit!
2068 */
2069 if ((res >> 28) == ALC880_HP_EVENT)
2070 alc880_uniwill_p53_hp_automute(codec);
f12ab1e0 2071 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce
KY
2072 alc880_uniwill_p53_dcvol_automute(codec);
2073}
2074
e9edcee0
TI
2075/*
2076 * F1734 pin configuration:
2077 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2078 */
2079static struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 2080 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
2081 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2082 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2083 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2084 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2085
e9edcee0 2086 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 2087 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 2088 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 2089 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2090
e9edcee0
TI
2091 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2092 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 2093 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 2094 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2095 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2096 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2097 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2098 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2099 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 2100
937b4160
TI
2101 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2102 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2103
dfc0ff62
TI
2104 { }
2105};
2106
e9edcee0
TI
2107/*
2108 * ASUS pin configuration:
2109 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2110 */
2111static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
2112 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2113 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2114 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2115 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2116
2117 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 2118 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2119 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2120 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2121 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2122 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2123 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
2124 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2125
2126 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2127 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2128 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2129 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2130 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2131 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 2132 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 2133 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 2134 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 2135
e9edcee0
TI
2136 { }
2137};
16ded525 2138
e9edcee0 2139/* Enable GPIO mask and set output */
bc9f98a9
KY
2140#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2141#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
df694daa
KY
2142
2143/* Clevo m520g init */
2144static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2145 /* headphone output */
2146 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2147 /* line-out */
2148 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2149 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2150 /* Line-in */
2151 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2152 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2153 /* CD */
2154 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2155 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2156 /* Mic1 (rear panel) */
2157 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2158 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2159 /* Mic2 (front panel) */
2160 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2161 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2162 /* headphone */
2163 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2164 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2165 /* change to EAPD mode */
2166 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2167 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2168
2169 { }
16ded525
TI
2170};
2171
df694daa 2172static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
2173 /* change to EAPD mode */
2174 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2175 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2176
df694daa
KY
2177 /* Headphone output */
2178 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2179 /* Front output*/
2180 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2181 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2182
2183 /* Line In pin widget for input */
2184 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2185 /* CD pin widget for input */
2186 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2187 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2188 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2189
2190 /* change to EAPD mode */
2191 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2192 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2193
2194 { }
2195};
16ded525 2196
e9edcee0 2197/*
ae6b813a
TI
2198 * LG m1 express dual
2199 *
2200 * Pin assignment:
2201 * Rear Line-In/Out (blue): 0x14
2202 * Build-in Mic-In: 0x15
2203 * Speaker-out: 0x17
2204 * HP-Out (green): 0x1b
2205 * Mic-In/Out (red): 0x19
2206 * SPDIF-Out: 0x1e
2207 */
2208
2209/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2210static hda_nid_t alc880_lg_dac_nids[3] = {
2211 0x05, 0x02, 0x03
2212};
2213
2214/* seems analog CD is not working */
2215static struct hda_input_mux alc880_lg_capture_source = {
2216 .num_items = 3,
2217 .items = {
2218 { "Mic", 0x1 },
2219 { "Line", 0x5 },
2220 { "Internal Mic", 0x6 },
2221 },
2222};
2223
2224/* 2,4,6 channel modes */
2225static struct hda_verb alc880_lg_ch2_init[] = {
2226 /* set line-in and mic-in to input */
2227 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2228 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2229 { }
2230};
2231
2232static struct hda_verb alc880_lg_ch4_init[] = {
2233 /* set line-in to out and mic-in to input */
2234 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2235 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2236 { }
2237};
2238
2239static struct hda_verb alc880_lg_ch6_init[] = {
2240 /* set line-in and mic-in to output */
2241 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2242 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2243 { }
2244};
2245
2246static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2247 { 2, alc880_lg_ch2_init },
2248 { 4, alc880_lg_ch4_init },
2249 { 6, alc880_lg_ch6_init },
2250};
2251
2252static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
2253 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2254 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
2255 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2256 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2257 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2258 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2259 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2260 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2261 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2262 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2263 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2264 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2265 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2266 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2267 {
2268 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2269 .name = "Channel Mode",
2270 .info = alc_ch_mode_info,
2271 .get = alc_ch_mode_get,
2272 .put = alc_ch_mode_put,
2273 },
2274 { } /* end */
2275};
2276
2277static struct hda_verb alc880_lg_init_verbs[] = {
2278 /* set capture source to mic-in */
2279 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2280 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2281 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2282 /* mute all amp mixer inputs */
2283 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
2284 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2285 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
2286 /* line-in to input */
2287 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2288 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2289 /* built-in mic */
2290 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2291 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2292 /* speaker-out */
2293 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2294 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2295 /* mic-in to input */
2296 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2297 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2298 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2299 /* HP-out */
2300 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2301 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2302 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2303 /* jack sense */
2304 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2305 { }
2306};
2307
2308/* toggle speaker-output according to the hp-jack state */
2309static void alc880_lg_automute(struct hda_codec *codec)
2310{
2311 unsigned int present;
f12ab1e0 2312 unsigned char bits;
ae6b813a
TI
2313
2314 present = snd_hda_codec_read(codec, 0x1b, 0,
2315 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2316 bits = present ? HDA_AMP_MUTE : 0;
2317 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2318 HDA_AMP_MUTE, bits);
ae6b813a
TI
2319}
2320
2321static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2322{
2323 /* Looks like the unsol event is incompatible with the standard
2324 * definition. 4bit tag is placed at 28 bit!
2325 */
2326 if ((res >> 28) == 0x01)
2327 alc880_lg_automute(codec);
2328}
2329
d681518a
TI
2330/*
2331 * LG LW20
2332 *
2333 * Pin assignment:
2334 * Speaker-out: 0x14
2335 * Mic-In: 0x18
e4f41da9
CM
2336 * Built-in Mic-In: 0x19
2337 * Line-In: 0x1b
2338 * HP-Out: 0x1a
d681518a
TI
2339 * SPDIF-Out: 0x1e
2340 */
2341
d681518a 2342static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 2343 .num_items = 3,
d681518a
TI
2344 .items = {
2345 { "Mic", 0x0 },
2346 { "Internal Mic", 0x1 },
e4f41da9 2347 { "Line In", 0x2 },
d681518a
TI
2348 },
2349};
2350
0a8c5da3
CM
2351#define alc880_lg_lw_modes alc880_threestack_modes
2352
d681518a 2353static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
2354 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2355 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2356 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2357 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2358 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2359 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2360 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2361 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2362 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2363 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
2364 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2365 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2366 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2367 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
2368 {
2369 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2370 .name = "Channel Mode",
2371 .info = alc_ch_mode_info,
2372 .get = alc_ch_mode_get,
2373 .put = alc_ch_mode_put,
2374 },
d681518a
TI
2375 { } /* end */
2376};
2377
2378static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
2379 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2380 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2381 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2382
d681518a
TI
2383 /* set capture source to mic-in */
2384 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2385 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2386 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 2387 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
2388 /* speaker-out */
2389 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2390 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2391 /* HP-out */
d681518a
TI
2392 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2393 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2394 /* mic-in to input */
2395 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2396 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2397 /* built-in mic */
2398 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2399 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2400 /* jack sense */
2401 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2402 { }
2403};
2404
2405/* toggle speaker-output according to the hp-jack state */
2406static void alc880_lg_lw_automute(struct hda_codec *codec)
2407{
2408 unsigned int present;
f12ab1e0 2409 unsigned char bits;
d681518a
TI
2410
2411 present = snd_hda_codec_read(codec, 0x1b, 0,
2412 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2413 bits = present ? HDA_AMP_MUTE : 0;
2414 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2415 HDA_AMP_MUTE, bits);
d681518a
TI
2416}
2417
2418static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2419{
2420 /* Looks like the unsol event is incompatible with the standard
2421 * definition. 4bit tag is placed at 28 bit!
2422 */
2423 if ((res >> 28) == 0x01)
2424 alc880_lg_lw_automute(codec);
2425}
2426
df99cd33
TI
2427static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2428 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2429 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2430 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2431 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2432 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2433 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2434 { } /* end */
2435};
2436
2437static struct hda_input_mux alc880_medion_rim_capture_source = {
2438 .num_items = 2,
2439 .items = {
2440 { "Mic", 0x0 },
2441 { "Internal Mic", 0x1 },
2442 },
2443};
2444
2445static struct hda_verb alc880_medion_rim_init_verbs[] = {
2446 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2447
2448 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2449 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2450
2451 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2452 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2453 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2454 /* Mic2 (as headphone out) for HP output */
2455 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2456 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2457 /* Internal Speaker */
2458 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2459 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2460
2461 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2462 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2463
2464 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2465 { }
2466};
2467
2468/* toggle speaker-output according to the hp-jack state */
2469static void alc880_medion_rim_automute(struct hda_codec *codec)
2470{
2471 unsigned int present;
2472 unsigned char bits;
2473
2474 present = snd_hda_codec_read(codec, 0x14, 0,
2475 AC_VERB_GET_PIN_SENSE, 0)
2476 & AC_PINSENSE_PRESENCE;
2477 bits = present ? HDA_AMP_MUTE : 0;
2478 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2479 HDA_AMP_MUTE, bits);
2480 if (present)
2481 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2482 else
2483 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2484}
2485
2486static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2487 unsigned int res)
2488{
2489 /* Looks like the unsol event is incompatible with the standard
2490 * definition. 4bit tag is placed at 28 bit!
2491 */
2492 if ((res >> 28) == ALC880_HP_EVENT)
2493 alc880_medion_rim_automute(codec);
2494}
2495
cb53c626
TI
2496#ifdef CONFIG_SND_HDA_POWER_SAVE
2497static struct hda_amp_list alc880_loopbacks[] = {
2498 { 0x0b, HDA_INPUT, 0 },
2499 { 0x0b, HDA_INPUT, 1 },
2500 { 0x0b, HDA_INPUT, 2 },
2501 { 0x0b, HDA_INPUT, 3 },
2502 { 0x0b, HDA_INPUT, 4 },
2503 { } /* end */
2504};
2505
2506static struct hda_amp_list alc880_lg_loopbacks[] = {
2507 { 0x0b, HDA_INPUT, 1 },
2508 { 0x0b, HDA_INPUT, 6 },
2509 { 0x0b, HDA_INPUT, 7 },
2510 { } /* end */
2511};
2512#endif
2513
ae6b813a
TI
2514/*
2515 * Common callbacks
e9edcee0
TI
2516 */
2517
1da177e4
LT
2518static int alc_init(struct hda_codec *codec)
2519{
2520 struct alc_spec *spec = codec->spec;
e9edcee0
TI
2521 unsigned int i;
2522
2c3bf9ab 2523 alc_fix_pll(codec);
1082c748
TI
2524 if (codec->vendor_id == 0x10ec0888)
2525 alc888_coef_init(codec);
2c3bf9ab 2526
e9edcee0
TI
2527 for (i = 0; i < spec->num_init_verbs; i++)
2528 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
2529
2530 if (spec->init_hook)
2531 spec->init_hook(codec);
2532
1da177e4
LT
2533 return 0;
2534}
2535
ae6b813a
TI
2536static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2537{
2538 struct alc_spec *spec = codec->spec;
2539
2540 if (spec->unsol_event)
2541 spec->unsol_event(codec, res);
2542}
2543
cb53c626
TI
2544#ifdef CONFIG_SND_HDA_POWER_SAVE
2545static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2546{
2547 struct alc_spec *spec = codec->spec;
2548 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2549}
2550#endif
2551
1da177e4
LT
2552/*
2553 * Analog playback callbacks
2554 */
2555static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2556 struct hda_codec *codec,
c8b6bf9b 2557 struct snd_pcm_substream *substream)
1da177e4
LT
2558{
2559 struct alc_spec *spec = codec->spec;
9a08160b
TI
2560 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2561 hinfo);
1da177e4
LT
2562}
2563
2564static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2565 struct hda_codec *codec,
2566 unsigned int stream_tag,
2567 unsigned int format,
c8b6bf9b 2568 struct snd_pcm_substream *substream)
1da177e4
LT
2569{
2570 struct alc_spec *spec = codec->spec;
9c7f852e
TI
2571 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2572 stream_tag, format, substream);
1da177e4
LT
2573}
2574
2575static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2576 struct hda_codec *codec,
c8b6bf9b 2577 struct snd_pcm_substream *substream)
1da177e4
LT
2578{
2579 struct alc_spec *spec = codec->spec;
2580 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2581}
2582
2583/*
2584 * Digital out
2585 */
2586static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2587 struct hda_codec *codec,
c8b6bf9b 2588 struct snd_pcm_substream *substream)
1da177e4
LT
2589{
2590 struct alc_spec *spec = codec->spec;
2591 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2592}
2593
6b97eb45
TI
2594static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2595 struct hda_codec *codec,
2596 unsigned int stream_tag,
2597 unsigned int format,
2598 struct snd_pcm_substream *substream)
2599{
2600 struct alc_spec *spec = codec->spec;
2601 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2602 stream_tag, format, substream);
2603}
2604
1da177e4
LT
2605static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2606 struct hda_codec *codec,
c8b6bf9b 2607 struct snd_pcm_substream *substream)
1da177e4
LT
2608{
2609 struct alc_spec *spec = codec->spec;
2610 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2611}
2612
2613/*
2614 * Analog capture
2615 */
6330079f 2616static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
2617 struct hda_codec *codec,
2618 unsigned int stream_tag,
2619 unsigned int format,
c8b6bf9b 2620 struct snd_pcm_substream *substream)
1da177e4
LT
2621{
2622 struct alc_spec *spec = codec->spec;
2623
6330079f 2624 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
2625 stream_tag, 0, format);
2626 return 0;
2627}
2628
6330079f 2629static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 2630 struct hda_codec *codec,
c8b6bf9b 2631 struct snd_pcm_substream *substream)
1da177e4
LT
2632{
2633 struct alc_spec *spec = codec->spec;
2634
888afa15
TI
2635 snd_hda_codec_cleanup_stream(codec,
2636 spec->adc_nids[substream->number + 1]);
1da177e4
LT
2637 return 0;
2638}
2639
2640
2641/*
2642 */
2643static struct hda_pcm_stream alc880_pcm_analog_playback = {
2644 .substreams = 1,
2645 .channels_min = 2,
2646 .channels_max = 8,
e9edcee0 2647 /* NID is set in alc_build_pcms */
1da177e4
LT
2648 .ops = {
2649 .open = alc880_playback_pcm_open,
2650 .prepare = alc880_playback_pcm_prepare,
2651 .cleanup = alc880_playback_pcm_cleanup
2652 },
2653};
2654
2655static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
2656 .substreams = 1,
2657 .channels_min = 2,
2658 .channels_max = 2,
2659 /* NID is set in alc_build_pcms */
2660};
2661
2662static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2663 .substreams = 1,
2664 .channels_min = 2,
2665 .channels_max = 2,
2666 /* NID is set in alc_build_pcms */
2667};
2668
2669static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2670 .substreams = 2, /* can be overridden */
1da177e4
LT
2671 .channels_min = 2,
2672 .channels_max = 2,
e9edcee0 2673 /* NID is set in alc_build_pcms */
1da177e4 2674 .ops = {
6330079f
TI
2675 .prepare = alc880_alt_capture_pcm_prepare,
2676 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
2677 },
2678};
2679
2680static struct hda_pcm_stream alc880_pcm_digital_playback = {
2681 .substreams = 1,
2682 .channels_min = 2,
2683 .channels_max = 2,
2684 /* NID is set in alc_build_pcms */
2685 .ops = {
2686 .open = alc880_dig_playback_pcm_open,
6b97eb45
TI
2687 .close = alc880_dig_playback_pcm_close,
2688 .prepare = alc880_dig_playback_pcm_prepare
1da177e4
LT
2689 },
2690};
2691
2692static struct hda_pcm_stream alc880_pcm_digital_capture = {
2693 .substreams = 1,
2694 .channels_min = 2,
2695 .channels_max = 2,
2696 /* NID is set in alc_build_pcms */
2697};
2698
4c5186ed 2699/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 2700static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
2701 .substreams = 0,
2702 .channels_min = 0,
2703 .channels_max = 0,
2704};
2705
1da177e4
LT
2706static int alc_build_pcms(struct hda_codec *codec)
2707{
2708 struct alc_spec *spec = codec->spec;
2709 struct hda_pcm *info = spec->pcm_rec;
2710 int i;
2711
2712 codec->num_pcms = 1;
2713 codec->pcm_info = info;
2714
2715 info->name = spec->stream_name_analog;
4a471b7d 2716 if (spec->stream_analog_playback) {
da3cec35
TI
2717 if (snd_BUG_ON(!spec->multiout.dac_nids))
2718 return -EINVAL;
4a471b7d
TI
2719 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2720 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2721 }
2722 if (spec->stream_analog_capture) {
da3cec35
TI
2723 if (snd_BUG_ON(!spec->adc_nids))
2724 return -EINVAL;
4a471b7d
TI
2725 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2726 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2727 }
2728
2729 if (spec->channel_mode) {
2730 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2731 for (i = 0; i < spec->num_channel_mode; i++) {
2732 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2733 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2734 }
1da177e4
LT
2735 }
2736 }
2737
e08a007d 2738 /* SPDIF for stream index #1 */
1da177e4 2739 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
e08a007d 2740 codec->num_pcms = 2;
c06134d7 2741 info = spec->pcm_rec + 1;
1da177e4 2742 info->name = spec->stream_name_digital;
7ba72ba1 2743 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
2744 if (spec->multiout.dig_out_nid &&
2745 spec->stream_digital_playback) {
1da177e4
LT
2746 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2747 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2748 }
4a471b7d
TI
2749 if (spec->dig_in_nid &&
2750 spec->stream_digital_capture) {
1da177e4
LT
2751 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2752 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2753 }
963f803f
TI
2754 /* FIXME: do we need this for all Realtek codec models? */
2755 codec->spdif_status_reset = 1;
1da177e4
LT
2756 }
2757
e08a007d
TI
2758 /* If the use of more than one ADC is requested for the current
2759 * model, configure a second analog capture-only PCM.
2760 */
2761 /* Additional Analaog capture for index #2 */
6330079f
TI
2762 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2763 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 2764 codec->num_pcms = 3;
c06134d7 2765 info = spec->pcm_rec + 2;
e08a007d 2766 info->name = spec->stream_name_analog;
6330079f
TI
2767 if (spec->alt_dac_nid) {
2768 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2769 *spec->stream_analog_alt_playback;
2770 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2771 spec->alt_dac_nid;
2772 } else {
2773 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2774 alc_pcm_null_stream;
2775 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2776 }
2777 if (spec->num_adc_nids > 1) {
2778 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2779 *spec->stream_analog_alt_capture;
2780 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2781 spec->adc_nids[1];
2782 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2783 spec->num_adc_nids - 1;
2784 } else {
2785 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2786 alc_pcm_null_stream;
2787 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
2788 }
2789 }
2790
1da177e4
LT
2791 return 0;
2792}
2793
603c4019
TI
2794static void alc_free_kctls(struct hda_codec *codec)
2795{
2796 struct alc_spec *spec = codec->spec;
2797
2798 if (spec->kctls.list) {
2799 struct snd_kcontrol_new *kctl = spec->kctls.list;
2800 int i;
2801 for (i = 0; i < spec->kctls.used; i++)
2802 kfree(kctl[i].name);
2803 }
2804 snd_array_free(&spec->kctls);
2805}
2806
1da177e4
LT
2807static void alc_free(struct hda_codec *codec)
2808{
e9edcee0 2809 struct alc_spec *spec = codec->spec;
e9edcee0 2810
f12ab1e0 2811 if (!spec)
e9edcee0
TI
2812 return;
2813
603c4019 2814 alc_free_kctls(codec);
e9edcee0 2815 kfree(spec);
7943a8ab 2816 codec->spec = NULL; /* to be sure */
1da177e4
LT
2817}
2818
e044c39a
TI
2819#ifdef SND_HDA_NEEDS_RESUME
2820static void store_pin_configs(struct hda_codec *codec)
2821{
2822 struct alc_spec *spec = codec->spec;
2823 hda_nid_t nid, end_nid;
2824
2825 end_nid = codec->start_nid + codec->num_nodes;
2826 for (nid = codec->start_nid; nid < end_nid; nid++) {
2827 unsigned int wid_caps = get_wcaps(codec, nid);
2828 unsigned int wid_type =
2829 (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2830 if (wid_type != AC_WID_PIN)
2831 continue;
2832 if (spec->num_pins >= ARRAY_SIZE(spec->pin_nids))
2833 break;
2834 spec->pin_nids[spec->num_pins] = nid;
2835 spec->pin_cfgs[spec->num_pins] =
2836 snd_hda_codec_read(codec, nid, 0,
2837 AC_VERB_GET_CONFIG_DEFAULT, 0);
2838 spec->num_pins++;
2839 }
2840}
2841
2842static void resume_pin_configs(struct hda_codec *codec)
2843{
2844 struct alc_spec *spec = codec->spec;
2845 int i;
2846
2847 for (i = 0; i < spec->num_pins; i++) {
2848 hda_nid_t pin_nid = spec->pin_nids[i];
2849 unsigned int pin_config = spec->pin_cfgs[i];
2850 snd_hda_codec_write(codec, pin_nid, 0,
2851 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
2852 pin_config & 0x000000ff);
2853 snd_hda_codec_write(codec, pin_nid, 0,
2854 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
2855 (pin_config & 0x0000ff00) >> 8);
2856 snd_hda_codec_write(codec, pin_nid, 0,
2857 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
2858 (pin_config & 0x00ff0000) >> 16);
2859 snd_hda_codec_write(codec, pin_nid, 0,
2860 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
2861 pin_config >> 24);
2862 }
2863}
2864
2865static int alc_resume(struct hda_codec *codec)
2866{
2867 resume_pin_configs(codec);
2868 codec->patch_ops.init(codec);
2869 snd_hda_codec_resume_amp(codec);
2870 snd_hda_codec_resume_cache(codec);
2871 return 0;
2872}
2873#else
2874#define store_pin_configs(codec)
2875#endif
2876
1da177e4
LT
2877/*
2878 */
2879static struct hda_codec_ops alc_patch_ops = {
2880 .build_controls = alc_build_controls,
2881 .build_pcms = alc_build_pcms,
2882 .init = alc_init,
2883 .free = alc_free,
ae6b813a 2884 .unsol_event = alc_unsol_event,
e044c39a
TI
2885#ifdef SND_HDA_NEEDS_RESUME
2886 .resume = alc_resume,
2887#endif
cb53c626
TI
2888#ifdef CONFIG_SND_HDA_POWER_SAVE
2889 .check_power_status = alc_check_power_status,
2890#endif
1da177e4
LT
2891};
2892
2fa522be
TI
2893
2894/*
2895 * Test configuration for debugging
2896 *
2897 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2898 * enum controls.
2899 */
2900#ifdef CONFIG_SND_DEBUG
2901static hda_nid_t alc880_test_dac_nids[4] = {
2902 0x02, 0x03, 0x04, 0x05
2903};
2904
2905static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 2906 .num_items = 7,
2fa522be
TI
2907 .items = {
2908 { "In-1", 0x0 },
2909 { "In-2", 0x1 },
2910 { "In-3", 0x2 },
2911 { "In-4", 0x3 },
2912 { "CD", 0x4 },
ae6b813a
TI
2913 { "Front", 0x5 },
2914 { "Surround", 0x6 },
2fa522be
TI
2915 },
2916};
2917
d2a6d7dc 2918static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 2919 { 2, NULL },
fd2c326d 2920 { 4, NULL },
2fa522be 2921 { 6, NULL },
fd2c326d 2922 { 8, NULL },
2fa522be
TI
2923};
2924
9c7f852e
TI
2925static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2926 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
2927{
2928 static char *texts[] = {
2929 "N/A", "Line Out", "HP Out",
2930 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2931 };
2932 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2933 uinfo->count = 1;
2934 uinfo->value.enumerated.items = 8;
2935 if (uinfo->value.enumerated.item >= 8)
2936 uinfo->value.enumerated.item = 7;
2937 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2938 return 0;
2939}
2940
9c7f852e
TI
2941static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2942 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2943{
2944 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2945 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2946 unsigned int pin_ctl, item = 0;
2947
2948 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2949 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2950 if (pin_ctl & AC_PINCTL_OUT_EN) {
2951 if (pin_ctl & AC_PINCTL_HP_EN)
2952 item = 2;
2953 else
2954 item = 1;
2955 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2956 switch (pin_ctl & AC_PINCTL_VREFEN) {
2957 case AC_PINCTL_VREF_HIZ: item = 3; break;
2958 case AC_PINCTL_VREF_50: item = 4; break;
2959 case AC_PINCTL_VREF_GRD: item = 5; break;
2960 case AC_PINCTL_VREF_80: item = 6; break;
2961 case AC_PINCTL_VREF_100: item = 7; break;
2962 }
2963 }
2964 ucontrol->value.enumerated.item[0] = item;
2965 return 0;
2966}
2967
9c7f852e
TI
2968static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2969 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2970{
2971 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2972 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2973 static unsigned int ctls[] = {
2974 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2975 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2976 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2977 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2978 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2979 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2980 };
2981 unsigned int old_ctl, new_ctl;
2982
2983 old_ctl = snd_hda_codec_read(codec, nid, 0,
2984 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2985 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2986 if (old_ctl != new_ctl) {
82beb8fd
TI
2987 int val;
2988 snd_hda_codec_write_cache(codec, nid, 0,
2989 AC_VERB_SET_PIN_WIDGET_CONTROL,
2990 new_ctl);
47fd830a
TI
2991 val = ucontrol->value.enumerated.item[0] >= 3 ?
2992 HDA_AMP_MUTE : 0;
2993 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2994 HDA_AMP_MUTE, val);
2fa522be
TI
2995 return 1;
2996 }
2997 return 0;
2998}
2999
9c7f852e
TI
3000static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3001 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
3002{
3003 static char *texts[] = {
3004 "Front", "Surround", "CLFE", "Side"
3005 };
3006 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3007 uinfo->count = 1;
3008 uinfo->value.enumerated.items = 4;
3009 if (uinfo->value.enumerated.item >= 4)
3010 uinfo->value.enumerated.item = 3;
3011 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3012 return 0;
3013}
3014
9c7f852e
TI
3015static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3016 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3017{
3018 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3019 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3020 unsigned int sel;
3021
3022 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3023 ucontrol->value.enumerated.item[0] = sel & 3;
3024 return 0;
3025}
3026
9c7f852e
TI
3027static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3028 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
3029{
3030 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3031 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3032 unsigned int sel;
3033
3034 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3035 if (ucontrol->value.enumerated.item[0] != sel) {
3036 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
3037 snd_hda_codec_write_cache(codec, nid, 0,
3038 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
3039 return 1;
3040 }
3041 return 0;
3042}
3043
3044#define PIN_CTL_TEST(xname,nid) { \
3045 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3046 .name = xname, \
3047 .info = alc_test_pin_ctl_info, \
3048 .get = alc_test_pin_ctl_get, \
3049 .put = alc_test_pin_ctl_put, \
3050 .private_value = nid \
3051 }
3052
3053#define PIN_SRC_TEST(xname,nid) { \
3054 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3055 .name = xname, \
3056 .info = alc_test_pin_src_info, \
3057 .get = alc_test_pin_src_get, \
3058 .put = alc_test_pin_src_put, \
3059 .private_value = nid \
3060 }
3061
c8b6bf9b 3062static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
3063 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3064 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3065 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3066 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
3067 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3068 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3069 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3070 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
3071 PIN_CTL_TEST("Front Pin Mode", 0x14),
3072 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3073 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3074 PIN_CTL_TEST("Side Pin Mode", 0x17),
3075 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3076 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3077 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3078 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3079 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3080 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3081 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3082 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3083 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3084 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3085 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3086 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3087 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3088 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3089 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3090 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3091 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3092 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
3093 {
3094 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3095 .name = "Channel Mode",
df694daa
KY
3096 .info = alc_ch_mode_info,
3097 .get = alc_ch_mode_get,
3098 .put = alc_ch_mode_put,
2fa522be
TI
3099 },
3100 { } /* end */
3101};
3102
3103static struct hda_verb alc880_test_init_verbs[] = {
3104 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
3105 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3106 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3107 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3108 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3109 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3110 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3111 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3112 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 3113 /* Vol output for 0x0c-0x0f */
05acb863
TI
3114 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3115 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3116 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3117 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 3118 /* Set output pins 0x14-0x17 */
05acb863
TI
3119 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3120 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3121 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3122 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 3123 /* Unmute output pins 0x14-0x17 */
05acb863
TI
3124 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3125 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3126 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3127 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 3128 /* Set input pins 0x18-0x1c */
16ded525
TI
3129 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3130 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
3131 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3132 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3133 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 3134 /* Mute input pins 0x18-0x1b */
05acb863
TI
3135 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3136 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3137 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3138 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 3139 /* ADC set up */
05acb863 3140 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3141 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 3142 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3143 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 3144 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 3145 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
3146 /* Analog input/passthru */
3147 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3148 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3149 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3150 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3151 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
3152 { }
3153};
3154#endif
3155
1da177e4
LT
3156/*
3157 */
3158
f5fcc13c
TI
3159static const char *alc880_models[ALC880_MODEL_LAST] = {
3160 [ALC880_3ST] = "3stack",
3161 [ALC880_TCL_S700] = "tcl",
3162 [ALC880_3ST_DIG] = "3stack-digout",
3163 [ALC880_CLEVO] = "clevo",
3164 [ALC880_5ST] = "5stack",
3165 [ALC880_5ST_DIG] = "5stack-digout",
3166 [ALC880_W810] = "w810",
3167 [ALC880_Z71V] = "z71v",
3168 [ALC880_6ST] = "6stack",
3169 [ALC880_6ST_DIG] = "6stack-digout",
3170 [ALC880_ASUS] = "asus",
3171 [ALC880_ASUS_W1V] = "asus-w1v",
3172 [ALC880_ASUS_DIG] = "asus-dig",
3173 [ALC880_ASUS_DIG2] = "asus-dig2",
3174 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
3175 [ALC880_UNIWILL_P53] = "uniwill-p53",
3176 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
3177 [ALC880_F1734] = "F1734",
3178 [ALC880_LG] = "lg",
3179 [ALC880_LG_LW] = "lg-lw",
df99cd33 3180 [ALC880_MEDION_RIM] = "medion",
2fa522be 3181#ifdef CONFIG_SND_DEBUG
f5fcc13c 3182 [ALC880_TEST] = "test",
2fa522be 3183#endif
f5fcc13c
TI
3184 [ALC880_AUTO] = "auto",
3185};
3186
3187static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 3188 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
3189 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3190 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3191 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3192 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3193 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3194 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3195 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3196 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
3197 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3198 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
3199 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3200 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3201 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3202 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3203 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3204 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3205 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3206 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3207 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3208 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 3209 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
3210 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3211 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3212 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
ac3e3741 3213 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 3214 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
3215 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3216 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
3217 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3218 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
3219 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3220 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3221 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3222 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
3223 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3224 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 3225 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 3226 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 3227 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 3228 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
3229 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3230 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 3231 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 3232 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 3233 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 3234 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 3235 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 3236 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
ac3e3741 3237 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2cf9f0fc 3238 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 3239 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
3240 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3241 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 3242 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
3243 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3244 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3245 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3246 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
3247 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3248 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 3249 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 3250 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
3251 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3252 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
3253 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3254 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3255 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
3256 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3257 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3258 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
3259 {}
3260};
3261
16ded525 3262/*
df694daa 3263 * ALC880 codec presets
16ded525 3264 */
16ded525
TI
3265static struct alc_config_preset alc880_presets[] = {
3266 [ALC880_3ST] = {
e9edcee0 3267 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
3268 .init_verbs = { alc880_volume_init_verbs,
3269 alc880_pin_3stack_init_verbs },
16ded525 3270 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 3271 .dac_nids = alc880_dac_nids,
16ded525
TI
3272 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3273 .channel_mode = alc880_threestack_modes,
4e195a7b 3274 .need_dac_fix = 1,
16ded525
TI
3275 .input_mux = &alc880_capture_source,
3276 },
3277 [ALC880_3ST_DIG] = {
e9edcee0 3278 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
3279 .init_verbs = { alc880_volume_init_verbs,
3280 alc880_pin_3stack_init_verbs },
16ded525 3281 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
3282 .dac_nids = alc880_dac_nids,
3283 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3284 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3285 .channel_mode = alc880_threestack_modes,
4e195a7b 3286 .need_dac_fix = 1,
16ded525
TI
3287 .input_mux = &alc880_capture_source,
3288 },
df694daa
KY
3289 [ALC880_TCL_S700] = {
3290 .mixers = { alc880_tcl_s700_mixer },
3291 .init_verbs = { alc880_volume_init_verbs,
3292 alc880_pin_tcl_S700_init_verbs,
3293 alc880_gpio2_init_verbs },
3294 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3295 .dac_nids = alc880_dac_nids,
3296 .hp_nid = 0x03,
3297 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3298 .channel_mode = alc880_2_jack_modes,
3299 .input_mux = &alc880_capture_source,
3300 },
16ded525 3301 [ALC880_5ST] = {
f12ab1e0
TI
3302 .mixers = { alc880_three_stack_mixer,
3303 alc880_five_stack_mixer},
3304 .init_verbs = { alc880_volume_init_verbs,
3305 alc880_pin_5stack_init_verbs },
16ded525
TI
3306 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3307 .dac_nids = alc880_dac_nids,
16ded525
TI
3308 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3309 .channel_mode = alc880_fivestack_modes,
3310 .input_mux = &alc880_capture_source,
3311 },
3312 [ALC880_5ST_DIG] = {
f12ab1e0
TI
3313 .mixers = { alc880_three_stack_mixer,
3314 alc880_five_stack_mixer },
3315 .init_verbs = { alc880_volume_init_verbs,
3316 alc880_pin_5stack_init_verbs },
16ded525
TI
3317 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3318 .dac_nids = alc880_dac_nids,
3319 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3320 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3321 .channel_mode = alc880_fivestack_modes,
3322 .input_mux = &alc880_capture_source,
3323 },
b6482d48
TI
3324 [ALC880_6ST] = {
3325 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3326 .init_verbs = { alc880_volume_init_verbs,
3327 alc880_pin_6stack_init_verbs },
b6482d48
TI
3328 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3329 .dac_nids = alc880_6st_dac_nids,
3330 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3331 .channel_mode = alc880_sixstack_modes,
3332 .input_mux = &alc880_6stack_capture_source,
3333 },
16ded525 3334 [ALC880_6ST_DIG] = {
e9edcee0 3335 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3336 .init_verbs = { alc880_volume_init_verbs,
3337 alc880_pin_6stack_init_verbs },
16ded525
TI
3338 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3339 .dac_nids = alc880_6st_dac_nids,
3340 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3341 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3342 .channel_mode = alc880_sixstack_modes,
3343 .input_mux = &alc880_6stack_capture_source,
3344 },
3345 [ALC880_W810] = {
e9edcee0 3346 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
3347 .init_verbs = { alc880_volume_init_verbs,
3348 alc880_pin_w810_init_verbs,
b0af0de5 3349 alc880_gpio2_init_verbs },
16ded525
TI
3350 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3351 .dac_nids = alc880_w810_dac_nids,
3352 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3353 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3354 .channel_mode = alc880_w810_modes,
3355 .input_mux = &alc880_capture_source,
3356 },
3357 [ALC880_Z71V] = {
e9edcee0 3358 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
3359 .init_verbs = { alc880_volume_init_verbs,
3360 alc880_pin_z71v_init_verbs },
16ded525
TI
3361 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3362 .dac_nids = alc880_z71v_dac_nids,
3363 .dig_out_nid = ALC880_DIGOUT_NID,
3364 .hp_nid = 0x03,
e9edcee0
TI
3365 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3366 .channel_mode = alc880_2_jack_modes,
16ded525
TI
3367 .input_mux = &alc880_capture_source,
3368 },
3369 [ALC880_F1734] = {
e9edcee0 3370 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
3371 .init_verbs = { alc880_volume_init_verbs,
3372 alc880_pin_f1734_init_verbs },
e9edcee0
TI
3373 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3374 .dac_nids = alc880_f1734_dac_nids,
3375 .hp_nid = 0x02,
3376 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3377 .channel_mode = alc880_2_jack_modes,
937b4160
TI
3378 .input_mux = &alc880_f1734_capture_source,
3379 .unsol_event = alc880_uniwill_p53_unsol_event,
3380 .init_hook = alc880_uniwill_p53_hp_automute,
16ded525
TI
3381 },
3382 [ALC880_ASUS] = {
e9edcee0 3383 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3384 .init_verbs = { alc880_volume_init_verbs,
3385 alc880_pin_asus_init_verbs,
e9edcee0
TI
3386 alc880_gpio1_init_verbs },
3387 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3388 .dac_nids = alc880_asus_dac_nids,
3389 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3390 .channel_mode = alc880_asus_modes,
4e195a7b 3391 .need_dac_fix = 1,
16ded525
TI
3392 .input_mux = &alc880_capture_source,
3393 },
3394 [ALC880_ASUS_DIG] = {
e9edcee0 3395 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3396 .init_verbs = { alc880_volume_init_verbs,
3397 alc880_pin_asus_init_verbs,
e9edcee0
TI
3398 alc880_gpio1_init_verbs },
3399 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3400 .dac_nids = alc880_asus_dac_nids,
16ded525 3401 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3402 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3403 .channel_mode = alc880_asus_modes,
4e195a7b 3404 .need_dac_fix = 1,
16ded525
TI
3405 .input_mux = &alc880_capture_source,
3406 },
df694daa
KY
3407 [ALC880_ASUS_DIG2] = {
3408 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3409 .init_verbs = { alc880_volume_init_verbs,
3410 alc880_pin_asus_init_verbs,
df694daa
KY
3411 alc880_gpio2_init_verbs }, /* use GPIO2 */
3412 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3413 .dac_nids = alc880_asus_dac_nids,
3414 .dig_out_nid = ALC880_DIGOUT_NID,
3415 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3416 .channel_mode = alc880_asus_modes,
4e195a7b 3417 .need_dac_fix = 1,
df694daa
KY
3418 .input_mux = &alc880_capture_source,
3419 },
16ded525 3420 [ALC880_ASUS_W1V] = {
e9edcee0 3421 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
3422 .init_verbs = { alc880_volume_init_verbs,
3423 alc880_pin_asus_init_verbs,
e9edcee0
TI
3424 alc880_gpio1_init_verbs },
3425 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3426 .dac_nids = alc880_asus_dac_nids,
16ded525 3427 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3428 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3429 .channel_mode = alc880_asus_modes,
4e195a7b 3430 .need_dac_fix = 1,
16ded525
TI
3431 .input_mux = &alc880_capture_source,
3432 },
3433 [ALC880_UNIWILL_DIG] = {
3c10a9d9 3434 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
ccc656ce
KY
3435 .init_verbs = { alc880_volume_init_verbs,
3436 alc880_pin_asus_init_verbs },
e9edcee0
TI
3437 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3438 .dac_nids = alc880_asus_dac_nids,
16ded525 3439 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3440 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3441 .channel_mode = alc880_asus_modes,
4e195a7b 3442 .need_dac_fix = 1,
16ded525
TI
3443 .input_mux = &alc880_capture_source,
3444 },
ccc656ce
KY
3445 [ALC880_UNIWILL] = {
3446 .mixers = { alc880_uniwill_mixer },
3447 .init_verbs = { alc880_volume_init_verbs,
3448 alc880_uniwill_init_verbs },
3449 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3450 .dac_nids = alc880_asus_dac_nids,
3451 .dig_out_nid = ALC880_DIGOUT_NID,
3452 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3453 .channel_mode = alc880_threestack_modes,
3454 .need_dac_fix = 1,
3455 .input_mux = &alc880_capture_source,
3456 .unsol_event = alc880_uniwill_unsol_event,
3457 .init_hook = alc880_uniwill_automute,
3458 },
3459 [ALC880_UNIWILL_P53] = {
3460 .mixers = { alc880_uniwill_p53_mixer },
3461 .init_verbs = { alc880_volume_init_verbs,
3462 alc880_uniwill_p53_init_verbs },
3463 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3464 .dac_nids = alc880_asus_dac_nids,
3465 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
3466 .channel_mode = alc880_threestack_modes,
3467 .input_mux = &alc880_capture_source,
3468 .unsol_event = alc880_uniwill_p53_unsol_event,
3469 .init_hook = alc880_uniwill_p53_hp_automute,
3470 },
3471 [ALC880_FUJITSU] = {
f12ab1e0 3472 .mixers = { alc880_fujitsu_mixer,
2cf9f0fc
TD
3473 alc880_pcbeep_mixer, },
3474 .init_verbs = { alc880_volume_init_verbs,
3475 alc880_uniwill_p53_init_verbs,
3476 alc880_beep_init_verbs },
3477 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3478 .dac_nids = alc880_dac_nids,
d53d7d9e 3479 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
3480 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3481 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
3482 .input_mux = &alc880_capture_source,
3483 .unsol_event = alc880_uniwill_p53_unsol_event,
3484 .init_hook = alc880_uniwill_p53_hp_automute,
3485 },
df694daa
KY
3486 [ALC880_CLEVO] = {
3487 .mixers = { alc880_three_stack_mixer },
3488 .init_verbs = { alc880_volume_init_verbs,
3489 alc880_pin_clevo_init_verbs },
3490 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3491 .dac_nids = alc880_dac_nids,
3492 .hp_nid = 0x03,
3493 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3494 .channel_mode = alc880_threestack_modes,
4e195a7b 3495 .need_dac_fix = 1,
df694daa
KY
3496 .input_mux = &alc880_capture_source,
3497 },
ae6b813a
TI
3498 [ALC880_LG] = {
3499 .mixers = { alc880_lg_mixer },
3500 .init_verbs = { alc880_volume_init_verbs,
3501 alc880_lg_init_verbs },
3502 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3503 .dac_nids = alc880_lg_dac_nids,
3504 .dig_out_nid = ALC880_DIGOUT_NID,
3505 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3506 .channel_mode = alc880_lg_ch_modes,
4e195a7b 3507 .need_dac_fix = 1,
ae6b813a
TI
3508 .input_mux = &alc880_lg_capture_source,
3509 .unsol_event = alc880_lg_unsol_event,
3510 .init_hook = alc880_lg_automute,
cb53c626
TI
3511#ifdef CONFIG_SND_HDA_POWER_SAVE
3512 .loopbacks = alc880_lg_loopbacks,
3513#endif
ae6b813a 3514 },
d681518a
TI
3515 [ALC880_LG_LW] = {
3516 .mixers = { alc880_lg_lw_mixer },
3517 .init_verbs = { alc880_volume_init_verbs,
3518 alc880_lg_lw_init_verbs },
0a8c5da3 3519 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
3520 .dac_nids = alc880_dac_nids,
3521 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
3522 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3523 .channel_mode = alc880_lg_lw_modes,
d681518a
TI
3524 .input_mux = &alc880_lg_lw_capture_source,
3525 .unsol_event = alc880_lg_lw_unsol_event,
3526 .init_hook = alc880_lg_lw_automute,
3527 },
df99cd33
TI
3528 [ALC880_MEDION_RIM] = {
3529 .mixers = { alc880_medion_rim_mixer },
3530 .init_verbs = { alc880_volume_init_verbs,
3531 alc880_medion_rim_init_verbs,
3532 alc_gpio2_init_verbs },
3533 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3534 .dac_nids = alc880_dac_nids,
3535 .dig_out_nid = ALC880_DIGOUT_NID,
3536 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3537 .channel_mode = alc880_2_jack_modes,
3538 .input_mux = &alc880_medion_rim_capture_source,
3539 .unsol_event = alc880_medion_rim_unsol_event,
3540 .init_hook = alc880_medion_rim_automute,
3541 },
16ded525
TI
3542#ifdef CONFIG_SND_DEBUG
3543 [ALC880_TEST] = {
e9edcee0
TI
3544 .mixers = { alc880_test_mixer },
3545 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
3546 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3547 .dac_nids = alc880_test_dac_nids,
3548 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3549 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3550 .channel_mode = alc880_test_modes,
3551 .input_mux = &alc880_test_capture_source,
3552 },
3553#endif
3554};
3555
e9edcee0
TI
3556/*
3557 * Automatic parse of I/O pins from the BIOS configuration
3558 */
3559
e9edcee0
TI
3560enum {
3561 ALC_CTL_WIDGET_VOL,
3562 ALC_CTL_WIDGET_MUTE,
3563 ALC_CTL_BIND_MUTE,
3564};
c8b6bf9b 3565static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
3566 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3567 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 3568 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
3569};
3570
3571/* add dynamic controls */
f12ab1e0
TI
3572static int add_control(struct alc_spec *spec, int type, const char *name,
3573 unsigned long val)
e9edcee0 3574{
c8b6bf9b 3575 struct snd_kcontrol_new *knew;
e9edcee0 3576
603c4019
TI
3577 snd_array_init(&spec->kctls, sizeof(*knew), 32);
3578 knew = snd_array_new(&spec->kctls);
3579 if (!knew)
3580 return -ENOMEM;
e9edcee0 3581 *knew = alc880_control_templates[type];
543537bd 3582 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 3583 if (!knew->name)
e9edcee0
TI
3584 return -ENOMEM;
3585 knew->private_value = val;
e9edcee0
TI
3586 return 0;
3587}
3588
3589#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3590#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3591#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3592#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3593#define alc880_is_input_pin(nid) ((nid) >= 0x18)
3594#define alc880_input_pin_idx(nid) ((nid) - 0x18)
3595#define alc880_idx_to_dac(nid) ((nid) + 0x02)
3596#define alc880_dac_to_idx(nid) ((nid) - 0x02)
3597#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3598#define alc880_idx_to_selector(nid) ((nid) + 0x10)
3599#define ALC880_PIN_CD_NID 0x1c
3600
3601/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
3602static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3603 const struct auto_pin_cfg *cfg)
e9edcee0
TI
3604{
3605 hda_nid_t nid;
3606 int assigned[4];
3607 int i, j;
3608
3609 memset(assigned, 0, sizeof(assigned));
b0af0de5 3610 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
3611
3612 /* check the pins hardwired to audio widget */
3613 for (i = 0; i < cfg->line_outs; i++) {
3614 nid = cfg->line_out_pins[i];
3615 if (alc880_is_fixed_pin(nid)) {
3616 int idx = alc880_fixed_pin_idx(nid);
5014f193 3617 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
3618 assigned[idx] = 1;
3619 }
3620 }
3621 /* left pins can be connect to any audio widget */
3622 for (i = 0; i < cfg->line_outs; i++) {
3623 nid = cfg->line_out_pins[i];
3624 if (alc880_is_fixed_pin(nid))
3625 continue;
3626 /* search for an empty channel */
3627 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
3628 if (!assigned[j]) {
3629 spec->multiout.dac_nids[i] =
3630 alc880_idx_to_dac(j);
e9edcee0
TI
3631 assigned[j] = 1;
3632 break;
3633 }
3634 }
3635 }
3636 spec->multiout.num_dacs = cfg->line_outs;
3637 return 0;
3638}
3639
3640/* add playback controls from the parsed DAC table */
df694daa
KY
3641static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3642 const struct auto_pin_cfg *cfg)
e9edcee0
TI
3643{
3644 char name[32];
f12ab1e0
TI
3645 static const char *chname[4] = {
3646 "Front", "Surround", NULL /*CLFE*/, "Side"
3647 };
e9edcee0
TI
3648 hda_nid_t nid;
3649 int i, err;
3650
3651 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 3652 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
3653 continue;
3654 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3655 if (i == 2) {
3656 /* Center/LFE */
f12ab1e0
TI
3657 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3658 "Center Playback Volume",
3659 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3660 HDA_OUTPUT));
3661 if (err < 0)
e9edcee0 3662 return err;
f12ab1e0
TI
3663 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3664 "LFE Playback Volume",
3665 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3666 HDA_OUTPUT));
3667 if (err < 0)
e9edcee0 3668 return err;
f12ab1e0
TI
3669 err = add_control(spec, ALC_CTL_BIND_MUTE,
3670 "Center Playback Switch",
3671 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3672 HDA_INPUT));
3673 if (err < 0)
e9edcee0 3674 return err;
f12ab1e0
TI
3675 err = add_control(spec, ALC_CTL_BIND_MUTE,
3676 "LFE Playback Switch",
3677 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3678 HDA_INPUT));
3679 if (err < 0)
e9edcee0
TI
3680 return err;
3681 } else {
3682 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
3683 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3684 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3685 HDA_OUTPUT));
3686 if (err < 0)
e9edcee0
TI
3687 return err;
3688 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0
TI
3689 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3690 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3691 HDA_INPUT));
3692 if (err < 0)
e9edcee0
TI
3693 return err;
3694 }
3695 }
e9edcee0
TI
3696 return 0;
3697}
3698
8d88bc3d
TI
3699/* add playback controls for speaker and HP outputs */
3700static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3701 const char *pfx)
e9edcee0
TI
3702{
3703 hda_nid_t nid;
3704 int err;
8d88bc3d 3705 char name[32];
e9edcee0 3706
f12ab1e0 3707 if (!pin)
e9edcee0
TI
3708 return 0;
3709
3710 if (alc880_is_fixed_pin(pin)) {
3711 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 3712 /* specify the DAC as the extra output */
f12ab1e0 3713 if (!spec->multiout.hp_nid)
e9edcee0 3714 spec->multiout.hp_nid = nid;
82bc955f
TI
3715 else
3716 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
3717 /* control HP volume/switch on the output mixer amp */
3718 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
8d88bc3d 3719 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
3720 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3721 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3722 if (err < 0)
e9edcee0 3723 return err;
8d88bc3d 3724 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
3725 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3726 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3727 if (err < 0)
e9edcee0
TI
3728 return err;
3729 } else if (alc880_is_multi_pin(pin)) {
3730 /* set manual connection */
e9edcee0 3731 /* we have only a switch on HP-out PIN */
8d88bc3d 3732 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
3733 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3734 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3735 if (err < 0)
e9edcee0
TI
3736 return err;
3737 }
3738 return 0;
3739}
3740
3741/* create input playback/capture controls for the given pin */
f12ab1e0
TI
3742static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3743 const char *ctlname,
df694daa 3744 int idx, hda_nid_t mix_nid)
e9edcee0
TI
3745{
3746 char name[32];
df694daa 3747 int err;
e9edcee0
TI
3748
3749 sprintf(name, "%s Playback Volume", ctlname);
f12ab1e0
TI
3750 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3751 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3752 if (err < 0)
e9edcee0
TI
3753 return err;
3754 sprintf(name, "%s Playback Switch", ctlname);
f12ab1e0
TI
3755 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3756 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3757 if (err < 0)
e9edcee0
TI
3758 return err;
3759 return 0;
3760}
3761
3762/* create playback/capture controls for input pins */
df694daa
KY
3763static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3764 const struct auto_pin_cfg *cfg)
e9edcee0 3765{
e9edcee0 3766 struct hda_input_mux *imux = &spec->private_imux;
df694daa 3767 int i, err, idx;
e9edcee0
TI
3768
3769 for (i = 0; i < AUTO_PIN_LAST; i++) {
3770 if (alc880_is_input_pin(cfg->input_pins[i])) {
df694daa 3771 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4a471b7d
TI
3772 err = new_analog_input(spec, cfg->input_pins[i],
3773 auto_pin_cfg_labels[i],
df694daa 3774 idx, 0x0b);
e9edcee0
TI
3775 if (err < 0)
3776 return err;
f12ab1e0
TI
3777 imux->items[imux->num_items].label =
3778 auto_pin_cfg_labels[i];
3779 imux->items[imux->num_items].index =
3780 alc880_input_pin_idx(cfg->input_pins[i]);
e9edcee0
TI
3781 imux->num_items++;
3782 }
3783 }
3784 return 0;
3785}
3786
f6c7e546
TI
3787static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3788 unsigned int pin_type)
3789{
3790 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3791 pin_type);
3792 /* unmute pin */
d260cdf6
TI
3793 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3794 AMP_OUT_UNMUTE);
f6c7e546
TI
3795}
3796
df694daa
KY
3797static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3798 hda_nid_t nid, int pin_type,
e9edcee0
TI
3799 int dac_idx)
3800{
f6c7e546 3801 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
3802 /* need the manual connection? */
3803 if (alc880_is_multi_pin(nid)) {
3804 struct alc_spec *spec = codec->spec;
3805 int idx = alc880_multi_pin_idx(nid);
3806 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3807 AC_VERB_SET_CONNECT_SEL,
3808 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3809 }
3810}
3811
baba8ee9
TI
3812static int get_pin_type(int line_out_type)
3813{
3814 if (line_out_type == AUTO_PIN_HP_OUT)
3815 return PIN_HP;
3816 else
3817 return PIN_OUT;
3818}
3819
e9edcee0
TI
3820static void alc880_auto_init_multi_out(struct hda_codec *codec)
3821{
3822 struct alc_spec *spec = codec->spec;
3823 int i;
ea1fb29a 3824
bc9f98a9 3825 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
e9edcee0
TI
3826 for (i = 0; i < spec->autocfg.line_outs; i++) {
3827 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
3828 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3829 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
3830 }
3831}
3832
8d88bc3d 3833static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
3834{
3835 struct alc_spec *spec = codec->spec;
3836 hda_nid_t pin;
3837
82bc955f 3838 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
3839 if (pin) /* connect to front */
3840 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 3841 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
3842 if (pin) /* connect to front */
3843 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3844}
3845
3846static void alc880_auto_init_analog_input(struct hda_codec *codec)
3847{
3848 struct alc_spec *spec = codec->spec;
3849 int i;
3850
3851 for (i = 0; i < AUTO_PIN_LAST; i++) {
3852 hda_nid_t nid = spec->autocfg.input_pins[i];
3853 if (alc880_is_input_pin(nid)) {
f12ab1e0
TI
3854 snd_hda_codec_write(codec, nid, 0,
3855 AC_VERB_SET_PIN_WIDGET_CONTROL,
3856 i <= AUTO_PIN_FRONT_MIC ?
3857 PIN_VREF80 : PIN_IN);
e9edcee0 3858 if (nid != ALC880_PIN_CD_NID)
f12ab1e0
TI
3859 snd_hda_codec_write(codec, nid, 0,
3860 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
3861 AMP_OUT_MUTE);
3862 }
3863 }
3864}
3865
3866/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
3867/* return 1 if successful, 0 if the proper config is not found,
3868 * or a negative error code
3869 */
e9edcee0
TI
3870static int alc880_parse_auto_config(struct hda_codec *codec)
3871{
3872 struct alc_spec *spec = codec->spec;
3873 int err;
df694daa 3874 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 3875
f12ab1e0
TI
3876 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3877 alc880_ignore);
3878 if (err < 0)
e9edcee0 3879 return err;
f12ab1e0 3880 if (!spec->autocfg.line_outs)
e9edcee0 3881 return 0; /* can't find valid BIOS pin config */
df694daa 3882
f12ab1e0
TI
3883 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3884 if (err < 0)
3885 return err;
3886 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3887 if (err < 0)
3888 return err;
3889 err = alc880_auto_create_extra_out(spec,
3890 spec->autocfg.speaker_pins[0],
3891 "Speaker");
3892 if (err < 0)
3893 return err;
3894 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3895 "Headphone");
3896 if (err < 0)
3897 return err;
3898 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3899 if (err < 0)
e9edcee0
TI
3900 return err;
3901
3902 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3903
3904 if (spec->autocfg.dig_out_pin)
3905 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3906 if (spec->autocfg.dig_in_pin)
3907 spec->dig_in_nid = ALC880_DIGIN_NID;
3908
603c4019 3909 if (spec->kctls.list)
d88897ea 3910 add_mixer(spec, spec->kctls.list);
e9edcee0 3911
d88897ea 3912 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 3913
a1e8d2da 3914 spec->num_mux_defs = 1;
e9edcee0
TI
3915 spec->input_mux = &spec->private_imux;
3916
e044c39a 3917 store_pin_configs(codec);
e9edcee0
TI
3918 return 1;
3919}
3920
ae6b813a
TI
3921/* additional initialization for auto-configuration model */
3922static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 3923{
f6c7e546 3924 struct alc_spec *spec = codec->spec;
e9edcee0 3925 alc880_auto_init_multi_out(codec);
8d88bc3d 3926 alc880_auto_init_extra_out(codec);
e9edcee0 3927 alc880_auto_init_analog_input(codec);
f6c7e546 3928 if (spec->unsol_event)
7fb0d78f 3929 alc_inithook(codec);
e9edcee0
TI
3930}
3931
3932/*
3933 * OK, here we have finally the patch for ALC880
3934 */
3935
1da177e4
LT
3936static int patch_alc880(struct hda_codec *codec)
3937{
3938 struct alc_spec *spec;
3939 int board_config;
df694daa 3940 int err;
1da177e4 3941
e560d8d8 3942 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
3943 if (spec == NULL)
3944 return -ENOMEM;
3945
3946 codec->spec = spec;
3947
f5fcc13c
TI
3948 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3949 alc880_models,
3950 alc880_cfg_tbl);
3951 if (board_config < 0) {
9c7f852e
TI
3952 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3953 "trying auto-probe from BIOS...\n");
e9edcee0 3954 board_config = ALC880_AUTO;
1da177e4 3955 }
1da177e4 3956
e9edcee0
TI
3957 if (board_config == ALC880_AUTO) {
3958 /* automatic parse from the BIOS config */
3959 err = alc880_parse_auto_config(codec);
3960 if (err < 0) {
3961 alc_free(codec);
3962 return err;
f12ab1e0 3963 } else if (!err) {
9c7f852e
TI
3964 printk(KERN_INFO
3965 "hda_codec: Cannot set up configuration "
3966 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
3967 board_config = ALC880_3ST;
3968 }
1da177e4
LT
3969 }
3970
df694daa
KY
3971 if (board_config != ALC880_AUTO)
3972 setup_preset(spec, &alc880_presets[board_config]);
1da177e4
LT
3973
3974 spec->stream_name_analog = "ALC880 Analog";
3975 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3976 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 3977 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4
LT
3978
3979 spec->stream_name_digital = "ALC880 Digital";
3980 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3981 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3982
f12ab1e0 3983 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 3984 /* check whether NID 0x07 is valid */
54d17403 3985 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0
TI
3986 /* get type */
3987 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
e9edcee0
TI
3988 if (wcap != AC_WID_AUD_IN) {
3989 spec->adc_nids = alc880_adc_nids_alt;
3990 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
d88897ea 3991 add_mixer(spec, alc880_capture_alt_mixer);
e9edcee0
TI
3992 } else {
3993 spec->adc_nids = alc880_adc_nids;
3994 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
d88897ea 3995 add_mixer(spec, alc880_capture_mixer);
e9edcee0
TI
3996 }
3997 }
1da177e4 3998
2134ea4f
TI
3999 spec->vmaster_nid = 0x0c;
4000
1da177e4 4001 codec->patch_ops = alc_patch_ops;
e9edcee0 4002 if (board_config == ALC880_AUTO)
ae6b813a 4003 spec->init_hook = alc880_auto_init;
cb53c626
TI
4004#ifdef CONFIG_SND_HDA_POWER_SAVE
4005 if (!spec->loopback.amplist)
4006 spec->loopback.amplist = alc880_loopbacks;
4007#endif
1da177e4
LT
4008
4009 return 0;
4010}
4011
e9edcee0 4012
1da177e4
LT
4013/*
4014 * ALC260 support
4015 */
4016
e9edcee0
TI
4017static hda_nid_t alc260_dac_nids[1] = {
4018 /* front */
4019 0x02,
4020};
4021
4022static hda_nid_t alc260_adc_nids[1] = {
4023 /* ADC0 */
4024 0x04,
4025};
4026
df694daa 4027static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
4028 /* ADC1 */
4029 0x05,
4030};
4031
df694daa
KY
4032static hda_nid_t alc260_hp_adc_nids[2] = {
4033 /* ADC1, 0 */
4034 0x05, 0x04
4035};
4036
d57fdac0
JW
4037/* NIDs used when simultaneous access to both ADCs makes sense. Note that
4038 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4039 */
4040static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
4041 /* ADC0, ADC1 */
4042 0x04, 0x05
4043};
4044
e9edcee0
TI
4045#define ALC260_DIGOUT_NID 0x03
4046#define ALC260_DIGIN_NID 0x06
4047
4048static struct hda_input_mux alc260_capture_source = {
4049 .num_items = 4,
4050 .items = {
4051 { "Mic", 0x0 },
4052 { "Front Mic", 0x1 },
4053 { "Line", 0x2 },
4054 { "CD", 0x4 },
4055 },
4056};
4057
17e7aec6 4058/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
4059 * headphone jack and the internal CD lines since these are the only pins at
4060 * which audio can appear. For flexibility, also allow the option of
4061 * recording the mixer output on the second ADC (ADC0 doesn't have a
4062 * connection to the mixer output).
a9430dd8 4063 */
a1e8d2da
JW
4064static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4065 {
4066 .num_items = 3,
4067 .items = {
4068 { "Mic/Line", 0x0 },
4069 { "CD", 0x4 },
4070 { "Headphone", 0x2 },
4071 },
a9430dd8 4072 },
a1e8d2da
JW
4073 {
4074 .num_items = 4,
4075 .items = {
4076 { "Mic/Line", 0x0 },
4077 { "CD", 0x4 },
4078 { "Headphone", 0x2 },
4079 { "Mixer", 0x5 },
4080 },
4081 },
4082
a9430dd8
JW
4083};
4084
a1e8d2da
JW
4085/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4086 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 4087 */
a1e8d2da
JW
4088static struct hda_input_mux alc260_acer_capture_sources[2] = {
4089 {
4090 .num_items = 4,
4091 .items = {
4092 { "Mic", 0x0 },
4093 { "Line", 0x2 },
4094 { "CD", 0x4 },
4095 { "Headphone", 0x5 },
4096 },
4097 },
4098 {
4099 .num_items = 5,
4100 .items = {
4101 { "Mic", 0x0 },
4102 { "Line", 0x2 },
4103 { "CD", 0x4 },
4104 { "Headphone", 0x6 },
4105 { "Mixer", 0x5 },
4106 },
0bfc90e9
JW
4107 },
4108};
1da177e4
LT
4109/*
4110 * This is just place-holder, so there's something for alc_build_pcms to look
4111 * at when it calculates the maximum number of channels. ALC260 has no mixer
4112 * element which allows changing the channel mode, so the verb list is
4113 * never used.
4114 */
d2a6d7dc 4115static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
4116 { 2, NULL },
4117};
4118
df694daa
KY
4119
4120/* Mixer combinations
4121 *
4122 * basic: base_output + input + pc_beep + capture
4123 * HP: base_output + input + capture_alt
4124 * HP_3013: hp_3013 + input + capture
4125 * fujitsu: fujitsu + capture
0bfc90e9 4126 * acer: acer + capture
df694daa
KY
4127 */
4128
4129static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 4130 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 4131 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 4132 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 4133 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 4134 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 4135 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 4136 { } /* end */
f12ab1e0 4137};
1da177e4 4138
df694daa 4139static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
4140 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4141 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4142 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4143 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4144 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4145 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4146 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4147 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
4148 { } /* end */
4149};
4150
4151static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
4152 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
4153 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
4154 { } /* end */
4155};
4156
bec15c3a
TI
4157/* update HP, line and mono out pins according to the master switch */
4158static void alc260_hp_master_update(struct hda_codec *codec,
4159 hda_nid_t hp, hda_nid_t line,
4160 hda_nid_t mono)
4161{
4162 struct alc_spec *spec = codec->spec;
4163 unsigned int val = spec->master_sw ? PIN_HP : 0;
4164 /* change HP and line-out pins */
4165 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4166 val);
4167 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4168 val);
4169 /* mono (speaker) depending on the HP jack sense */
4170 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4171 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4172 val);
4173}
4174
4175static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4176 struct snd_ctl_elem_value *ucontrol)
4177{
4178 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4179 struct alc_spec *spec = codec->spec;
4180 *ucontrol->value.integer.value = spec->master_sw;
4181 return 0;
4182}
4183
4184static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4185 struct snd_ctl_elem_value *ucontrol)
4186{
4187 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4188 struct alc_spec *spec = codec->spec;
4189 int val = !!*ucontrol->value.integer.value;
4190 hda_nid_t hp, line, mono;
4191
4192 if (val == spec->master_sw)
4193 return 0;
4194 spec->master_sw = val;
4195 hp = (kcontrol->private_value >> 16) & 0xff;
4196 line = (kcontrol->private_value >> 8) & 0xff;
4197 mono = kcontrol->private_value & 0xff;
4198 alc260_hp_master_update(codec, hp, line, mono);
4199 return 1;
4200}
4201
4202static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4203 {
4204 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4205 .name = "Master Playback Switch",
4206 .info = snd_ctl_boolean_mono_info,
4207 .get = alc260_hp_master_sw_get,
4208 .put = alc260_hp_master_sw_put,
4209 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4210 },
4211 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4212 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4213 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4214 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4215 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4216 HDA_OUTPUT),
4217 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4218 { } /* end */
4219};
4220
4221static struct hda_verb alc260_hp_unsol_verbs[] = {
4222 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4223 {},
4224};
4225
4226static void alc260_hp_automute(struct hda_codec *codec)
4227{
4228 struct alc_spec *spec = codec->spec;
4229 unsigned int present;
4230
4231 present = snd_hda_codec_read(codec, 0x10, 0,
4232 AC_VERB_GET_PIN_SENSE, 0);
4233 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4234 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4235}
4236
4237static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4238{
4239 if ((res >> 26) == ALC880_HP_EVENT)
4240 alc260_hp_automute(codec);
4241}
4242
df694daa 4243static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
4244 {
4245 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4246 .name = "Master Playback Switch",
4247 .info = snd_ctl_boolean_mono_info,
4248 .get = alc260_hp_master_sw_get,
4249 .put = alc260_hp_master_sw_put,
4250 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
4251 },
df694daa
KY
4252 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4253 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4254 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4255 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4256 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4257 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
4258 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4259 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
4260 { } /* end */
4261};
4262
3f878308
KY
4263static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4264 .ops = &snd_hda_bind_vol,
4265 .values = {
4266 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4267 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4268 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4269 0
4270 },
4271};
4272
4273static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4274 .ops = &snd_hda_bind_sw,
4275 .values = {
4276 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4277 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4278 0
4279 },
4280};
4281
4282static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4283 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4284 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4285 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4286 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4287 { } /* end */
4288};
4289
bec15c3a
TI
4290static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4291 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4292 {},
4293};
4294
4295static void alc260_hp_3013_automute(struct hda_codec *codec)
4296{
4297 struct alc_spec *spec = codec->spec;
4298 unsigned int present;
4299
4300 present = snd_hda_codec_read(codec, 0x15, 0,
4301 AC_VERB_GET_PIN_SENSE, 0);
4302 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4303 alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
4304}
4305
4306static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4307 unsigned int res)
4308{
4309 if ((res >> 26) == ALC880_HP_EVENT)
4310 alc260_hp_3013_automute(codec);
4311}
4312
3f878308
KY
4313static void alc260_hp_3012_automute(struct hda_codec *codec)
4314{
4315 unsigned int present, bits;
4316
4317 present = snd_hda_codec_read(codec, 0x10, 0,
4318 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4319
4320 bits = present ? 0 : PIN_OUT;
4321 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4322 bits);
4323 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4324 bits);
4325 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4326 bits);
4327}
4328
4329static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4330 unsigned int res)
4331{
4332 if ((res >> 26) == ALC880_HP_EVENT)
4333 alc260_hp_3012_automute(codec);
4334}
4335
4336/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
4337 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4338 */
c8b6bf9b 4339static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 4340 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 4341 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 4342 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
4343 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4344 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4345 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4346 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 4347 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
a9430dd8
JW
4348 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4349 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
31bffaa9
TI
4350 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4351 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
4352 { } /* end */
4353};
4354
a1e8d2da
JW
4355/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4356 * versions of the ALC260 don't act on requests to enable mic bias from NID
4357 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4358 * datasheet doesn't mention this restriction. At this stage it's not clear
4359 * whether this behaviour is intentional or is a hardware bug in chip
4360 * revisions available in early 2006. Therefore for now allow the
4361 * "Headphone Jack Mode" control to span all choices, but if it turns out
4362 * that the lack of mic bias for this NID is intentional we could change the
4363 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4364 *
4365 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4366 * don't appear to make the mic bias available from the "line" jack, even
4367 * though the NID used for this jack (0x14) can supply it. The theory is
4368 * that perhaps Acer have included blocking capacitors between the ALC260
4369 * and the output jack. If this turns out to be the case for all such
4370 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4371 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
4372 *
4373 * The C20x Tablet series have a mono internal speaker which is controlled
4374 * via the chip's Mono sum widget and pin complex, so include the necessary
4375 * controls for such models. On models without a "mono speaker" the control
4376 * won't do anything.
a1e8d2da 4377 */
0bfc90e9
JW
4378static struct snd_kcontrol_new alc260_acer_mixer[] = {
4379 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4380 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 4381 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 4382 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 4383 HDA_OUTPUT),
31bffaa9 4384 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 4385 HDA_INPUT),
0bfc90e9
JW
4386 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4387 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4388 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4389 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4390 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4391 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4392 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4393 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4394 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4395 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4396 { } /* end */
4397};
4398
bc9f98a9
KY
4399/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4400 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4401 */
4402static struct snd_kcontrol_new alc260_will_mixer[] = {
4403 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4404 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4405 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4406 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4407 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4408 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4409 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4410 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4411 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4412 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4413 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4414 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4415 { } /* end */
4416};
4417
4418/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4419 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4420 */
4421static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4422 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4423 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4424 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4425 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4426 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4427 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4428 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4429 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4430 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4431 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4432 { } /* end */
4433};
4434
df694daa
KY
4435/* capture mixer elements */
4436static struct snd_kcontrol_new alc260_capture_mixer[] = {
a9430dd8
JW
4437 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4438 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
df694daa
KY
4439 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4440 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
a9430dd8
JW
4441 {
4442 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
df694daa
KY
4443 /* The multiple "Capture Source" controls confuse alsamixer
4444 * So call somewhat different..
df694daa
KY
4445 */
4446 /* .name = "Capture Source", */
4447 .name = "Input Source",
4448 .count = 2,
4449 .info = alc_mux_enum_info,
4450 .get = alc_mux_enum_get,
4451 .put = alc_mux_enum_put,
4452 },
4453 { } /* end */
4454};
4455
4456static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4457 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4458 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4459 {
4460 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4461 /* The multiple "Capture Source" controls confuse alsamixer
4462 * So call somewhat different..
df694daa
KY
4463 */
4464 /* .name = "Capture Source", */
4465 .name = "Input Source",
4466 .count = 1,
a9430dd8
JW
4467 .info = alc_mux_enum_info,
4468 .get = alc_mux_enum_get,
4469 .put = alc_mux_enum_put,
4470 },
4471 { } /* end */
4472};
4473
df694daa
KY
4474/*
4475 * initialization verbs
4476 */
1da177e4
LT
4477static struct hda_verb alc260_init_verbs[] = {
4478 /* Line In pin widget for input */
05acb863 4479 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 4480 /* CD pin widget for input */
05acb863 4481 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 4482 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 4483 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 4484 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 4485 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 4486 /* LINE-2 is used for line-out in rear */
05acb863 4487 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 4488 /* select line-out */
fd56f2db 4489 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 4490 /* LINE-OUT pin */
05acb863 4491 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 4492 /* enable HP */
05acb863 4493 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 4494 /* enable Mono */
05acb863
TI
4495 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4496 /* mute capture amp left and right */
16ded525 4497 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
4498 /* set connection select to line in (default select for this ADC) */
4499 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
4500 /* mute capture amp left and right */
4501 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4502 /* set connection select to line in (default select for this ADC) */
4503 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
4504 /* set vol=0 Line-Out mixer amp left and right */
4505 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4506 /* unmute pin widget amp left and right (no gain on this amp) */
4507 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4508 /* set vol=0 HP mixer amp left and right */
4509 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4510 /* unmute pin widget amp left and right (no gain on this amp) */
4511 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4512 /* set vol=0 Mono mixer amp left and right */
4513 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4514 /* unmute pin widget amp left and right (no gain on this amp) */
4515 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4516 /* unmute LINE-2 out pin */
4517 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
4518 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4519 * Line In 2 = 0x03
4520 */
cb53c626
TI
4521 /* mute analog inputs */
4522 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4523 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4524 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4525 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4526 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 4527 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
4528 /* mute Front out path */
4529 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4530 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4531 /* mute Headphone out path */
4532 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4533 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4534 /* mute Mono out path */
4535 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4536 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
4537 { }
4538};
4539
474167d6 4540#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
4541static struct hda_verb alc260_hp_init_verbs[] = {
4542 /* Headphone and output */
4543 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4544 /* mono output */
4545 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4546 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4547 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4548 /* Mic2 (front panel) pin widget for input and vref at 80% */
4549 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4550 /* Line In pin widget for input */
4551 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4552 /* Line-2 pin widget for output */
4553 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4554 /* CD pin widget for input */
4555 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4556 /* unmute amp left and right */
4557 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4558 /* set connection select to line in (default select for this ADC) */
4559 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4560 /* unmute Line-Out mixer amp left and right (volume = 0) */
4561 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4562 /* mute pin widget amp left and right (no gain on this amp) */
4563 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4564 /* unmute HP mixer amp left and right (volume = 0) */
4565 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4566 /* mute pin widget amp left and right (no gain on this amp) */
4567 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
4568 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4569 * Line In 2 = 0x03
4570 */
cb53c626
TI
4571 /* mute analog inputs */
4572 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4573 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4574 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4575 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4576 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4577 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4578 /* Unmute Front out path */
4579 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4580 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4581 /* Unmute Headphone out path */
4582 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4583 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4584 /* Unmute Mono out path */
4585 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4586 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4587 { }
4588};
474167d6 4589#endif
df694daa
KY
4590
4591static struct hda_verb alc260_hp_3013_init_verbs[] = {
4592 /* Line out and output */
4593 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4594 /* mono output */
4595 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4596 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4597 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4598 /* Mic2 (front panel) pin widget for input and vref at 80% */
4599 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4600 /* Line In pin widget for input */
4601 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4602 /* Headphone pin widget for output */
4603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4604 /* CD pin widget for input */
4605 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4606 /* unmute amp left and right */
4607 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4608 /* set connection select to line in (default select for this ADC) */
4609 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4610 /* unmute Line-Out mixer amp left and right (volume = 0) */
4611 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4612 /* mute pin widget amp left and right (no gain on this amp) */
4613 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4614 /* unmute HP mixer amp left and right (volume = 0) */
4615 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4616 /* mute pin widget amp left and right (no gain on this amp) */
4617 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
4618 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4619 * Line In 2 = 0x03
4620 */
cb53c626
TI
4621 /* mute analog inputs */
4622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4623 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4624 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4625 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4626 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4627 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4628 /* Unmute Front out path */
4629 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4630 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4631 /* Unmute Headphone out path */
4632 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4633 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4634 /* Unmute Mono out path */
4635 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4636 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4637 { }
4638};
4639
a9430dd8 4640/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
4641 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4642 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
4643 */
4644static struct hda_verb alc260_fujitsu_init_verbs[] = {
4645 /* Disable all GPIOs */
4646 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4647 /* Internal speaker is connected to headphone pin */
4648 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4649 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4650 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
4651 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4652 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4653 /* Ensure all other unused pins are disabled and muted. */
4654 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4655 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 4656 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 4657 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 4658 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
4659 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4660 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4661 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4662
4663 /* Disable digital (SPDIF) pins */
4664 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4665 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 4666
ea1fb29a 4667 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
4668 * when acting as an output.
4669 */
4670 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 4671
f7ace40d 4672 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
4673 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4674 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4675 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4676 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4677 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4678 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4679 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4680 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4681 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 4682
f7ace40d
JW
4683 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4684 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4685 /* Unmute Line1 pin widget output buffer since it starts as an output.
4686 * If the pin mode is changed by the user the pin mode control will
4687 * take care of enabling the pin's input/output buffers as needed.
4688 * Therefore there's no need to enable the input buffer at this
4689 * stage.
cdcd9268 4690 */
f7ace40d 4691 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 4692 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
4693 * mixer ctrl)
4694 */
f7ace40d
JW
4695 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4696
4697 /* Mute capture amp left and right */
4698 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 4699 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
4700 * in (on mic1 pin)
4701 */
4702 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4703
4704 /* Do the same for the second ADC: mute capture input amp and
4705 * set ADC connection to line in (on mic1 pin)
4706 */
4707 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4708 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4709
4710 /* Mute all inputs to mixer widget (even unconnected ones) */
4711 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4712 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4713 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4714 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4715 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4716 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4717 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4718 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
4719
4720 { }
a9430dd8
JW
4721};
4722
0bfc90e9
JW
4723/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4724 * similar laptops (adapted from Fujitsu init verbs).
4725 */
4726static struct hda_verb alc260_acer_init_verbs[] = {
4727 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4728 * the headphone jack. Turn this on and rely on the standard mute
4729 * methods whenever the user wants to turn these outputs off.
4730 */
4731 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4732 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4733 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4734 /* Internal speaker/Headphone jack is connected to Line-out pin */
4735 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4736 /* Internal microphone/Mic jack is connected to Mic1 pin */
4737 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4738 /* Line In jack is connected to Line1 pin */
4739 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
4740 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4741 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
4742 /* Ensure all other unused pins are disabled and muted. */
4743 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4744 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
4745 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4746 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4747 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4748 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4749 /* Disable digital (SPDIF) pins */
4750 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4751 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4752
ea1fb29a 4753 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
4754 * bus when acting as outputs.
4755 */
4756 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4757 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4758
4759 /* Start with output sum widgets muted and their output gains at min */
4760 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4761 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4762 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4763 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4764 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4765 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4766 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4767 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4768 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4769
f12ab1e0
TI
4770 /* Unmute Line-out pin widget amp left and right
4771 * (no equiv mixer ctrl)
4772 */
0bfc90e9 4773 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
4774 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4775 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
4776 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4777 * inputs. If the pin mode is changed by the user the pin mode control
4778 * will take care of enabling the pin's input/output buffers as needed.
4779 * Therefore there's no need to enable the input buffer at this
4780 * stage.
4781 */
4782 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4783 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4784
4785 /* Mute capture amp left and right */
4786 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4787 /* Set ADC connection select to match default mixer setting - mic
4788 * (on mic1 pin)
4789 */
4790 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4791
4792 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 4793 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
4794 */
4795 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 4796 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
4797
4798 /* Mute all inputs to mixer widget (even unconnected ones) */
4799 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4800 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4801 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4802 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4803 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4804 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4805 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4806 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4807
4808 { }
4809};
4810
bc9f98a9
KY
4811static struct hda_verb alc260_will_verbs[] = {
4812 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4813 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4814 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4815 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4816 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4817 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4818 {}
4819};
4820
4821static struct hda_verb alc260_replacer_672v_verbs[] = {
4822 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4823 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4824 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4825
4826 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4827 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4828 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4829
4830 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4831 {}
4832};
4833
4834/* toggle speaker-output according to the hp-jack state */
4835static void alc260_replacer_672v_automute(struct hda_codec *codec)
4836{
4837 unsigned int present;
4838
4839 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4840 present = snd_hda_codec_read(codec, 0x0f, 0,
4841 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4842 if (present) {
82beb8fd
TI
4843 snd_hda_codec_write_cache(codec, 0x01, 0,
4844 AC_VERB_SET_GPIO_DATA, 1);
4845 snd_hda_codec_write_cache(codec, 0x0f, 0,
4846 AC_VERB_SET_PIN_WIDGET_CONTROL,
4847 PIN_HP);
bc9f98a9 4848 } else {
82beb8fd
TI
4849 snd_hda_codec_write_cache(codec, 0x01, 0,
4850 AC_VERB_SET_GPIO_DATA, 0);
4851 snd_hda_codec_write_cache(codec, 0x0f, 0,
4852 AC_VERB_SET_PIN_WIDGET_CONTROL,
4853 PIN_OUT);
bc9f98a9
KY
4854 }
4855}
4856
4857static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4858 unsigned int res)
4859{
4860 if ((res >> 26) == ALC880_HP_EVENT)
4861 alc260_replacer_672v_automute(codec);
4862}
4863
3f878308
KY
4864static struct hda_verb alc260_hp_dc7600_verbs[] = {
4865 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
4866 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4867 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4868 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4869 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4870 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4871 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4872 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4873 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4874 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4875 {}
4876};
4877
7cf51e48
JW
4878/* Test configuration for debugging, modelled after the ALC880 test
4879 * configuration.
4880 */
4881#ifdef CONFIG_SND_DEBUG
4882static hda_nid_t alc260_test_dac_nids[1] = {
4883 0x02,
4884};
4885static hda_nid_t alc260_test_adc_nids[2] = {
4886 0x04, 0x05,
4887};
a1e8d2da 4888/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 4889 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 4890 * is NID 0x04.
17e7aec6 4891 */
a1e8d2da
JW
4892static struct hda_input_mux alc260_test_capture_sources[2] = {
4893 {
4894 .num_items = 7,
4895 .items = {
4896 { "MIC1 pin", 0x0 },
4897 { "MIC2 pin", 0x1 },
4898 { "LINE1 pin", 0x2 },
4899 { "LINE2 pin", 0x3 },
4900 { "CD pin", 0x4 },
4901 { "LINE-OUT pin", 0x5 },
4902 { "HP-OUT pin", 0x6 },
4903 },
4904 },
4905 {
4906 .num_items = 8,
4907 .items = {
4908 { "MIC1 pin", 0x0 },
4909 { "MIC2 pin", 0x1 },
4910 { "LINE1 pin", 0x2 },
4911 { "LINE2 pin", 0x3 },
4912 { "CD pin", 0x4 },
4913 { "Mixer", 0x5 },
4914 { "LINE-OUT pin", 0x6 },
4915 { "HP-OUT pin", 0x7 },
4916 },
7cf51e48
JW
4917 },
4918};
4919static struct snd_kcontrol_new alc260_test_mixer[] = {
4920 /* Output driver widgets */
4921 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4922 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4923 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4924 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4925 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4926 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4927
a1e8d2da
JW
4928 /* Modes for retasking pin widgets
4929 * Note: the ALC260 doesn't seem to act on requests to enable mic
4930 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4931 * mention this restriction. At this stage it's not clear whether
4932 * this behaviour is intentional or is a hardware bug in chip
4933 * revisions available at least up until early 2006. Therefore for
4934 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4935 * choices, but if it turns out that the lack of mic bias for these
4936 * NIDs is intentional we could change their modes from
4937 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4938 */
7cf51e48
JW
4939 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4940 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4941 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4942 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4943 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4944 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4945
4946 /* Loopback mixer controls */
4947 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4948 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4949 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4950 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4951 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4952 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4953 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4954 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4955 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4956 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4957 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4958 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4959 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4960 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4961 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4962 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
4963
4964 /* Controls for GPIO pins, assuming they are configured as outputs */
4965 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4966 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4967 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4968 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4969
92621f13
JW
4970 /* Switches to allow the digital IO pins to be enabled. The datasheet
4971 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 4972 * make this output available should provide clarification.
92621f13
JW
4973 */
4974 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4975 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4976
f8225f6d
JW
4977 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4978 * this output to turn on an external amplifier.
4979 */
4980 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4981 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4982
7cf51e48
JW
4983 { } /* end */
4984};
4985static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
4986 /* Enable all GPIOs as outputs with an initial value of 0 */
4987 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4988 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4989 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4990
7cf51e48
JW
4991 /* Enable retasking pins as output, initially without power amp */
4992 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4993 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4994 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4995 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4996 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4997 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4998
92621f13
JW
4999 /* Disable digital (SPDIF) pins initially, but users can enable
5000 * them via a mixer switch. In the case of SPDIF-out, this initverb
5001 * payload also sets the generation to 0, output to be in "consumer"
5002 * PCM format, copyright asserted, no pre-emphasis and no validity
5003 * control.
5004 */
7cf51e48
JW
5005 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5006 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5007
ea1fb29a 5008 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
5009 * OUT1 sum bus when acting as an output.
5010 */
5011 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5012 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5013 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5014 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5015
5016 /* Start with output sum widgets muted and their output gains at min */
5017 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5018 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5019 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5020 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5021 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5022 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5023 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5024 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5025 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5026
cdcd9268
JW
5027 /* Unmute retasking pin widget output buffers since the default
5028 * state appears to be output. As the pin mode is changed by the
5029 * user the pin mode control will take care of enabling the pin's
5030 * input/output buffers as needed.
5031 */
7cf51e48
JW
5032 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5033 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5034 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5035 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5036 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5037 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5038 /* Also unmute the mono-out pin widget */
5039 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5040
7cf51e48
JW
5041 /* Mute capture amp left and right */
5042 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
5043 /* Set ADC connection select to match default mixer setting (mic1
5044 * pin)
7cf51e48
JW
5045 */
5046 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5047
5048 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 5049 * set ADC connection to mic1 pin
7cf51e48
JW
5050 */
5051 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5052 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5053
5054 /* Mute all inputs to mixer widget (even unconnected ones) */
5055 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5056 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5057 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5058 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5059 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5060 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5061 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5062 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5063
5064 { }
5065};
5066#endif
5067
6330079f
TI
5068#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5069#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 5070
a3bcba38
TI
5071#define alc260_pcm_digital_playback alc880_pcm_digital_playback
5072#define alc260_pcm_digital_capture alc880_pcm_digital_capture
5073
df694daa
KY
5074/*
5075 * for BIOS auto-configuration
5076 */
16ded525 5077
df694daa 5078static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 5079 const char *pfx, int *vol_bits)
df694daa
KY
5080{
5081 hda_nid_t nid_vol;
5082 unsigned long vol_val, sw_val;
5083 char name[32];
5084 int err;
5085
5086 if (nid >= 0x0f && nid < 0x11) {
5087 nid_vol = nid - 0x7;
5088 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5089 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5090 } else if (nid == 0x11) {
5091 nid_vol = nid - 0x7;
5092 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5093 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5094 } else if (nid >= 0x12 && nid <= 0x15) {
5095 nid_vol = 0x08;
5096 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5097 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5098 } else
5099 return 0; /* N/A */
ea1fb29a 5100
863b4518
TI
5101 if (!(*vol_bits & (1 << nid_vol))) {
5102 /* first control for the volume widget */
5103 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5104 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5105 if (err < 0)
5106 return err;
5107 *vol_bits |= (1 << nid_vol);
5108 }
df694daa 5109 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
f12ab1e0
TI
5110 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5111 if (err < 0)
df694daa
KY
5112 return err;
5113 return 1;
5114}
5115
5116/* add playback controls from the parsed DAC table */
5117static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5118 const struct auto_pin_cfg *cfg)
5119{
5120 hda_nid_t nid;
5121 int err;
863b4518 5122 int vols = 0;
df694daa
KY
5123
5124 spec->multiout.num_dacs = 1;
5125 spec->multiout.dac_nids = spec->private_dac_nids;
5126 spec->multiout.dac_nids[0] = 0x02;
5127
5128 nid = cfg->line_out_pins[0];
5129 if (nid) {
863b4518 5130 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
df694daa
KY
5131 if (err < 0)
5132 return err;
5133 }
5134
82bc955f 5135 nid = cfg->speaker_pins[0];
df694daa 5136 if (nid) {
863b4518 5137 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
5138 if (err < 0)
5139 return err;
5140 }
5141
eb06ed8f 5142 nid = cfg->hp_pins[0];
df694daa 5143 if (nid) {
863b4518
TI
5144 err = alc260_add_playback_controls(spec, nid, "Headphone",
5145 &vols);
df694daa
KY
5146 if (err < 0)
5147 return err;
5148 }
f12ab1e0 5149 return 0;
df694daa
KY
5150}
5151
5152/* create playback/capture controls for input pins */
5153static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5154 const struct auto_pin_cfg *cfg)
5155{
df694daa
KY
5156 struct hda_input_mux *imux = &spec->private_imux;
5157 int i, err, idx;
5158
5159 for (i = 0; i < AUTO_PIN_LAST; i++) {
5160 if (cfg->input_pins[i] >= 0x12) {
5161 idx = cfg->input_pins[i] - 0x12;
4a471b7d 5162 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
5163 auto_pin_cfg_labels[i], idx,
5164 0x07);
df694daa
KY
5165 if (err < 0)
5166 return err;
f12ab1e0
TI
5167 imux->items[imux->num_items].label =
5168 auto_pin_cfg_labels[i];
df694daa
KY
5169 imux->items[imux->num_items].index = idx;
5170 imux->num_items++;
5171 }
f12ab1e0 5172 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
df694daa 5173 idx = cfg->input_pins[i] - 0x09;
4a471b7d 5174 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
5175 auto_pin_cfg_labels[i], idx,
5176 0x07);
df694daa
KY
5177 if (err < 0)
5178 return err;
f12ab1e0
TI
5179 imux->items[imux->num_items].label =
5180 auto_pin_cfg_labels[i];
df694daa
KY
5181 imux->items[imux->num_items].index = idx;
5182 imux->num_items++;
5183 }
5184 }
5185 return 0;
5186}
5187
5188static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5189 hda_nid_t nid, int pin_type,
5190 int sel_idx)
5191{
f6c7e546 5192 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
5193 /* need the manual connection? */
5194 if (nid >= 0x12) {
5195 int idx = nid - 0x12;
5196 snd_hda_codec_write(codec, idx + 0x0b, 0,
5197 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
5198 }
5199}
5200
5201static void alc260_auto_init_multi_out(struct hda_codec *codec)
5202{
5203 struct alc_spec *spec = codec->spec;
5204 hda_nid_t nid;
5205
bc9f98a9 5206 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
f12ab1e0 5207 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
5208 if (nid) {
5209 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5210 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5211 }
ea1fb29a 5212
82bc955f 5213 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
5214 if (nid)
5215 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5216
eb06ed8f 5217 nid = spec->autocfg.hp_pins[0];
df694daa 5218 if (nid)
baba8ee9 5219 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 5220}
df694daa
KY
5221
5222#define ALC260_PIN_CD_NID 0x16
5223static void alc260_auto_init_analog_input(struct hda_codec *codec)
5224{
5225 struct alc_spec *spec = codec->spec;
5226 int i;
5227
5228 for (i = 0; i < AUTO_PIN_LAST; i++) {
5229 hda_nid_t nid = spec->autocfg.input_pins[i];
5230 if (nid >= 0x12) {
f12ab1e0
TI
5231 snd_hda_codec_write(codec, nid, 0,
5232 AC_VERB_SET_PIN_WIDGET_CONTROL,
5233 i <= AUTO_PIN_FRONT_MIC ?
5234 PIN_VREF80 : PIN_IN);
df694daa 5235 if (nid != ALC260_PIN_CD_NID)
f12ab1e0
TI
5236 snd_hda_codec_write(codec, nid, 0,
5237 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
5238 AMP_OUT_MUTE);
5239 }
5240 }
5241}
5242
5243/*
5244 * generic initialization of ADC, input mixers and output mixers
5245 */
5246static struct hda_verb alc260_volume_init_verbs[] = {
5247 /*
5248 * Unmute ADC0-1 and set the default input to mic-in
5249 */
5250 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5251 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5252 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5253 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 5254
df694daa
KY
5255 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5256 * mixer widget
f12ab1e0
TI
5257 * Note: PASD motherboards uses the Line In 2 as the input for
5258 * front panel mic (mic 2)
df694daa
KY
5259 */
5260 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
5261 /* mute analog inputs */
5262 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5263 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5264 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5265 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5266 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
5267
5268 /*
5269 * Set up output mixers (0x08 - 0x0a)
5270 */
5271 /* set vol=0 to output mixers */
5272 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5273 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5274 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5275 /* set up input amps for analog loopback */
5276 /* Amp Indices: DAC = 0, mixer = 1 */
5277 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5278 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5279 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5280 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5281 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5282 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 5283
df694daa
KY
5284 { }
5285};
5286
5287static int alc260_parse_auto_config(struct hda_codec *codec)
5288{
5289 struct alc_spec *spec = codec->spec;
5290 unsigned int wcap;
5291 int err;
5292 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5293
f12ab1e0
TI
5294 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5295 alc260_ignore);
5296 if (err < 0)
df694daa 5297 return err;
f12ab1e0
TI
5298 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5299 if (err < 0)
4a471b7d 5300 return err;
603c4019 5301 if (!spec->kctls.list)
df694daa 5302 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
5303 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5304 if (err < 0)
df694daa
KY
5305 return err;
5306
5307 spec->multiout.max_channels = 2;
5308
5309 if (spec->autocfg.dig_out_pin)
5310 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 5311 if (spec->kctls.list)
d88897ea 5312 add_mixer(spec, spec->kctls.list);
df694daa 5313
d88897ea 5314 add_verb(spec, alc260_volume_init_verbs);
df694daa 5315
a1e8d2da 5316 spec->num_mux_defs = 1;
df694daa
KY
5317 spec->input_mux = &spec->private_imux;
5318
5319 /* check whether NID 0x04 is valid */
4a471b7d 5320 wcap = get_wcaps(codec, 0x04);
df694daa 5321 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
67ebcb03 5322 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
df694daa
KY
5323 spec->adc_nids = alc260_adc_nids_alt;
5324 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
d88897ea 5325 add_mixer(spec, alc260_capture_alt_mixer);
df694daa
KY
5326 } else {
5327 spec->adc_nids = alc260_adc_nids;
5328 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
d88897ea 5329 add_mixer(spec, alc260_capture_mixer);
df694daa
KY
5330 }
5331
e044c39a 5332 store_pin_configs(codec);
df694daa
KY
5333 return 1;
5334}
5335
ae6b813a
TI
5336/* additional initialization for auto-configuration model */
5337static void alc260_auto_init(struct hda_codec *codec)
df694daa 5338{
f6c7e546 5339 struct alc_spec *spec = codec->spec;
df694daa
KY
5340 alc260_auto_init_multi_out(codec);
5341 alc260_auto_init_analog_input(codec);
f6c7e546 5342 if (spec->unsol_event)
7fb0d78f 5343 alc_inithook(codec);
df694daa
KY
5344}
5345
cb53c626
TI
5346#ifdef CONFIG_SND_HDA_POWER_SAVE
5347static struct hda_amp_list alc260_loopbacks[] = {
5348 { 0x07, HDA_INPUT, 0 },
5349 { 0x07, HDA_INPUT, 1 },
5350 { 0x07, HDA_INPUT, 2 },
5351 { 0x07, HDA_INPUT, 3 },
5352 { 0x07, HDA_INPUT, 4 },
5353 { } /* end */
5354};
5355#endif
5356
df694daa
KY
5357/*
5358 * ALC260 configurations
5359 */
f5fcc13c
TI
5360static const char *alc260_models[ALC260_MODEL_LAST] = {
5361 [ALC260_BASIC] = "basic",
5362 [ALC260_HP] = "hp",
5363 [ALC260_HP_3013] = "hp-3013",
2922c9af 5364 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
5365 [ALC260_FUJITSU_S702X] = "fujitsu",
5366 [ALC260_ACER] = "acer",
bc9f98a9
KY
5367 [ALC260_WILL] = "will",
5368 [ALC260_REPLACER_672V] = "replacer",
7cf51e48 5369#ifdef CONFIG_SND_DEBUG
f5fcc13c 5370 [ALC260_TEST] = "test",
7cf51e48 5371#endif
f5fcc13c
TI
5372 [ALC260_AUTO] = "auto",
5373};
5374
5375static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 5376 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
f5fcc13c 5377 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
9720b718 5378 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
a8a5d067 5379 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
f5fcc13c 5380 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 5381 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 5382 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
5383 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5384 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5385 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5386 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5387 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5388 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5389 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5390 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5391 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 5392 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 5393 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
5394 {}
5395};
5396
5397static struct alc_config_preset alc260_presets[] = {
5398 [ALC260_BASIC] = {
5399 .mixers = { alc260_base_output_mixer,
5400 alc260_input_mixer,
5401 alc260_pc_beep_mixer,
5402 alc260_capture_mixer },
5403 .init_verbs = { alc260_init_verbs },
5404 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5405 .dac_nids = alc260_dac_nids,
5406 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5407 .adc_nids = alc260_adc_nids,
5408 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5409 .channel_mode = alc260_modes,
5410 .input_mux = &alc260_capture_source,
5411 },
5412 [ALC260_HP] = {
bec15c3a 5413 .mixers = { alc260_hp_output_mixer,
df694daa
KY
5414 alc260_input_mixer,
5415 alc260_capture_alt_mixer },
bec15c3a
TI
5416 .init_verbs = { alc260_init_verbs,
5417 alc260_hp_unsol_verbs },
df694daa
KY
5418 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5419 .dac_nids = alc260_dac_nids,
5420 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5421 .adc_nids = alc260_hp_adc_nids,
5422 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5423 .channel_mode = alc260_modes,
5424 .input_mux = &alc260_capture_source,
bec15c3a
TI
5425 .unsol_event = alc260_hp_unsol_event,
5426 .init_hook = alc260_hp_automute,
df694daa 5427 },
3f878308
KY
5428 [ALC260_HP_DC7600] = {
5429 .mixers = { alc260_hp_dc7600_mixer,
5430 alc260_input_mixer,
5431 alc260_capture_alt_mixer },
5432 .init_verbs = { alc260_init_verbs,
5433 alc260_hp_dc7600_verbs },
5434 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5435 .dac_nids = alc260_dac_nids,
5436 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5437 .adc_nids = alc260_hp_adc_nids,
5438 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5439 .channel_mode = alc260_modes,
5440 .input_mux = &alc260_capture_source,
5441 .unsol_event = alc260_hp_3012_unsol_event,
5442 .init_hook = alc260_hp_3012_automute,
5443 },
df694daa
KY
5444 [ALC260_HP_3013] = {
5445 .mixers = { alc260_hp_3013_mixer,
5446 alc260_input_mixer,
5447 alc260_capture_alt_mixer },
bec15c3a
TI
5448 .init_verbs = { alc260_hp_3013_init_verbs,
5449 alc260_hp_3013_unsol_verbs },
df694daa
KY
5450 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5451 .dac_nids = alc260_dac_nids,
5452 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5453 .adc_nids = alc260_hp_adc_nids,
5454 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5455 .channel_mode = alc260_modes,
5456 .input_mux = &alc260_capture_source,
bec15c3a
TI
5457 .unsol_event = alc260_hp_3013_unsol_event,
5458 .init_hook = alc260_hp_3013_automute,
df694daa
KY
5459 },
5460 [ALC260_FUJITSU_S702X] = {
5461 .mixers = { alc260_fujitsu_mixer,
5462 alc260_capture_mixer },
5463 .init_verbs = { alc260_fujitsu_init_verbs },
5464 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5465 .dac_nids = alc260_dac_nids,
d57fdac0
JW
5466 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5467 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
5468 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5469 .channel_mode = alc260_modes,
a1e8d2da
JW
5470 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5471 .input_mux = alc260_fujitsu_capture_sources,
df694daa 5472 },
0bfc90e9
JW
5473 [ALC260_ACER] = {
5474 .mixers = { alc260_acer_mixer,
5475 alc260_capture_mixer },
5476 .init_verbs = { alc260_acer_init_verbs },
5477 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5478 .dac_nids = alc260_dac_nids,
5479 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5480 .adc_nids = alc260_dual_adc_nids,
5481 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5482 .channel_mode = alc260_modes,
a1e8d2da
JW
5483 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5484 .input_mux = alc260_acer_capture_sources,
0bfc90e9 5485 },
bc9f98a9
KY
5486 [ALC260_WILL] = {
5487 .mixers = { alc260_will_mixer,
5488 alc260_capture_mixer },
5489 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5490 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5491 .dac_nids = alc260_dac_nids,
5492 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5493 .adc_nids = alc260_adc_nids,
5494 .dig_out_nid = ALC260_DIGOUT_NID,
5495 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5496 .channel_mode = alc260_modes,
5497 .input_mux = &alc260_capture_source,
5498 },
5499 [ALC260_REPLACER_672V] = {
5500 .mixers = { alc260_replacer_672v_mixer,
5501 alc260_capture_mixer },
5502 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5503 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5504 .dac_nids = alc260_dac_nids,
5505 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5506 .adc_nids = alc260_adc_nids,
5507 .dig_out_nid = ALC260_DIGOUT_NID,
5508 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5509 .channel_mode = alc260_modes,
5510 .input_mux = &alc260_capture_source,
5511 .unsol_event = alc260_replacer_672v_unsol_event,
5512 .init_hook = alc260_replacer_672v_automute,
5513 },
7cf51e48
JW
5514#ifdef CONFIG_SND_DEBUG
5515 [ALC260_TEST] = {
5516 .mixers = { alc260_test_mixer,
5517 alc260_capture_mixer },
5518 .init_verbs = { alc260_test_init_verbs },
5519 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5520 .dac_nids = alc260_test_dac_nids,
5521 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5522 .adc_nids = alc260_test_adc_nids,
5523 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5524 .channel_mode = alc260_modes,
a1e8d2da
JW
5525 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5526 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
5527 },
5528#endif
df694daa
KY
5529};
5530
5531static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
5532{
5533 struct alc_spec *spec;
df694daa 5534 int err, board_config;
1da177e4 5535
e560d8d8 5536 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5537 if (spec == NULL)
5538 return -ENOMEM;
5539
5540 codec->spec = spec;
5541
f5fcc13c
TI
5542 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5543 alc260_models,
5544 alc260_cfg_tbl);
5545 if (board_config < 0) {
9c7f852e
TI
5546 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5547 "trying auto-probe from BIOS...\n");
df694daa 5548 board_config = ALC260_AUTO;
16ded525 5549 }
1da177e4 5550
df694daa
KY
5551 if (board_config == ALC260_AUTO) {
5552 /* automatic parse from the BIOS config */
5553 err = alc260_parse_auto_config(codec);
5554 if (err < 0) {
5555 alc_free(codec);
5556 return err;
f12ab1e0 5557 } else if (!err) {
9c7f852e
TI
5558 printk(KERN_INFO
5559 "hda_codec: Cannot set up configuration "
5560 "from BIOS. Using base mode...\n");
df694daa
KY
5561 board_config = ALC260_BASIC;
5562 }
a9430dd8 5563 }
e9edcee0 5564
df694daa
KY
5565 if (board_config != ALC260_AUTO)
5566 setup_preset(spec, &alc260_presets[board_config]);
1da177e4
LT
5567
5568 spec->stream_name_analog = "ALC260 Analog";
5569 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5570 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5571
a3bcba38
TI
5572 spec->stream_name_digital = "ALC260 Digital";
5573 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5574 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5575
2134ea4f
TI
5576 spec->vmaster_nid = 0x08;
5577
1da177e4 5578 codec->patch_ops = alc_patch_ops;
df694daa 5579 if (board_config == ALC260_AUTO)
ae6b813a 5580 spec->init_hook = alc260_auto_init;
cb53c626
TI
5581#ifdef CONFIG_SND_HDA_POWER_SAVE
5582 if (!spec->loopback.amplist)
5583 spec->loopback.amplist = alc260_loopbacks;
5584#endif
1da177e4
LT
5585
5586 return 0;
5587}
5588
e9edcee0 5589
1da177e4
LT
5590/*
5591 * ALC882 support
5592 *
5593 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5594 * configuration. Each pin widget can choose any input DACs and a mixer.
5595 * Each ADC is connected from a mixer of all inputs. This makes possible
5596 * 6-channel independent captures.
5597 *
5598 * In addition, an independent DAC for the multi-playback (not used in this
5599 * driver yet).
5600 */
df694daa
KY
5601#define ALC882_DIGOUT_NID 0x06
5602#define ALC882_DIGIN_NID 0x0a
1da177e4 5603
d2a6d7dc 5604static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
5605 { 8, NULL }
5606};
5607
5608static hda_nid_t alc882_dac_nids[4] = {
5609 /* front, rear, clfe, rear_surr */
5610 0x02, 0x03, 0x04, 0x05
5611};
5612
df694daa
KY
5613/* identical with ALC880 */
5614#define alc882_adc_nids alc880_adc_nids
5615#define alc882_adc_nids_alt alc880_adc_nids_alt
1da177e4 5616
e1406348
TI
5617static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5618static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5619
1da177e4
LT
5620/* input MUX */
5621/* FIXME: should be a matrix-type input source selection */
5622
5623static struct hda_input_mux alc882_capture_source = {
5624 .num_items = 4,
5625 .items = {
5626 { "Mic", 0x0 },
5627 { "Front Mic", 0x1 },
5628 { "Line", 0x2 },
5629 { "CD", 0x4 },
5630 },
5631};
1da177e4
LT
5632#define alc882_mux_enum_info alc_mux_enum_info
5633#define alc882_mux_enum_get alc_mux_enum_get
5634
f12ab1e0
TI
5635static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5636 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
5637{
5638 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5639 struct alc_spec *spec = codec->spec;
5640 const struct hda_input_mux *imux = spec->input_mux;
5641 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
88c71a99
TI
5642 hda_nid_t nid = spec->capsrc_nids ?
5643 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
1da177e4
LT
5644 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5645 unsigned int i, idx;
5646
5647 idx = ucontrol->value.enumerated.item[0];
5648 if (idx >= imux->num_items)
5649 idx = imux->num_items - 1;
82beb8fd 5650 if (*cur_val == idx)
1da177e4
LT
5651 return 0;
5652 for (i = 0; i < imux->num_items; i++) {
47fd830a
TI
5653 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5654 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
82beb8fd 5655 imux->items[i].index,
47fd830a 5656 HDA_AMP_MUTE, v);
1da177e4
LT
5657 }
5658 *cur_val = idx;
5659 return 1;
5660}
5661
272a527c
KY
5662/*
5663 * 2ch mode
5664 */
5665static struct hda_verb alc882_3ST_ch2_init[] = {
5666 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5667 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5668 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5669 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5670 { } /* end */
5671};
5672
5673/*
5674 * 6ch mode
5675 */
5676static struct hda_verb alc882_3ST_ch6_init[] = {
5677 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5678 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5679 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5680 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5681 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5682 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5683 { } /* end */
5684};
5685
5686static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5687 { 2, alc882_3ST_ch2_init },
5688 { 6, alc882_3ST_ch6_init },
5689};
5690
df694daa
KY
5691/*
5692 * 6ch mode
5693 */
5694static struct hda_verb alc882_sixstack_ch6_init[] = {
5695 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5696 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5697 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5698 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5699 { } /* end */
5700};
5701
5702/*
5703 * 8ch mode
5704 */
5705static struct hda_verb alc882_sixstack_ch8_init[] = {
5706 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5707 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5708 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5709 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5710 { } /* end */
5711};
5712
5713static struct hda_channel_mode alc882_sixstack_modes[2] = {
5714 { 6, alc882_sixstack_ch6_init },
5715 { 8, alc882_sixstack_ch8_init },
5716};
5717
87350ad0
TI
5718/*
5719 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5720 */
5721
5722/*
5723 * 2ch mode
5724 */
5725static struct hda_verb alc885_mbp_ch2_init[] = {
5726 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5727 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5728 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5729 { } /* end */
5730};
5731
5732/*
5733 * 6ch mode
5734 */
5735static struct hda_verb alc885_mbp_ch6_init[] = {
5736 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5737 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5738 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5739 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5740 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5741 { } /* end */
5742};
5743
5744static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5745 { 2, alc885_mbp_ch2_init },
5746 { 6, alc885_mbp_ch6_init },
5747};
5748
5749
1da177e4
LT
5750/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5751 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5752 */
c8b6bf9b 5753static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 5754 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 5755 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 5756 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 5757 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
5758 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5759 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
5760 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5761 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 5762 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 5763 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
5764 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5765 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5766 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5767 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5768 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5769 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 5770 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
5771 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5772 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 5773 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4
LT
5774 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5775 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5776 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1da177e4
LT
5777 { } /* end */
5778};
5779
87350ad0 5780static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
2134ea4f
TI
5781 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5782 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5783 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5784 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5785 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5786 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
5787 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5788 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 5789 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
5790 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5791 { } /* end */
5792};
bdd148a3
KY
5793static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5794 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5795 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5796 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5797 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5798 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5799 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5800 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5801 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5802 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5803 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5804 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5805 { } /* end */
5806};
5807
272a527c
KY
5808static struct snd_kcontrol_new alc882_targa_mixer[] = {
5809 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5810 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5811 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5812 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5813 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5814 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5815 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5816 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5817 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 5818 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
5819 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5820 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 5821 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
5822 { } /* end */
5823};
5824
5825/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5826 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5827 */
5828static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5829 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5830 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5831 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5832 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5833 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5834 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5835 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5836 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5837 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5838 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5839 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5840 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 5841 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
5842 { } /* end */
5843};
5844
914759b7
TI
5845static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5846 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5847 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5848 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5849 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5850 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5851 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5852 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5853 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5854 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5855 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5856 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5857 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5858 { } /* end */
5859};
5860
df694daa
KY
5861static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5862 {
5863 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5864 .name = "Channel Mode",
5865 .info = alc_ch_mode_info,
5866 .get = alc_ch_mode_get,
5867 .put = alc_ch_mode_put,
5868 },
5869 { } /* end */
5870};
5871
1da177e4
LT
5872static struct hda_verb alc882_init_verbs[] = {
5873 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
5874 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5875 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5876 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5877 /* Rear mixer */
05acb863
TI
5878 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5879 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5880 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5881 /* CLFE mixer */
05acb863
TI
5882 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5883 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5884 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5885 /* Side mixer */
05acb863
TI
5886 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5887 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5888 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5889
e9edcee0 5890 /* Front Pin: output 0 (0x0c) */
05acb863 5891 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5892 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5893 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 5894 /* Rear Pin: output 1 (0x0d) */
05acb863 5895 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5896 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5897 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 5898 /* CLFE Pin: output 2 (0x0e) */
05acb863 5899 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5900 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5901 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 5902 /* Side Pin: output 3 (0x0f) */
05acb863 5903 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5904 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5905 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 5906 /* Mic (rear) pin: input vref at 80% */
16ded525 5907 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
5908 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5909 /* Front Mic pin: input vref at 80% */
16ded525 5910 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
5911 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5912 /* Line In pin: input */
05acb863 5913 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
5914 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5915 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5916 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5917 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5918 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5919 /* CD pin widget for input */
05acb863 5920 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
5921
5922 /* FIXME: use matrix-type input source selection */
5923 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5924 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
05acb863
TI
5925 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5926 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5927 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5928 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5929 /* Input mixer2 */
05acb863
TI
5930 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5931 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5932 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5933 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5934 /* Input mixer3 */
05acb863
TI
5935 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5936 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5937 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5938 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5939 /* ADC1: mute amp left and right */
5940 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5941 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
5942 /* ADC2: mute amp left and right */
5943 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5944 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
5945 /* ADC3: mute amp left and right */
5946 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5947 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
5948
5949 { }
5950};
5951
4b146cb0
TI
5952static struct hda_verb alc882_eapd_verbs[] = {
5953 /* change to EAPD mode */
5954 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 5955 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 5956 { }
4b146cb0
TI
5957};
5958
9102cd1c
TD
5959/* Mac Pro test */
5960static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5961 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5962 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5963 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5964 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5965 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5966 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5967 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5968 { } /* end */
5969};
5970
5971static struct hda_verb alc882_macpro_init_verbs[] = {
5972 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5973 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5974 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5975 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5976 /* Front Pin: output 0 (0x0c) */
5977 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5978 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5979 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5980 /* Front Mic pin: input vref at 80% */
5981 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5982 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5983 /* Speaker: output */
5984 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5985 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5986 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5987 /* Headphone output (output 0 - 0x0c) */
5988 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5989 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5990 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5991
5992 /* FIXME: use matrix-type input source selection */
5993 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5994 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5995 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5996 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5997 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5998 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5999 /* Input mixer2 */
6000 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6001 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6002 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6003 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6004 /* Input mixer3 */
6005 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6006 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6007 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6008 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6009 /* ADC1: mute amp left and right */
6010 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6011 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6012 /* ADC2: mute amp left and right */
6013 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6014 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6015 /* ADC3: mute amp left and right */
6016 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6017 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6018
6019 { }
6020};
f12ab1e0 6021
87350ad0
TI
6022/* Macbook Pro rev3 */
6023static struct hda_verb alc885_mbp3_init_verbs[] = {
6024 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6026 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6027 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6028 /* Rear mixer */
6029 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6030 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6031 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6032 /* Front Pin: output 0 (0x0c) */
6033 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6034 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6035 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6036 /* HP Pin: output 0 (0x0d) */
6037 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6038 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6039 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6040 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6041 /* Mic (rear) pin: input vref at 80% */
6042 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6043 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6044 /* Front Mic pin: input vref at 80% */
6045 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6046 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6047 /* Line In pin: use output 1 when in LineOut mode */
6048 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6049 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6050 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6051
6052 /* FIXME: use matrix-type input source selection */
6053 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6054 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6055 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6056 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6057 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6058 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6059 /* Input mixer2 */
6060 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6061 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6062 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6063 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6064 /* Input mixer3 */
6065 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6066 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6067 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6068 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6069 /* ADC1: mute amp left and right */
6070 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6071 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6072 /* ADC2: mute amp left and right */
6073 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6074 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6075 /* ADC3: mute amp left and right */
6076 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6077 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6078
6079 { }
6080};
6081
c54728d8
NF
6082/* iMac 24 mixer. */
6083static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6084 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6085 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6086 { } /* end */
6087};
6088
6089/* iMac 24 init verbs. */
6090static struct hda_verb alc885_imac24_init_verbs[] = {
6091 /* Internal speakers: output 0 (0x0c) */
6092 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6093 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6094 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6095 /* Internal speakers: output 0 (0x0c) */
6096 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6097 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6098 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6099 /* Headphone: output 0 (0x0c) */
6100 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6101 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6102 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6103 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6104 /* Front Mic: input vref at 80% */
6105 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6106 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6107 { }
6108};
6109
6110/* Toggle speaker-output according to the hp-jack state */
6111static void alc885_imac24_automute(struct hda_codec *codec)
6112{
6113 unsigned int present;
6114
6115 present = snd_hda_codec_read(codec, 0x14, 0,
6116 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
6117 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
6118 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6119 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
6120 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
c54728d8
NF
6121}
6122
6123/* Processes unsolicited events. */
6124static void alc885_imac24_unsol_event(struct hda_codec *codec,
6125 unsigned int res)
6126{
6127 /* Headphone insertion or removal. */
6128 if ((res >> 26) == ALC880_HP_EVENT)
6129 alc885_imac24_automute(codec);
6130}
6131
87350ad0
TI
6132static void alc885_mbp3_automute(struct hda_codec *codec)
6133{
6134 unsigned int present;
6135
6136 present = snd_hda_codec_read(codec, 0x15, 0,
6137 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6138 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6139 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6140 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6141 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6142
6143}
6144static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6145 unsigned int res)
6146{
6147 /* Headphone insertion or removal. */
6148 if ((res >> 26) == ALC880_HP_EVENT)
6149 alc885_mbp3_automute(codec);
6150}
6151
6152
272a527c
KY
6153static struct hda_verb alc882_targa_verbs[] = {
6154 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6155 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6156
6157 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6158 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 6159
272a527c
KY
6160 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6161 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6162 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6163
6164 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6165 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6166 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6167 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6168 { } /* end */
6169};
6170
6171/* toggle speaker-output according to the hp-jack state */
6172static void alc882_targa_automute(struct hda_codec *codec)
6173{
6174 unsigned int present;
ea1fb29a 6175
272a527c
KY
6176 present = snd_hda_codec_read(codec, 0x14, 0,
6177 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
6178 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6179 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
82beb8fd
TI
6180 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6181 present ? 1 : 3);
272a527c
KY
6182}
6183
6184static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6185{
6186 /* Looks like the unsol event is incompatible with the standard
6187 * definition. 4bit tag is placed at 26 bit!
6188 */
6189 if (((res >> 26) == ALC880_HP_EVENT)) {
6190 alc882_targa_automute(codec);
6191 }
6192}
6193
6194static struct hda_verb alc882_asus_a7j_verbs[] = {
6195 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6196 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6197
6198 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6199 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6200 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 6201
272a527c
KY
6202 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6203 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6204 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6205
6206 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6207 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6208 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6209 { } /* end */
6210};
6211
914759b7
TI
6212static struct hda_verb alc882_asus_a7m_verbs[] = {
6213 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6214 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6215
6216 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6217 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6218 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 6219
914759b7
TI
6220 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6221 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6222 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6223
6224 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6225 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6226 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6227 { } /* end */
6228};
6229
9102cd1c
TD
6230static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6231{
6232 unsigned int gpiostate, gpiomask, gpiodir;
6233
6234 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6235 AC_VERB_GET_GPIO_DATA, 0);
6236
6237 if (!muted)
6238 gpiostate |= (1 << pin);
6239 else
6240 gpiostate &= ~(1 << pin);
6241
6242 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6243 AC_VERB_GET_GPIO_MASK, 0);
6244 gpiomask |= (1 << pin);
6245
6246 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6247 AC_VERB_GET_GPIO_DIRECTION, 0);
6248 gpiodir |= (1 << pin);
6249
6250
6251 snd_hda_codec_write(codec, codec->afg, 0,
6252 AC_VERB_SET_GPIO_MASK, gpiomask);
6253 snd_hda_codec_write(codec, codec->afg, 0,
6254 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6255
6256 msleep(1);
6257
6258 snd_hda_codec_write(codec, codec->afg, 0,
6259 AC_VERB_SET_GPIO_DATA, gpiostate);
6260}
6261
7debbe51
TI
6262/* set up GPIO at initialization */
6263static void alc885_macpro_init_hook(struct hda_codec *codec)
6264{
6265 alc882_gpio_mute(codec, 0, 0);
6266 alc882_gpio_mute(codec, 1, 0);
6267}
6268
6269/* set up GPIO and update auto-muting at initialization */
6270static void alc885_imac24_init_hook(struct hda_codec *codec)
6271{
6272 alc885_macpro_init_hook(codec);
6273 alc885_imac24_automute(codec);
6274}
6275
df694daa
KY
6276/*
6277 * generic initialization of ADC, input mixers and output mixers
6278 */
6279static struct hda_verb alc882_auto_init_verbs[] = {
6280 /*
6281 * Unmute ADC0-2 and set the default input to mic-in
6282 */
6283 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6284 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6285 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6286 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6287 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6288 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 6289
cb53c626 6290 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 6291 * mixer widget
f12ab1e0
TI
6292 * Note: PASD motherboards uses the Line In 2 as the input for
6293 * front panel mic (mic 2)
df694daa
KY
6294 */
6295 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
6296 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6297 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6298 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6299 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6300 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
e9edcee0 6301
df694daa
KY
6302 /*
6303 * Set up output mixers (0x0c - 0x0f)
6304 */
6305 /* set vol=0 to output mixers */
6306 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6307 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6308 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6309 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6310 /* set up input amps for analog loopback */
6311 /* Amp Indices: DAC = 0, mixer = 1 */
6312 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6313 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6314 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6315 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6316 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6317 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6318 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6319 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6320 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6321 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6322
6323 /* FIXME: use matrix-type input source selection */
6324 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6325 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6326 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6327 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6328 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6329 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6330 /* Input mixer2 */
6331 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6332 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6333 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6334 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6335 /* Input mixer3 */
6336 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6337 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6338 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6339 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6340
6341 { }
6342};
6343
6344/* capture mixer elements */
6345static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
6346 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6347 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6348 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6349 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6350 {
6351 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6352 /* The multiple "Capture Source" controls confuse alsamixer
6353 * So call somewhat different..
df694daa
KY
6354 */
6355 /* .name = "Capture Source", */
6356 .name = "Input Source",
6357 .count = 2,
6358 .info = alc882_mux_enum_info,
6359 .get = alc882_mux_enum_get,
6360 .put = alc882_mux_enum_put,
6361 },
6362 { } /* end */
6363};
6364
6365static struct snd_kcontrol_new alc882_capture_mixer[] = {
6366 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
6367 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
6368 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
6369 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
6370 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
6371 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
6372 {
6373 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6374 /* The multiple "Capture Source" controls confuse alsamixer
6375 * So call somewhat different..
df694daa
KY
6376 */
6377 /* .name = "Capture Source", */
6378 .name = "Input Source",
6379 .count = 3,
6380 .info = alc882_mux_enum_info,
6381 .get = alc882_mux_enum_get,
6382 .put = alc882_mux_enum_put,
6383 },
6384 { } /* end */
6385};
6386
cb53c626
TI
6387#ifdef CONFIG_SND_HDA_POWER_SAVE
6388#define alc882_loopbacks alc880_loopbacks
6389#endif
6390
df694daa
KY
6391/* pcm configuration: identiacal with ALC880 */
6392#define alc882_pcm_analog_playback alc880_pcm_analog_playback
6393#define alc882_pcm_analog_capture alc880_pcm_analog_capture
6394#define alc882_pcm_digital_playback alc880_pcm_digital_playback
6395#define alc882_pcm_digital_capture alc880_pcm_digital_capture
6396
6397/*
6398 * configuration and preset
6399 */
f5fcc13c
TI
6400static const char *alc882_models[ALC882_MODEL_LAST] = {
6401 [ALC882_3ST_DIG] = "3stack-dig",
6402 [ALC882_6ST_DIG] = "6stack-dig",
6403 [ALC882_ARIMA] = "arima",
bdd148a3 6404 [ALC882_W2JC] = "w2jc",
0438a00e
TI
6405 [ALC882_TARGA] = "targa",
6406 [ALC882_ASUS_A7J] = "asus-a7j",
6407 [ALC882_ASUS_A7M] = "asus-a7m",
9102cd1c 6408 [ALC885_MACPRO] = "macpro",
87350ad0 6409 [ALC885_MBP3] = "mbp3",
c54728d8 6410 [ALC885_IMAC24] = "imac24",
f5fcc13c
TI
6411 [ALC882_AUTO] = "auto",
6412};
6413
6414static struct snd_pci_quirk alc882_cfg_tbl[] = {
6415 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
272a527c 6416 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
ac8842a0 6417 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
914759b7 6418 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
ac3e3741 6419 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
c5d9f1cd 6420 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
7b9470d8 6421 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 6422 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
4444704c 6423 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
ac3e3741
TI
6424 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6425 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6426 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
df694daa
KY
6427 {}
6428};
6429
6430static struct alc_config_preset alc882_presets[] = {
6431 [ALC882_3ST_DIG] = {
6432 .mixers = { alc882_base_mixer },
6433 .init_verbs = { alc882_init_verbs },
6434 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6435 .dac_nids = alc882_dac_nids,
6436 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
6437 .dig_in_nid = ALC882_DIGIN_NID,
6438 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6439 .channel_mode = alc882_ch_modes,
4e195a7b 6440 .need_dac_fix = 1,
df694daa
KY
6441 .input_mux = &alc882_capture_source,
6442 },
6443 [ALC882_6ST_DIG] = {
6444 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6445 .init_verbs = { alc882_init_verbs },
6446 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6447 .dac_nids = alc882_dac_nids,
6448 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
6449 .dig_in_nid = ALC882_DIGIN_NID,
6450 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6451 .channel_mode = alc882_sixstack_modes,
6452 .input_mux = &alc882_capture_source,
6453 },
4b146cb0
TI
6454 [ALC882_ARIMA] = {
6455 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6456 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6457 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6458 .dac_nids = alc882_dac_nids,
6459 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6460 .channel_mode = alc882_sixstack_modes,
6461 .input_mux = &alc882_capture_source,
6462 },
bdd148a3
KY
6463 [ALC882_W2JC] = {
6464 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6465 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6466 alc880_gpio1_init_verbs },
6467 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6468 .dac_nids = alc882_dac_nids,
6469 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6470 .channel_mode = alc880_threestack_modes,
6471 .need_dac_fix = 1,
6472 .input_mux = &alc882_capture_source,
6473 .dig_out_nid = ALC882_DIGOUT_NID,
6474 },
87350ad0
TI
6475 [ALC885_MBP3] = {
6476 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6477 .init_verbs = { alc885_mbp3_init_verbs,
6478 alc880_gpio1_init_verbs },
6479 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6480 .dac_nids = alc882_dac_nids,
6481 .channel_mode = alc885_mbp_6ch_modes,
6482 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6483 .input_mux = &alc882_capture_source,
6484 .dig_out_nid = ALC882_DIGOUT_NID,
6485 .dig_in_nid = ALC882_DIGIN_NID,
6486 .unsol_event = alc885_mbp3_unsol_event,
6487 .init_hook = alc885_mbp3_automute,
6488 },
9102cd1c
TD
6489 [ALC885_MACPRO] = {
6490 .mixers = { alc882_macpro_mixer },
6491 .init_verbs = { alc882_macpro_init_verbs },
6492 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6493 .dac_nids = alc882_dac_nids,
6494 .dig_out_nid = ALC882_DIGOUT_NID,
6495 .dig_in_nid = ALC882_DIGIN_NID,
6496 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6497 .channel_mode = alc882_ch_modes,
6498 .input_mux = &alc882_capture_source,
7debbe51 6499 .init_hook = alc885_macpro_init_hook,
9102cd1c 6500 },
c54728d8
NF
6501 [ALC885_IMAC24] = {
6502 .mixers = { alc885_imac24_mixer },
6503 .init_verbs = { alc885_imac24_init_verbs },
6504 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6505 .dac_nids = alc882_dac_nids,
6506 .dig_out_nid = ALC882_DIGOUT_NID,
6507 .dig_in_nid = ALC882_DIGIN_NID,
6508 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6509 .channel_mode = alc882_ch_modes,
6510 .input_mux = &alc882_capture_source,
6511 .unsol_event = alc885_imac24_unsol_event,
7debbe51 6512 .init_hook = alc885_imac24_init_hook,
c54728d8 6513 },
272a527c
KY
6514 [ALC882_TARGA] = {
6515 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6516 alc882_capture_mixer },
6517 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6518 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6519 .dac_nids = alc882_dac_nids,
6520 .dig_out_nid = ALC882_DIGOUT_NID,
6521 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6522 .adc_nids = alc882_adc_nids,
e1406348 6523 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
6524 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6525 .channel_mode = alc882_3ST_6ch_modes,
6526 .need_dac_fix = 1,
6527 .input_mux = &alc882_capture_source,
6528 .unsol_event = alc882_targa_unsol_event,
6529 .init_hook = alc882_targa_automute,
6530 },
6531 [ALC882_ASUS_A7J] = {
6532 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6533 alc882_capture_mixer },
6534 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6535 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6536 .dac_nids = alc882_dac_nids,
6537 .dig_out_nid = ALC882_DIGOUT_NID,
6538 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6539 .adc_nids = alc882_adc_nids,
e1406348 6540 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
6541 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6542 .channel_mode = alc882_3ST_6ch_modes,
6543 .need_dac_fix = 1,
6544 .input_mux = &alc882_capture_source,
ea1fb29a 6545 },
914759b7
TI
6546 [ALC882_ASUS_A7M] = {
6547 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6548 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6549 alc880_gpio1_init_verbs,
6550 alc882_asus_a7m_verbs },
6551 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6552 .dac_nids = alc882_dac_nids,
6553 .dig_out_nid = ALC882_DIGOUT_NID,
6554 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6555 .channel_mode = alc880_threestack_modes,
6556 .need_dac_fix = 1,
6557 .input_mux = &alc882_capture_source,
ea1fb29a 6558 },
df694daa
KY
6559};
6560
6561
f95474ec
TI
6562/*
6563 * Pin config fixes
6564 */
ea1fb29a 6565enum {
f95474ec
TI
6566 PINFIX_ABIT_AW9D_MAX
6567};
6568
6569static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6570 { 0x15, 0x01080104 }, /* side */
6571 { 0x16, 0x01011012 }, /* rear */
6572 { 0x17, 0x01016011 }, /* clfe */
6573 { }
6574};
6575
6576static const struct alc_pincfg *alc882_pin_fixes[] = {
6577 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6578};
6579
6580static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6581 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6582 {}
6583};
6584
df694daa
KY
6585/*
6586 * BIOS auto configuration
6587 */
6588static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6589 hda_nid_t nid, int pin_type,
6590 int dac_idx)
6591{
6592 /* set as output */
6593 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
6594 int idx;
6595
f6c7e546 6596 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6597 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6598 idx = 4;
6599 else
6600 idx = spec->multiout.dac_nids[dac_idx] - 2;
df694daa
KY
6601 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6602
6603}
6604
6605static void alc882_auto_init_multi_out(struct hda_codec *codec)
6606{
6607 struct alc_spec *spec = codec->spec;
6608 int i;
6609
bc9f98a9 6610 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
df694daa 6611 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 6612 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 6613 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 6614 if (nid)
baba8ee9 6615 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 6616 i);
df694daa
KY
6617 }
6618}
6619
6620static void alc882_auto_init_hp_out(struct hda_codec *codec)
6621{
6622 struct alc_spec *spec = codec->spec;
6623 hda_nid_t pin;
6624
eb06ed8f 6625 pin = spec->autocfg.hp_pins[0];
df694daa 6626 if (pin) /* connect to front */
f12ab1e0
TI
6627 /* use dac 0 */
6628 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
6629 pin = spec->autocfg.speaker_pins[0];
6630 if (pin)
6631 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
6632}
6633
6634#define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6635#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6636
6637static void alc882_auto_init_analog_input(struct hda_codec *codec)
6638{
6639 struct alc_spec *spec = codec->spec;
6640 int i;
6641
6642 for (i = 0; i < AUTO_PIN_LAST; i++) {
6643 hda_nid_t nid = spec->autocfg.input_pins[i];
7194cae6
TI
6644 unsigned int vref;
6645 if (!nid)
6646 continue;
6647 vref = PIN_IN;
6648 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
531240ff
KY
6649 unsigned int pincap;
6650 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6651 if ((pincap >> AC_PINCAP_VREF_SHIFT) &
7194cae6
TI
6652 AC_PINCAP_VREF_80)
6653 vref = PIN_VREF80;
df694daa 6654 }
7194cae6
TI
6655 snd_hda_codec_write(codec, nid, 0,
6656 AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6657 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6658 snd_hda_codec_write(codec, nid, 0,
6659 AC_VERB_SET_AMP_GAIN_MUTE,
6660 AMP_OUT_MUTE);
df694daa
KY
6661 }
6662}
6663
f511b01c
TI
6664static void alc882_auto_init_input_src(struct hda_codec *codec)
6665{
6666 struct alc_spec *spec = codec->spec;
6667 const struct hda_input_mux *imux = spec->input_mux;
6668 int c;
6669
6670 for (c = 0; c < spec->num_adc_nids; c++) {
6671 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6672 hda_nid_t nid = spec->capsrc_nids[c];
6673 int conns, mute, idx, item;
6674
6675 conns = snd_hda_get_connections(codec, nid, conn_list,
6676 ARRAY_SIZE(conn_list));
6677 if (conns < 0)
6678 continue;
6679 for (idx = 0; idx < conns; idx++) {
6680 /* if the current connection is the selected one,
6681 * unmute it as default - otherwise mute it
6682 */
6683 mute = AMP_IN_MUTE(idx);
6684 for (item = 0; item < imux->num_items; item++) {
6685 if (imux->items[item].index == idx) {
6686 if (spec->cur_mux[c] == item)
6687 mute = AMP_IN_UNMUTE(idx);
6688 break;
6689 }
6690 }
6691 snd_hda_codec_write(codec, nid, 0,
6692 AC_VERB_SET_AMP_GAIN_MUTE, mute);
6693 }
6694 }
6695}
6696
776e184e
TI
6697/* add mic boosts if needed */
6698static int alc_auto_add_mic_boost(struct hda_codec *codec)
6699{
6700 struct alc_spec *spec = codec->spec;
6701 int err;
6702 hda_nid_t nid;
6703
6704 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
ce22e03e 6705 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
6706 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6707 "Mic Boost",
6708 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6709 if (err < 0)
6710 return err;
6711 }
6712 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
ce22e03e 6713 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
6714 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6715 "Front Mic Boost",
6716 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6717 if (err < 0)
6718 return err;
6719 }
6720 return 0;
6721}
6722
df694daa
KY
6723/* almost identical with ALC880 parser... */
6724static int alc882_parse_auto_config(struct hda_codec *codec)
6725{
6726 struct alc_spec *spec = codec->spec;
6727 int err = alc880_parse_auto_config(codec);
6728
6729 if (err < 0)
6730 return err;
776e184e
TI
6731 else if (!err)
6732 return 0; /* no config found */
6733
6734 err = alc_auto_add_mic_boost(codec);
6735 if (err < 0)
6736 return err;
6737
6738 /* hack - override the init verbs */
6739 spec->init_verbs[0] = alc882_auto_init_verbs;
6740
6741 return 1; /* config found */
df694daa
KY
6742}
6743
ae6b813a
TI
6744/* additional initialization for auto-configuration model */
6745static void alc882_auto_init(struct hda_codec *codec)
df694daa 6746{
f6c7e546 6747 struct alc_spec *spec = codec->spec;
df694daa
KY
6748 alc882_auto_init_multi_out(codec);
6749 alc882_auto_init_hp_out(codec);
6750 alc882_auto_init_analog_input(codec);
f511b01c 6751 alc882_auto_init_input_src(codec);
f6c7e546 6752 if (spec->unsol_event)
7fb0d78f 6753 alc_inithook(codec);
df694daa
KY
6754}
6755
7943a8ab
TI
6756static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6757
df694daa
KY
6758static int patch_alc882(struct hda_codec *codec)
6759{
6760 struct alc_spec *spec;
6761 int err, board_config;
6762
6763 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6764 if (spec == NULL)
6765 return -ENOMEM;
6766
6767 codec->spec = spec;
6768
f5fcc13c
TI
6769 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6770 alc882_models,
6771 alc882_cfg_tbl);
df694daa
KY
6772
6773 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
081d17c4
TD
6774 /* Pick up systems that don't supply PCI SSID */
6775 switch (codec->subsystem_id) {
6776 case 0x106b0c00: /* Mac Pro */
6777 board_config = ALC885_MACPRO;
6778 break;
c54728d8 6779 case 0x106b1000: /* iMac 24 */
f3911c5a 6780 case 0x106b2800: /* AppleTV */
c54728d8
NF
6781 board_config = ALC885_IMAC24;
6782 break;
c7e0757a 6783 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
9c95c43d 6784 case 0x106b00a4: /* MacbookPro4,1 */
87350ad0 6785 case 0x106b2c00: /* Macbook Pro rev3 */
c7e0757a 6786 case 0x106b3600: /* Macbook 3.1 */
87350ad0
TI
6787 board_config = ALC885_MBP3;
6788 break;
081d17c4 6789 default:
7943a8ab 6790 /* ALC889A is handled better as ALC888-compatible */
669faba2
CM
6791 if (codec->revision_id == 0x100101 ||
6792 codec->revision_id == 0x100103) {
7943a8ab
TI
6793 alc_free(codec);
6794 return patch_alc883(codec);
6795 }
081d17c4
TD
6796 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6797 "trying auto-probe from BIOS...\n");
6798 board_config = ALC882_AUTO;
6799 }
df694daa
KY
6800 }
6801
f95474ec
TI
6802 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6803
df694daa
KY
6804 if (board_config == ALC882_AUTO) {
6805 /* automatic parse from the BIOS config */
6806 err = alc882_parse_auto_config(codec);
6807 if (err < 0) {
6808 alc_free(codec);
6809 return err;
f12ab1e0 6810 } else if (!err) {
9c7f852e
TI
6811 printk(KERN_INFO
6812 "hda_codec: Cannot set up configuration "
6813 "from BIOS. Using base mode...\n");
df694daa
KY
6814 board_config = ALC882_3ST_DIG;
6815 }
6816 }
6817
6818 if (board_config != ALC882_AUTO)
6819 setup_preset(spec, &alc882_presets[board_config]);
1da177e4 6820
2f893286
KY
6821 if (codec->vendor_id == 0x10ec0885) {
6822 spec->stream_name_analog = "ALC885 Analog";
6823 spec->stream_name_digital = "ALC885 Digital";
6824 } else {
6825 spec->stream_name_analog = "ALC882 Analog";
6826 spec->stream_name_digital = "ALC882 Digital";
6827 }
6828
df694daa
KY
6829 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6830 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6330079f
TI
6831 /* FIXME: setup DAC5 */
6832 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6833 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 6834
df694daa
KY
6835 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6836 spec->stream_digital_capture = &alc882_pcm_digital_capture;
1da177e4 6837
f12ab1e0 6838 if (!spec->adc_nids && spec->input_mux) {
df694daa 6839 /* check whether NID 0x07 is valid */
4a471b7d 6840 unsigned int wcap = get_wcaps(codec, 0x07);
f12ab1e0
TI
6841 /* get type */
6842 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
6843 if (wcap != AC_WID_AUD_IN) {
6844 spec->adc_nids = alc882_adc_nids_alt;
6845 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
e1406348 6846 spec->capsrc_nids = alc882_capsrc_nids_alt;
d88897ea 6847 add_mixer(spec, alc882_capture_alt_mixer);
df694daa
KY
6848 } else {
6849 spec->adc_nids = alc882_adc_nids;
6850 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
e1406348 6851 spec->capsrc_nids = alc882_capsrc_nids;
d88897ea 6852 add_mixer(spec, alc882_capture_mixer);
df694daa
KY
6853 }
6854 }
1da177e4 6855
2134ea4f
TI
6856 spec->vmaster_nid = 0x0c;
6857
1da177e4 6858 codec->patch_ops = alc_patch_ops;
df694daa 6859 if (board_config == ALC882_AUTO)
ae6b813a 6860 spec->init_hook = alc882_auto_init;
cb53c626
TI
6861#ifdef CONFIG_SND_HDA_POWER_SAVE
6862 if (!spec->loopback.amplist)
6863 spec->loopback.amplist = alc882_loopbacks;
6864#endif
df694daa
KY
6865
6866 return 0;
6867}
6868
6869/*
9c7f852e
TI
6870 * ALC883 support
6871 *
6872 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6873 * configuration. Each pin widget can choose any input DACs and a mixer.
6874 * Each ADC is connected from a mixer of all inputs. This makes possible
6875 * 6-channel independent captures.
6876 *
6877 * In addition, an independent DAC for the multi-playback (not used in this
6878 * driver yet).
df694daa 6879 */
9c7f852e
TI
6880#define ALC883_DIGOUT_NID 0x06
6881#define ALC883_DIGIN_NID 0x0a
df694daa 6882
9c7f852e
TI
6883static hda_nid_t alc883_dac_nids[4] = {
6884 /* front, rear, clfe, rear_surr */
f32a19e3 6885 0x02, 0x03, 0x04, 0x05
9c7f852e 6886};
df694daa 6887
9c7f852e
TI
6888static hda_nid_t alc883_adc_nids[2] = {
6889 /* ADC1-2 */
6890 0x08, 0x09,
6891};
f12ab1e0 6892
e1406348
TI
6893static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6894
9c7f852e
TI
6895/* input MUX */
6896/* FIXME: should be a matrix-type input source selection */
df694daa 6897
9c7f852e
TI
6898static struct hda_input_mux alc883_capture_source = {
6899 .num_items = 4,
6900 .items = {
6901 { "Mic", 0x0 },
6902 { "Front Mic", 0x1 },
6903 { "Line", 0x2 },
6904 { "CD", 0x4 },
6905 },
6906};
bc9f98a9 6907
17bba1b7
J
6908static struct hda_input_mux alc883_3stack_6ch_intel = {
6909 .num_items = 4,
6910 .items = {
6911 { "Mic", 0x1 },
6912 { "Front Mic", 0x0 },
6913 { "Line", 0x2 },
6914 { "CD", 0x4 },
6915 },
6916};
6917
bc9f98a9
KY
6918static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6919 .num_items = 2,
6920 .items = {
6921 { "Mic", 0x1 },
6922 { "Line", 0x2 },
6923 },
6924};
6925
272a527c
KY
6926static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6927 .num_items = 4,
6928 .items = {
6929 { "Mic", 0x0 },
6930 { "iMic", 0x1 },
6931 { "Line", 0x2 },
6932 { "CD", 0x4 },
6933 },
6934};
6935
fb97dc67
J
6936static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6937 .num_items = 2,
6938 .items = {
6939 { "Mic", 0x0 },
6940 { "Int Mic", 0x1 },
6941 },
6942};
6943
e2757d5e
KY
6944static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6945 .num_items = 3,
6946 .items = {
6947 { "Mic", 0x0 },
6948 { "Front Mic", 0x1 },
6949 { "Line", 0x4 },
6950 },
6951};
6952
6953static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6954 .num_items = 2,
6955 .items = {
6956 { "Mic", 0x0 },
6957 { "Line", 0x2 },
6958 },
6959};
6960
9c7f852e
TI
6961#define alc883_mux_enum_info alc_mux_enum_info
6962#define alc883_mux_enum_get alc_mux_enum_get
e1406348
TI
6963/* ALC883 has the ALC882-type input selection */
6964#define alc883_mux_enum_put alc882_mux_enum_put
f12ab1e0 6965
9c7f852e
TI
6966/*
6967 * 2ch mode
6968 */
6969static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6970 { 2, NULL }
6971};
6972
6973/*
6974 * 2ch mode
6975 */
6976static struct hda_verb alc883_3ST_ch2_init[] = {
6977 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6978 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6979 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6980 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6981 { } /* end */
6982};
6983
b201131c
TD
6984/*
6985 * 4ch mode
6986 */
6987static struct hda_verb alc883_3ST_ch4_init[] = {
6988 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6989 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6990 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6991 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6992 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6993 { } /* end */
6994};
6995
9c7f852e
TI
6996/*
6997 * 6ch mode
6998 */
6999static struct hda_verb alc883_3ST_ch6_init[] = {
7000 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7001 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7002 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7003 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7004 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7005 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7006 { } /* end */
7007};
7008
b201131c 7009static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
9c7f852e 7010 { 2, alc883_3ST_ch2_init },
b201131c 7011 { 4, alc883_3ST_ch4_init },
9c7f852e
TI
7012 { 6, alc883_3ST_ch6_init },
7013};
7014
17bba1b7
J
7015/*
7016 * 2ch mode
7017 */
7018static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7019 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7020 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7021 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7022 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7023 { } /* end */
7024};
7025
7026/*
7027 * 4ch mode
7028 */
7029static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7030 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7031 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7032 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7033 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7034 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7035 { } /* end */
7036};
7037
7038/*
7039 * 6ch mode
7040 */
7041static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7042 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7043 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7044 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7045 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7046 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7047 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7048 { } /* end */
7049};
7050
7051static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7052 { 2, alc883_3ST_ch2_intel_init },
7053 { 4, alc883_3ST_ch4_intel_init },
7054 { 6, alc883_3ST_ch6_intel_init },
7055};
7056
9c7f852e
TI
7057/*
7058 * 6ch mode
7059 */
7060static struct hda_verb alc883_sixstack_ch6_init[] = {
7061 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7062 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7063 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7064 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7065 { } /* end */
7066};
7067
7068/*
7069 * 8ch mode
7070 */
7071static struct hda_verb alc883_sixstack_ch8_init[] = {
7072 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7073 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7074 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7075 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7076 { } /* end */
7077};
7078
7079static struct hda_channel_mode alc883_sixstack_modes[2] = {
7080 { 6, alc883_sixstack_ch6_init },
7081 { 8, alc883_sixstack_ch8_init },
7082};
7083
b373bdeb
AN
7084static struct hda_verb alc883_medion_eapd_verbs[] = {
7085 /* eanable EAPD on medion laptop */
7086 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7087 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7088 { }
7089};
7090
9c7f852e
TI
7091/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7092 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7093 */
7094
7095static struct snd_kcontrol_new alc883_base_mixer[] = {
df694daa 7096 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9c7f852e
TI
7097 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7098 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7099 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7100 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7101 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7102 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7103 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7104 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7105 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7106 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
df694daa
KY
7107 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7108 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7109 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7110 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7111 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7112 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
df694daa 7113 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9c7f852e 7114 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7115 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
7116 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7117 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7118 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7119 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7120 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7121 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7122 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7123 {
7124 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7125 /* .name = "Capture Source", */
7126 .name = "Input Source",
7127 .count = 2,
7128 .info = alc883_mux_enum_info,
7129 .get = alc883_mux_enum_get,
7130 .put = alc883_mux_enum_put,
7131 },
df694daa 7132 { } /* end */
834be88d
TI
7133};
7134
a8848bd6
AS
7135static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7136 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7137 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7138 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7139 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7140 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7141 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7142 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7143 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7144 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7145 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7146 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7147 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7148 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7149 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7150 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7151 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7152 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7153 {
7154 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7155 /* .name = "Capture Source", */
7156 .name = "Input Source",
7157 .count = 2,
7158 .info = alc883_mux_enum_info,
7159 .get = alc883_mux_enum_get,
7160 .put = alc883_mux_enum_put,
7161 },
7162 { } /* end */
7163};
7164
0c4cc443 7165static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
7166 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7167 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7168 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7169 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7170 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7171 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7172 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7173 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7174 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7175 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7176 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7177 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7178 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7179 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7180 {
7181 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7182 /* .name = "Capture Source", */
7183 .name = "Input Source",
7184 .count = 2,
7185 .info = alc883_mux_enum_info,
7186 .get = alc883_mux_enum_get,
7187 .put = alc883_mux_enum_put,
7188 },
7189 { } /* end */
7190};
7191
fb97dc67
J
7192static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7193 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7194 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7195 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7196 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7197 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7198 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7199 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7200 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7201 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7202 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7203 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7204 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7205 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7206 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7207 {
7208 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7209 /* .name = "Capture Source", */
7210 .name = "Input Source",
7211 .count = 2,
7212 .info = alc883_mux_enum_info,
7213 .get = alc883_mux_enum_get,
7214 .put = alc883_mux_enum_put,
7215 },
7216 { } /* end */
7217};
7218
9c7f852e
TI
7219static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7220 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7221 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7222 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7223 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7224 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7225 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7226 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7227 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7228 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
7229 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7230 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7231 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
7232 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7233 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7234 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7235 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7236 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7237 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7238 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7239 {
7240 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7241 /* .name = "Capture Source", */
7242 .name = "Input Source",
7243 .count = 2,
7244 .info = alc883_mux_enum_info,
7245 .get = alc883_mux_enum_get,
7246 .put = alc883_mux_enum_put,
7247 },
7248 { } /* end */
7249};
df694daa 7250
9c7f852e
TI
7251static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7252 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7253 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7254 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7255 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7256 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7257 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7258 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7259 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7260 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7261 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7262 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7263 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7264 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7265 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7266 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
7267 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7268 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7269 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
7270 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7271 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7272 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7273 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7274 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9c7f852e
TI
7275 {
7276 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7277 /* .name = "Capture Source", */
7278 .name = "Input Source",
e2757d5e 7279 .count = 1,
9c7f852e
TI
7280 .info = alc883_mux_enum_info,
7281 .get = alc883_mux_enum_get,
7282 .put = alc883_mux_enum_put,
7283 },
7284 { } /* end */
7285};
7286
17bba1b7
J
7287static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7288 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7289 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7290 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7291 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7292 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7293 HDA_OUTPUT),
7294 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7295 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7296 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7297 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7298 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7299 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7300 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7301 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7302 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7303 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7304 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7305 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7306 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7307 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7308 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7309 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7310 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7311 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7312 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7313 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7314 {
7315 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7316 /* .name = "Capture Source", */
7317 .name = "Input Source",
7318 .count = 2,
7319 .info = alc883_mux_enum_info,
7320 .get = alc883_mux_enum_get,
7321 .put = alc883_mux_enum_put,
7322 },
7323 { } /* end */
7324};
7325
d1d985f0 7326static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 7327 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 7328 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 7329 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 7330 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
7331 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7332 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
7333 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7334 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
7335 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7336 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7337 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7338 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7339 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7340 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7341 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
7342 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7343 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 7344 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8
TD
7345 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7346 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7347 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7348 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7349 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7350
7351 {
7352 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7353 /* .name = "Capture Source", */
7354 .name = "Input Source",
7355 .count = 1,
7356 .info = alc883_mux_enum_info,
7357 .get = alc883_mux_enum_get,
7358 .put = alc883_mux_enum_put,
7359 },
7360 { } /* end */
7361};
7362
ccc656ce
KY
7363static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7364 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7365 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7366 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7367 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7368 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7369 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7370 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7371 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7372 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7373 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7374 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7375 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7376 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7377 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7378 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
7379 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7380 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7381 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7382 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7383 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7384 {
7385 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7386 /* .name = "Capture Source", */
7387 .name = "Input Source",
7388 .count = 2,
7389 .info = alc883_mux_enum_info,
7390 .get = alc883_mux_enum_get,
7391 .put = alc883_mux_enum_put,
7392 },
7393 { } /* end */
f12ab1e0 7394};
ccc656ce
KY
7395
7396static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7397 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7398 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7399 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7400 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7401 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7402 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 7403 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce 7404 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4383fae0
J
7405 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7406 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7407 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
7408 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7409 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7410 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7411 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7412 {
7413 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7414 /* .name = "Capture Source", */
7415 .name = "Input Source",
7416 .count = 2,
7417 .info = alc883_mux_enum_info,
7418 .get = alc883_mux_enum_get,
7419 .put = alc883_mux_enum_put,
7420 },
7421 { } /* end */
f12ab1e0 7422};
ccc656ce 7423
bc9f98a9
KY
7424static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7425 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7426 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
7427 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7428 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
7429 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7430 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7431 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7432 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7433 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7434 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7435 {
7436 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7437 /* .name = "Capture Source", */
7438 .name = "Input Source",
7439 .count = 1,
7440 .info = alc883_mux_enum_info,
7441 .get = alc883_mux_enum_get,
7442 .put = alc883_mux_enum_put,
7443 },
7444 { } /* end */
f12ab1e0 7445};
bc9f98a9 7446
272a527c
KY
7447static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7448 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7449 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7450 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7451 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7452 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7453 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7454 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7455 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7456 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7457 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7458 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7459 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7460 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7461 {
7462 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7463 /* .name = "Capture Source", */
7464 .name = "Input Source",
7465 .count = 2,
7466 .info = alc883_mux_enum_info,
7467 .get = alc883_mux_enum_get,
7468 .put = alc883_mux_enum_put,
7469 },
7470 { } /* end */
7471};
7472
7473static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7474 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7475 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7476 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7477 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7478 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7479 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7480 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7481 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7482 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7483 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7484 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7485 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7486 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7487 {
7488 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7489 /* .name = "Capture Source", */
7490 .name = "Input Source",
7491 .count = 2,
7492 .info = alc883_mux_enum_info,
7493 .get = alc883_mux_enum_get,
7494 .put = alc883_mux_enum_put,
7495 },
7496 { } /* end */
ea1fb29a 7497};
272a527c 7498
2880a867 7499static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
7500 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7501 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 7502 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
7503 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7504 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
7505 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7506 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7507 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867
TD
7508 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7509 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7510 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7511 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7512 {
7513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7514 /* .name = "Capture Source", */
7515 .name = "Input Source",
7516 .count = 2,
7517 .info = alc883_mux_enum_info,
7518 .get = alc883_mux_enum_get,
7519 .put = alc883_mux_enum_put,
7520 },
7521 { } /* end */
d1a991a6 7522};
2880a867 7523
e2757d5e
KY
7524static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7525 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7526 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7527 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7528 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7529 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7530 0x0d, 1, 0x0, HDA_OUTPUT),
7531 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7532 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7533 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7534 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7535 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7536 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7537 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7538 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7539 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7540 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7541 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7542 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7543 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7544 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7545 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7546 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7547 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7548 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7549 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7550 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7551 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7552 {
7553 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7554 /* .name = "Capture Source", */
7555 .name = "Input Source",
7556 .count = 2,
7557 .info = alc883_mux_enum_info,
7558 .get = alc883_mux_enum_get,
7559 .put = alc883_mux_enum_put,
7560 },
7561 { } /* end */
7562};
7563
7564static struct hda_bind_ctls alc883_bind_cap_vol = {
7565 .ops = &snd_hda_bind_vol,
7566 .values = {
7567 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7568 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7569 0
7570 },
7571};
7572
7573static struct hda_bind_ctls alc883_bind_cap_switch = {
7574 .ops = &snd_hda_bind_sw,
7575 .values = {
7576 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7577 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7578 0
7579 },
7580};
7581
7582static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7583 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7584 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7585 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7586 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7587 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7588 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7589 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7590 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7591 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7592 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7593 {
7594 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7595 /* .name = "Capture Source", */
7596 .name = "Input Source",
7597 .count = 1,
7598 .info = alc883_mux_enum_info,
7599 .get = alc883_mux_enum_get,
7600 .put = alc883_mux_enum_put,
7601 },
7602 { } /* end */
7603};
7604
9c7f852e
TI
7605static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7606 {
7607 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7608 .name = "Channel Mode",
7609 .info = alc_ch_mode_info,
7610 .get = alc_ch_mode_get,
7611 .put = alc_ch_mode_put,
7612 },
7613 { } /* end */
7614};
7615
7616static struct hda_verb alc883_init_verbs[] = {
7617 /* ADC1: mute amp left and right */
e2757d5e 7618 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
df694daa 7619 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
7620 /* ADC2: mute amp left and right */
7621 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
df694daa 7622 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
7623 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7624 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7625 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7626 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7627 /* Rear mixer */
7628 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7629 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7630 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7631 /* CLFE mixer */
7632 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7633 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7634 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7635 /* Side mixer */
7636 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7637 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7638 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa 7639
cb53c626
TI
7640 /* mute analog input loopbacks */
7641 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7642 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7643 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7644 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7645 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa 7646
9c7f852e
TI
7647 /* Front Pin: output 0 (0x0c) */
7648 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7649 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7650 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7651 /* Rear Pin: output 1 (0x0d) */
7652 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7653 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7654 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7655 /* CLFE Pin: output 2 (0x0e) */
7656 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7657 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7658 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7659 /* Side Pin: output 3 (0x0f) */
7660 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7661 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7662 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7663 /* Mic (rear) pin: input vref at 80% */
7664 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7665 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7666 /* Front Mic pin: input vref at 80% */
7667 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7668 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7669 /* Line In pin: input */
7670 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7671 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7672 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7673 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7674 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7675 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7676 /* CD pin widget for input */
7677 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7678
7679 /* FIXME: use matrix-type input source selection */
7680 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7681 /* Input mixer2 */
7682 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
e2757d5e
KY
7683 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7684 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7685 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
7686 /* Input mixer3 */
7687 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
e2757d5e
KY
7688 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7689 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7690 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
7691 { }
7692};
7693
a8848bd6
AS
7694/* toggle speaker-output according to the hp-jack state */
7695static void alc883_mitac_hp_automute(struct hda_codec *codec)
7696{
7697 unsigned int present;
7698
7699 present = snd_hda_codec_read(codec, 0x15, 0,
7700 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7701 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7702 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7703 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7704 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7705}
7706
7707/* auto-toggle front mic */
7708/*
7709static void alc883_mitac_mic_automute(struct hda_codec *codec)
7710{
7711 unsigned int present;
7712 unsigned char bits;
7713
7714 present = snd_hda_codec_read(codec, 0x18, 0,
7715 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7716 bits = present ? HDA_AMP_MUTE : 0;
7717 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7718}
7719*/
7720
7721static void alc883_mitac_automute(struct hda_codec *codec)
7722{
7723 alc883_mitac_hp_automute(codec);
7724 /* alc883_mitac_mic_automute(codec); */
7725}
7726
7727static void alc883_mitac_unsol_event(struct hda_codec *codec,
7728 unsigned int res)
7729{
7730 switch (res >> 26) {
7731 case ALC880_HP_EVENT:
7732 alc883_mitac_hp_automute(codec);
7733 break;
7734 case ALC880_MIC_EVENT:
7735 /* alc883_mitac_mic_automute(codec); */
7736 break;
7737 }
7738}
7739
7740static struct hda_verb alc883_mitac_verbs[] = {
7741 /* HP */
7742 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7743 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7744 /* Subwoofer */
7745 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7746 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7747
7748 /* enable unsolicited event */
7749 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7750 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7751
7752 { } /* end */
7753};
7754
0c4cc443 7755static struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
7756 /* HP */
7757 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7758 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7759 /* Int speaker */
7760 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7761 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7762
7763 /* enable unsolicited event */
7764 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 7765 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
7766
7767 { } /* end */
7768};
7769
fb97dc67
J
7770static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7771 /* HP */
7772 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7773 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7774 /* Subwoofer */
7775 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7776 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7777
7778 /* enable unsolicited event */
7779 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7780
7781 { } /* end */
7782};
7783
ccc656ce
KY
7784static struct hda_verb alc883_tagra_verbs[] = {
7785 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7786 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7787
7788 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7789 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 7790
ccc656ce
KY
7791 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7792 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7793 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7794
7795 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
f12ab1e0
TI
7796 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7797 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7798 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
ccc656ce
KY
7799
7800 { } /* end */
7801};
7802
bc9f98a9
KY
7803static struct hda_verb alc883_lenovo_101e_verbs[] = {
7804 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7805 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7806 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7807 { } /* end */
7808};
7809
272a527c
KY
7810static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7811 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7812 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7813 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7814 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7815 { } /* end */
7816};
7817
7818static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7819 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7820 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7821 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7822 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7823 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7824 { } /* end */
7825};
7826
189609ae
KY
7827static struct hda_verb alc883_haier_w66_verbs[] = {
7828 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7829 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7830
7831 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7832
7833 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7834 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7835 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7836 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7837 { } /* end */
7838};
7839
e2757d5e
KY
7840static struct hda_verb alc888_lenovo_sky_verbs[] = {
7841 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7842 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7843 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7844 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7845 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7846 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7847 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7848 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7849 { } /* end */
7850};
7851
4723c022 7852static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 7853 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
7854 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7855 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
8341de60
CM
7856 { }
7857};
7858
5795b9e6 7859static struct hda_verb alc888_6st_dell_verbs[] = {
5795b9e6
CM
7860 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7861 { }
7862};
7863
4723c022 7864static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
7865 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7866 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7867 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7868 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7869 { }
7870};
7871
4723c022 7872static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
7873 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7874 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7875 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7876 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7877 { }
7878};
7879
4723c022
CM
7880static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7881 { 2, alc888_3st_hp_2ch_init },
7882 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
7883};
7884
272a527c
KY
7885/* toggle front-jack and RCA according to the hp-jack state */
7886static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7887{
7888 unsigned int present;
ea1fb29a 7889
272a527c
KY
7890 present = snd_hda_codec_read(codec, 0x1b, 0,
7891 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7892 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7893 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7894 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7895 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
7896}
7897
7898/* toggle RCA according to the front-jack state */
7899static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7900{
7901 unsigned int present;
ea1fb29a 7902
272a527c
KY
7903 present = snd_hda_codec_read(codec, 0x14, 0,
7904 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7905 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7906 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 7907}
47fd830a 7908
272a527c
KY
7909static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7910 unsigned int res)
7911{
7912 if ((res >> 26) == ALC880_HP_EVENT)
7913 alc888_lenovo_ms7195_front_automute(codec);
7914 if ((res >> 26) == ALC880_FRONT_EVENT)
7915 alc888_lenovo_ms7195_rca_automute(codec);
7916}
7917
7918static struct hda_verb alc883_medion_md2_verbs[] = {
7919 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7920 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7921
7922 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7923
7924 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7925 { } /* end */
7926};
7927
7928/* toggle speaker-output according to the hp-jack state */
7929static void alc883_medion_md2_automute(struct hda_codec *codec)
7930{
7931 unsigned int present;
ea1fb29a 7932
272a527c
KY
7933 present = snd_hda_codec_read(codec, 0x14, 0,
7934 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7935 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7936 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
7937}
7938
7939static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7940 unsigned int res)
7941{
7942 if ((res >> 26) == ALC880_HP_EVENT)
7943 alc883_medion_md2_automute(codec);
7944}
7945
ccc656ce
KY
7946/* toggle speaker-output according to the hp-jack state */
7947static void alc883_tagra_automute(struct hda_codec *codec)
7948{
7949 unsigned int present;
f12ab1e0 7950 unsigned char bits;
ccc656ce
KY
7951
7952 present = snd_hda_codec_read(codec, 0x14, 0,
7953 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7954 bits = present ? HDA_AMP_MUTE : 0;
7955 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7956 HDA_AMP_MUTE, bits);
82beb8fd
TI
7957 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7958 present ? 1 : 3);
ccc656ce
KY
7959}
7960
7961static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7962{
7963 if ((res >> 26) == ALC880_HP_EVENT)
7964 alc883_tagra_automute(codec);
7965}
7966
368c7a95 7967/* toggle speaker-output according to the hp-jack state */
0c4cc443 7968static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
368c7a95
J
7969{
7970 unsigned int present;
7971 unsigned char bits;
7972
7973 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7974 & AC_PINSENSE_PRESENCE;
7975 bits = present ? HDA_AMP_MUTE : 0;
7976 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7977 HDA_AMP_MUTE, bits);
7978}
7979
0c4cc443
HRK
7980static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7981{
7982 unsigned int present;
7983
7984 present = snd_hda_codec_read(codec, 0x18, 0,
7985 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7986 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7987 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7988}
7989
7990static void alc883_clevo_m720_automute(struct hda_codec *codec)
7991{
7992 alc883_clevo_m720_hp_automute(codec);
7993 alc883_clevo_m720_mic_automute(codec);
7994}
7995
7996static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
7997 unsigned int res)
7998{
0c4cc443
HRK
7999 switch (res >> 26) {
8000 case ALC880_HP_EVENT:
8001 alc883_clevo_m720_hp_automute(codec);
8002 break;
8003 case ALC880_MIC_EVENT:
8004 alc883_clevo_m720_mic_automute(codec);
8005 break;
8006 }
368c7a95
J
8007}
8008
fb97dc67
J
8009/* toggle speaker-output according to the hp-jack state */
8010static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
8011{
8012 unsigned int present;
8013 unsigned char bits;
8014
8015 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8016 & AC_PINSENSE_PRESENCE;
8017 bits = present ? HDA_AMP_MUTE : 0;
8018 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8019 HDA_AMP_MUTE, bits);
8020}
8021
8022static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
8023 unsigned int res)
8024{
8025 if ((res >> 26) == ALC880_HP_EVENT)
8026 alc883_2ch_fujitsu_pi2515_automute(codec);
8027}
8028
189609ae
KY
8029static void alc883_haier_w66_automute(struct hda_codec *codec)
8030{
8031 unsigned int present;
8032 unsigned char bits;
8033
8034 present = snd_hda_codec_read(codec, 0x1b, 0,
8035 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8036 bits = present ? 0x80 : 0;
8037 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8038 0x80, bits);
8039}
8040
8041static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
8042 unsigned int res)
8043{
8044 if ((res >> 26) == ALC880_HP_EVENT)
8045 alc883_haier_w66_automute(codec);
8046}
8047
bc9f98a9
KY
8048static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8049{
8050 unsigned int present;
f12ab1e0 8051 unsigned char bits;
bc9f98a9
KY
8052
8053 present = snd_hda_codec_read(codec, 0x14, 0,
8054 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8055 bits = present ? HDA_AMP_MUTE : 0;
8056 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8057 HDA_AMP_MUTE, bits);
bc9f98a9
KY
8058}
8059
8060static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8061{
8062 unsigned int present;
f12ab1e0 8063 unsigned char bits;
bc9f98a9
KY
8064
8065 present = snd_hda_codec_read(codec, 0x1b, 0,
8066 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
8067 bits = present ? HDA_AMP_MUTE : 0;
8068 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8069 HDA_AMP_MUTE, bits);
8070 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8071 HDA_AMP_MUTE, bits);
bc9f98a9
KY
8072}
8073
8074static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8075 unsigned int res)
8076{
8077 if ((res >> 26) == ALC880_HP_EVENT)
8078 alc883_lenovo_101e_all_automute(codec);
8079 if ((res >> 26) == ALC880_FRONT_EVENT)
8080 alc883_lenovo_101e_ispeaker_automute(codec);
8081}
8082
676a9b53
TI
8083/* toggle speaker-output according to the hp-jack state */
8084static void alc883_acer_aspire_automute(struct hda_codec *codec)
8085{
8086 unsigned int present;
ea1fb29a 8087
676a9b53
TI
8088 present = snd_hda_codec_read(codec, 0x14, 0,
8089 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8090 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8091 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8092 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8093 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8094}
8095
8096static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
8097 unsigned int res)
8098{
8099 if ((res >> 26) == ALC880_HP_EVENT)
8100 alc883_acer_aspire_automute(codec);
8101}
8102
d1a991a6
KY
8103static struct hda_verb alc883_acer_eapd_verbs[] = {
8104 /* HP Pin: output 0 (0x0c) */
8105 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8106 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8107 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8108 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
8109 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8110 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 8111 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
8112 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8113 /* eanable EAPD on medion laptop */
8114 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8115 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
8116 /* enable unsolicited event */
8117 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
8118 { }
8119};
8120
5795b9e6
CM
8121static void alc888_6st_dell_front_automute(struct hda_codec *codec)
8122{
8123 unsigned int present;
ea1fb29a 8124
5795b9e6
CM
8125 present = snd_hda_codec_read(codec, 0x1b, 0,
8126 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8127 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8128 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8129 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8130 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8131 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8132 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8133 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8134 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8135}
8136
8137static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
8138 unsigned int res)
8139{
8140 switch (res >> 26) {
8141 case ALC880_HP_EVENT:
8142 printk("hp_event\n");
8143 alc888_6st_dell_front_automute(codec);
8144 break;
8145 }
8146}
8147
e2757d5e
KY
8148static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
8149{
8150 unsigned int mute;
8151 unsigned int present;
8152
8153 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8154 present = snd_hda_codec_read(codec, 0x1b, 0,
8155 AC_VERB_GET_PIN_SENSE, 0);
8156 present = (present & 0x80000000) != 0;
8157 if (present) {
8158 /* mute internal speaker */
8159 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8160 HDA_AMP_MUTE, HDA_AMP_MUTE);
8161 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8162 HDA_AMP_MUTE, HDA_AMP_MUTE);
8163 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8164 HDA_AMP_MUTE, HDA_AMP_MUTE);
8165 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8166 HDA_AMP_MUTE, HDA_AMP_MUTE);
8167 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8168 HDA_AMP_MUTE, HDA_AMP_MUTE);
8169 } else {
8170 /* unmute internal speaker if necessary */
8171 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8172 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8173 HDA_AMP_MUTE, mute);
8174 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8175 HDA_AMP_MUTE, mute);
8176 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8177 HDA_AMP_MUTE, mute);
8178 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8179 HDA_AMP_MUTE, mute);
8180 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8181 HDA_AMP_MUTE, mute);
8182 }
8183}
8184
8185static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
8186 unsigned int res)
8187{
8188 if ((res >> 26) == ALC880_HP_EVENT)
8189 alc888_lenovo_sky_front_automute(codec);
8190}
8191
9c7f852e
TI
8192/*
8193 * generic initialization of ADC, input mixers and output mixers
8194 */
8195static struct hda_verb alc883_auto_init_verbs[] = {
8196 /*
8197 * Unmute ADC0-2 and set the default input to mic-in
8198 */
8199 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8200 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8201 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8202 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8203
cb53c626 8204 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 8205 * mixer widget
f12ab1e0
TI
8206 * Note: PASD motherboards uses the Line In 2 as the input for
8207 * front panel mic (mic 2)
9c7f852e
TI
8208 */
8209 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8210 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8211 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8212 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8213 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8214 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
8215
8216 /*
8217 * Set up output mixers (0x0c - 0x0f)
8218 */
8219 /* set vol=0 to output mixers */
8220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8221 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8222 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8223 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8224 /* set up input amps for analog loopback */
8225 /* Amp Indices: DAC = 0, mixer = 1 */
8226 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8227 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8228 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8229 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8230 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8231 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8232 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8233 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8234 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8235 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8236
8237 /* FIXME: use matrix-type input source selection */
8238 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8239 /* Input mixer1 */
8240 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8241 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8242 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 8243 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
9c7f852e
TI
8244 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8245 /* Input mixer2 */
8246 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8247 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8248 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 8249 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
e3cde64a 8250 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
9c7f852e
TI
8251
8252 { }
8253};
8254
8255/* capture mixer elements */
8256static struct snd_kcontrol_new alc883_capture_mixer[] = {
8257 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8258 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8259 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
8260 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
8261 {
8262 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8263 /* The multiple "Capture Source" controls confuse alsamixer
8264 * So call somewhat different..
9c7f852e
TI
8265 */
8266 /* .name = "Capture Source", */
8267 .name = "Input Source",
8268 .count = 2,
8269 .info = alc882_mux_enum_info,
8270 .get = alc882_mux_enum_get,
8271 .put = alc882_mux_enum_put,
8272 },
8273 { } /* end */
8274};
8275
e2757d5e
KY
8276static struct hda_verb alc888_asus_m90v_verbs[] = {
8277 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8278 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8279 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8280 /* enable unsolicited event */
8281 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8282 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8283 { } /* end */
8284};
8285
8286static void alc883_nb_mic_automute(struct hda_codec *codec)
8287{
8288 unsigned int present;
8289
8290 present = snd_hda_codec_read(codec, 0x18, 0,
8291 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8292 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8293 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8294 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8295 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8296}
8297
8298static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8299{
8300 unsigned int present;
8301 unsigned char bits;
8302
8303 present = snd_hda_codec_read(codec, 0x1b, 0,
8304 AC_VERB_GET_PIN_SENSE, 0)
8305 & AC_PINSENSE_PRESENCE;
8306 bits = present ? 0 : PIN_OUT;
8307 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8308 bits);
8309 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8310 bits);
8311 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8312 bits);
8313}
8314
8315static void alc883_mode2_unsol_event(struct hda_codec *codec,
8316 unsigned int res)
8317{
8318 switch (res >> 26) {
8319 case ALC880_HP_EVENT:
8320 alc883_M90V_speaker_automute(codec);
8321 break;
8322 case ALC880_MIC_EVENT:
8323 alc883_nb_mic_automute(codec);
8324 break;
8325 }
8326}
8327
8328static void alc883_mode2_inithook(struct hda_codec *codec)
8329{
8330 alc883_M90V_speaker_automute(codec);
8331 alc883_nb_mic_automute(codec);
8332}
8333
8334static struct hda_verb alc888_asus_eee1601_verbs[] = {
8335 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8336 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8337 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8338 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8339 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8340 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8341 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8342 /* enable unsolicited event */
8343 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8344 { } /* end */
8345};
8346
8347static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8348{
8349 unsigned int present;
8350 unsigned char bits;
8351
8352 present = snd_hda_codec_read(codec, 0x14, 0,
8353 AC_VERB_GET_PIN_SENSE, 0)
8354 & AC_PINSENSE_PRESENCE;
8355 bits = present ? 0 : PIN_OUT;
8356 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8357 bits);
8358}
8359
8360static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8361 unsigned int res)
8362{
8363 switch (res >> 26) {
8364 case ALC880_HP_EVENT:
8365 alc883_eee1601_speaker_automute(codec);
8366 break;
8367 }
8368}
8369
8370static void alc883_eee1601_inithook(struct hda_codec *codec)
8371{
8372 alc883_eee1601_speaker_automute(codec);
8373}
8374
cb53c626
TI
8375#ifdef CONFIG_SND_HDA_POWER_SAVE
8376#define alc883_loopbacks alc880_loopbacks
8377#endif
8378
9c7f852e
TI
8379/* pcm configuration: identiacal with ALC880 */
8380#define alc883_pcm_analog_playback alc880_pcm_analog_playback
8381#define alc883_pcm_analog_capture alc880_pcm_analog_capture
6330079f 8382#define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
9c7f852e
TI
8383#define alc883_pcm_digital_playback alc880_pcm_digital_playback
8384#define alc883_pcm_digital_capture alc880_pcm_digital_capture
8385
8386/*
8387 * configuration and preset
8388 */
f5fcc13c
TI
8389static const char *alc883_models[ALC883_MODEL_LAST] = {
8390 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8391 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8392 [ALC883_3ST_6ch] = "3stack-6ch",
8393 [ALC883_6ST_DIG] = "6stack-dig",
8394 [ALC883_TARGA_DIG] = "targa-dig",
8395 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
f5fcc13c 8396 [ALC883_ACER] = "acer",
2880a867 8397 [ALC883_ACER_ASPIRE] = "acer-aspire",
f5fcc13c 8398 [ALC883_MEDION] = "medion",
272a527c 8399 [ALC883_MEDION_MD2] = "medion-md2",
f5fcc13c 8400 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 8401 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
8402 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8403 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 8404 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 8405 [ALC883_HAIER_W66] = "haier-w66",
4723c022 8406 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 8407 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 8408 [ALC883_MITAC] = "mitac",
0c4cc443 8409 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 8410 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
17bba1b7 8411 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
f5fcc13c
TI
8412 [ALC883_AUTO] = "auto",
8413};
8414
8415static struct snd_pci_quirk alc883_cfg_tbl[] = {
8416 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
ac3e3741
TI
8417 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8418 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8419 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 8420 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
ac3e3741 8421 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
5795b9e6 8422 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
febe3375 8423 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
8424 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8425 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 8426 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
a01c30cb 8427 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
ac3e3741 8428 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
e2757d5e 8429 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
97ec710c 8430 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
f5fcc13c 8431 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
ac3e3741
TI
8432 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8433 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 8434 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 8435 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
57b14f24 8436 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6f3bf657 8437 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 8438 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8439 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4383fae0 8440 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
dd146a60 8441 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 8442 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 8443 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8444 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
8445 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8446 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 8447 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 8448 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
8449 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8450 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8451 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
ac3e3741
TI
8452 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8453 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8454 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
86d34b7e 8455 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
8456 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8457 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
f5fcc13c 8458 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 8459 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
0c4cc443
HRK
8460 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8461 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
ac3e3741 8462 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 8463 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
f5fcc13c 8464 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
fb97dc67 8465 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
272a527c 8466 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 8467 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
8468 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8469 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 8470 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
272a527c 8471 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
0b167bf4 8472 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 8473 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
17bba1b7
J
8474 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8475 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
ac3e3741 8476 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9c7f852e
TI
8477 {}
8478};
8479
8480static struct alc_config_preset alc883_presets[] = {
8481 [ALC883_3ST_2ch_DIG] = {
8482 .mixers = { alc883_3ST_2ch_mixer },
8483 .init_verbs = { alc883_init_verbs },
8484 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8485 .dac_nids = alc883_dac_nids,
8486 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8487 .dig_in_nid = ALC883_DIGIN_NID,
8488 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8489 .channel_mode = alc883_3ST_2ch_modes,
8490 .input_mux = &alc883_capture_source,
8491 },
8492 [ALC883_3ST_6ch_DIG] = {
8493 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8494 .init_verbs = { alc883_init_verbs },
8495 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8496 .dac_nids = alc883_dac_nids,
8497 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8498 .dig_in_nid = ALC883_DIGIN_NID,
8499 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8500 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 8501 .need_dac_fix = 1,
9c7f852e 8502 .input_mux = &alc883_capture_source,
f12ab1e0 8503 },
9c7f852e
TI
8504 [ALC883_3ST_6ch] = {
8505 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8506 .init_verbs = { alc883_init_verbs },
8507 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8508 .dac_nids = alc883_dac_nids,
9c7f852e
TI
8509 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8510 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 8511 .need_dac_fix = 1,
9c7f852e 8512 .input_mux = &alc883_capture_source,
f12ab1e0 8513 },
17bba1b7
J
8514 [ALC883_3ST_6ch_INTEL] = {
8515 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8516 .init_verbs = { alc883_init_verbs },
8517 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8518 .dac_nids = alc883_dac_nids,
8519 .dig_out_nid = ALC883_DIGOUT_NID,
8520 .dig_in_nid = ALC883_DIGIN_NID,
8521 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8522 .channel_mode = alc883_3ST_6ch_intel_modes,
8523 .need_dac_fix = 1,
8524 .input_mux = &alc883_3stack_6ch_intel,
8525 },
9c7f852e
TI
8526 [ALC883_6ST_DIG] = {
8527 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8528 .init_verbs = { alc883_init_verbs },
8529 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8530 .dac_nids = alc883_dac_nids,
8531 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
8532 .dig_in_nid = ALC883_DIGIN_NID,
8533 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8534 .channel_mode = alc883_sixstack_modes,
8535 .input_mux = &alc883_capture_source,
8536 },
ccc656ce
KY
8537 [ALC883_TARGA_DIG] = {
8538 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8539 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8540 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8541 .dac_nids = alc883_dac_nids,
8542 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
8543 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8544 .channel_mode = alc883_3ST_6ch_modes,
8545 .need_dac_fix = 1,
8546 .input_mux = &alc883_capture_source,
8547 .unsol_event = alc883_tagra_unsol_event,
8548 .init_hook = alc883_tagra_automute,
8549 },
8550 [ALC883_TARGA_2ch_DIG] = {
8551 .mixers = { alc883_tagra_2ch_mixer},
8552 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8553 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8554 .dac_nids = alc883_dac_nids,
8555 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
8556 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8557 .channel_mode = alc883_3ST_2ch_modes,
8558 .input_mux = &alc883_capture_source,
8559 .unsol_event = alc883_tagra_unsol_event,
8560 .init_hook = alc883_tagra_automute,
8561 },
bab282b9 8562 [ALC883_ACER] = {
676a9b53 8563 .mixers = { alc883_base_mixer },
bab282b9
VA
8564 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8565 * and the headphone jack. Turn this on and rely on the
8566 * standard mute methods whenever the user wants to turn
8567 * these outputs off.
8568 */
8569 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8570 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8571 .dac_nids = alc883_dac_nids,
bab282b9
VA
8572 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8573 .channel_mode = alc883_3ST_2ch_modes,
8574 .input_mux = &alc883_capture_source,
8575 },
2880a867 8576 [ALC883_ACER_ASPIRE] = {
676a9b53 8577 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 8578 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
8579 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8580 .dac_nids = alc883_dac_nids,
8581 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
8582 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8583 .channel_mode = alc883_3ST_2ch_modes,
8584 .input_mux = &alc883_capture_source,
676a9b53
TI
8585 .unsol_event = alc883_acer_aspire_unsol_event,
8586 .init_hook = alc883_acer_aspire_automute,
d1a991a6 8587 },
c07584c8
TD
8588 [ALC883_MEDION] = {
8589 .mixers = { alc883_fivestack_mixer,
8590 alc883_chmode_mixer },
8591 .init_verbs = { alc883_init_verbs,
b373bdeb 8592 alc883_medion_eapd_verbs },
c07584c8
TD
8593 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8594 .dac_nids = alc883_dac_nids,
c07584c8
TD
8595 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8596 .channel_mode = alc883_sixstack_modes,
8597 .input_mux = &alc883_capture_source,
b373bdeb 8598 },
272a527c
KY
8599 [ALC883_MEDION_MD2] = {
8600 .mixers = { alc883_medion_md2_mixer},
8601 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8602 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8603 .dac_nids = alc883_dac_nids,
8604 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
8605 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8606 .channel_mode = alc883_3ST_2ch_modes,
8607 .input_mux = &alc883_capture_source,
8608 .unsol_event = alc883_medion_md2_unsol_event,
8609 .init_hook = alc883_medion_md2_automute,
ea1fb29a 8610 },
b373bdeb 8611 [ALC883_LAPTOP_EAPD] = {
676a9b53 8612 .mixers = { alc883_base_mixer },
b373bdeb
AN
8613 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8614 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8615 .dac_nids = alc883_dac_nids,
b373bdeb
AN
8616 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8617 .channel_mode = alc883_3ST_2ch_modes,
8618 .input_mux = &alc883_capture_source,
8619 },
0c4cc443
HRK
8620 [ALC883_CLEVO_M720] = {
8621 .mixers = { alc883_clevo_m720_mixer },
8622 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
8623 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8624 .dac_nids = alc883_dac_nids,
8625 .dig_out_nid = ALC883_DIGOUT_NID,
8626 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8627 .channel_mode = alc883_3ST_2ch_modes,
8628 .input_mux = &alc883_capture_source,
0c4cc443
HRK
8629 .unsol_event = alc883_clevo_m720_unsol_event,
8630 .init_hook = alc883_clevo_m720_automute,
368c7a95 8631 },
bc9f98a9
KY
8632 [ALC883_LENOVO_101E_2ch] = {
8633 .mixers = { alc883_lenovo_101e_2ch_mixer},
8634 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8635 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8636 .dac_nids = alc883_dac_nids,
bc9f98a9
KY
8637 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8638 .channel_mode = alc883_3ST_2ch_modes,
8639 .input_mux = &alc883_lenovo_101e_capture_source,
8640 .unsol_event = alc883_lenovo_101e_unsol_event,
8641 .init_hook = alc883_lenovo_101e_all_automute,
8642 },
272a527c
KY
8643 [ALC883_LENOVO_NB0763] = {
8644 .mixers = { alc883_lenovo_nb0763_mixer },
8645 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8646 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8647 .dac_nids = alc883_dac_nids,
272a527c
KY
8648 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8649 .channel_mode = alc883_3ST_2ch_modes,
8650 .need_dac_fix = 1,
8651 .input_mux = &alc883_lenovo_nb0763_capture_source,
8652 .unsol_event = alc883_medion_md2_unsol_event,
8653 .init_hook = alc883_medion_md2_automute,
8654 },
8655 [ALC888_LENOVO_MS7195_DIG] = {
8656 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8657 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8658 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8659 .dac_nids = alc883_dac_nids,
8660 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
8661 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8662 .channel_mode = alc883_3ST_6ch_modes,
8663 .need_dac_fix = 1,
8664 .input_mux = &alc883_capture_source,
8665 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8666 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
8667 },
8668 [ALC883_HAIER_W66] = {
8669 .mixers = { alc883_tagra_2ch_mixer},
8670 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8671 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8672 .dac_nids = alc883_dac_nids,
8673 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
8674 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8675 .channel_mode = alc883_3ST_2ch_modes,
8676 .input_mux = &alc883_capture_source,
8677 .unsol_event = alc883_haier_w66_unsol_event,
8678 .init_hook = alc883_haier_w66_automute,
eea6419e 8679 },
4723c022 8680 [ALC888_3ST_HP] = {
eea6419e 8681 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 8682 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
8683 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8684 .dac_nids = alc883_dac_nids,
4723c022
CM
8685 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8686 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
8687 .need_dac_fix = 1,
8688 .input_mux = &alc883_capture_source,
8689 },
5795b9e6 8690 [ALC888_6ST_DELL] = {
f24dbdc6 8691 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
8692 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8693 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8694 .dac_nids = alc883_dac_nids,
8695 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
8696 .dig_in_nid = ALC883_DIGIN_NID,
8697 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8698 .channel_mode = alc883_sixstack_modes,
8699 .input_mux = &alc883_capture_source,
8700 .unsol_event = alc888_6st_dell_unsol_event,
8701 .init_hook = alc888_6st_dell_front_automute,
8702 },
a8848bd6
AS
8703 [ALC883_MITAC] = {
8704 .mixers = { alc883_mitac_mixer },
8705 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8706 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8707 .dac_nids = alc883_dac_nids,
a8848bd6
AS
8708 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8709 .channel_mode = alc883_3ST_2ch_modes,
8710 .input_mux = &alc883_capture_source,
8711 .unsol_event = alc883_mitac_unsol_event,
8712 .init_hook = alc883_mitac_automute,
8713 },
fb97dc67
J
8714 [ALC883_FUJITSU_PI2515] = {
8715 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8716 .init_verbs = { alc883_init_verbs,
8717 alc883_2ch_fujitsu_pi2515_verbs},
8718 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8719 .dac_nids = alc883_dac_nids,
8720 .dig_out_nid = ALC883_DIGOUT_NID,
8721 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8722 .channel_mode = alc883_3ST_2ch_modes,
8723 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8724 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8725 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
8726 },
e2757d5e
KY
8727 [ALC888_LENOVO_SKY] = {
8728 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8729 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8730 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8731 .dac_nids = alc883_dac_nids,
8732 .dig_out_nid = ALC883_DIGOUT_NID,
8733 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
8734 .adc_nids = alc883_adc_nids,
8735 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8736 .channel_mode = alc883_sixstack_modes,
8737 .need_dac_fix = 1,
8738 .input_mux = &alc883_lenovo_sky_capture_source,
8739 .unsol_event = alc883_lenovo_sky_unsol_event,
8740 .init_hook = alc888_lenovo_sky_front_automute,
8741 },
8742 [ALC888_ASUS_M90V] = {
8743 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8744 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8745 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8746 .dac_nids = alc883_dac_nids,
8747 .dig_out_nid = ALC883_DIGOUT_NID,
8748 .dig_in_nid = ALC883_DIGIN_NID,
8749 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8750 .channel_mode = alc883_3ST_6ch_modes,
8751 .need_dac_fix = 1,
8752 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8753 .unsol_event = alc883_mode2_unsol_event,
8754 .init_hook = alc883_mode2_inithook,
8755 },
8756 [ALC888_ASUS_EEE1601] = {
8757 .mixers = { alc883_asus_eee1601_mixer },
8758 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
8759 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8760 .dac_nids = alc883_dac_nids,
8761 .dig_out_nid = ALC883_DIGOUT_NID,
8762 .dig_in_nid = ALC883_DIGIN_NID,
8763 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8764 .channel_mode = alc883_3ST_2ch_modes,
8765 .need_dac_fix = 1,
8766 .input_mux = &alc883_asus_eee1601_capture_source,
8767 .unsol_event = alc883_eee1601_unsol_event,
8768 .init_hook = alc883_eee1601_inithook,
8769 },
9c7f852e
TI
8770};
8771
8772
8773/*
8774 * BIOS auto configuration
8775 */
8776static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8777 hda_nid_t nid, int pin_type,
8778 int dac_idx)
8779{
8780 /* set as output */
8781 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
8782 int idx;
8783
f6c7e546 8784 alc_set_pin_output(codec, nid, pin_type);
9c7f852e
TI
8785 if (spec->multiout.dac_nids[dac_idx] == 0x25)
8786 idx = 4;
8787 else
8788 idx = spec->multiout.dac_nids[dac_idx] - 2;
9c7f852e
TI
8789 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8790
8791}
8792
8793static void alc883_auto_init_multi_out(struct hda_codec *codec)
8794{
8795 struct alc_spec *spec = codec->spec;
8796 int i;
8797
bc9f98a9 8798 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
9c7f852e 8799 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 8800 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 8801 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 8802 if (nid)
baba8ee9 8803 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 8804 i);
9c7f852e
TI
8805 }
8806}
8807
8808static void alc883_auto_init_hp_out(struct hda_codec *codec)
8809{
8810 struct alc_spec *spec = codec->spec;
8811 hda_nid_t pin;
8812
eb06ed8f 8813 pin = spec->autocfg.hp_pins[0];
9c7f852e
TI
8814 if (pin) /* connect to front */
8815 /* use dac 0 */
8816 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
8817 pin = spec->autocfg.speaker_pins[0];
8818 if (pin)
8819 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9c7f852e
TI
8820}
8821
8822#define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
8823#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
8824
8825static void alc883_auto_init_analog_input(struct hda_codec *codec)
8826{
8827 struct alc_spec *spec = codec->spec;
8828 int i;
8829
8830 for (i = 0; i < AUTO_PIN_LAST; i++) {
8831 hda_nid_t nid = spec->autocfg.input_pins[i];
8832 if (alc883_is_input_pin(nid)) {
8833 snd_hda_codec_write(codec, nid, 0,
8834 AC_VERB_SET_PIN_WIDGET_CONTROL,
8835 (i <= AUTO_PIN_FRONT_MIC ?
8836 PIN_VREF80 : PIN_IN));
8837 if (nid != ALC883_PIN_CD_NID)
8838 snd_hda_codec_write(codec, nid, 0,
8839 AC_VERB_SET_AMP_GAIN_MUTE,
8840 AMP_OUT_MUTE);
8841 }
8842 }
8843}
8844
f511b01c
TI
8845#define alc883_auto_init_input_src alc882_auto_init_input_src
8846
9c7f852e
TI
8847/* almost identical with ALC880 parser... */
8848static int alc883_parse_auto_config(struct hda_codec *codec)
8849{
8850 struct alc_spec *spec = codec->spec;
8851 int err = alc880_parse_auto_config(codec);
8852
8853 if (err < 0)
8854 return err;
776e184e
TI
8855 else if (!err)
8856 return 0; /* no config found */
8857
8858 err = alc_auto_add_mic_boost(codec);
8859 if (err < 0)
8860 return err;
8861
8862 /* hack - override the init verbs */
8863 spec->init_verbs[0] = alc883_auto_init_verbs;
d88897ea 8864 add_mixer(spec, alc883_capture_mixer);
776e184e
TI
8865
8866 return 1; /* config found */
9c7f852e
TI
8867}
8868
8869/* additional initialization for auto-configuration model */
8870static void alc883_auto_init(struct hda_codec *codec)
8871{
f6c7e546 8872 struct alc_spec *spec = codec->spec;
9c7f852e
TI
8873 alc883_auto_init_multi_out(codec);
8874 alc883_auto_init_hp_out(codec);
8875 alc883_auto_init_analog_input(codec);
f511b01c 8876 alc883_auto_init_input_src(codec);
f6c7e546 8877 if (spec->unsol_event)
7fb0d78f 8878 alc_inithook(codec);
9c7f852e
TI
8879}
8880
8881static int patch_alc883(struct hda_codec *codec)
8882{
8883 struct alc_spec *spec;
8884 int err, board_config;
8885
8886 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8887 if (spec == NULL)
8888 return -ENOMEM;
8889
8890 codec->spec = spec;
8891
2c3bf9ab
TI
8892 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
8893
f5fcc13c
TI
8894 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8895 alc883_models,
8896 alc883_cfg_tbl);
8897 if (board_config < 0) {
9c7f852e
TI
8898 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8899 "trying auto-probe from BIOS...\n");
8900 board_config = ALC883_AUTO;
8901 }
8902
8903 if (board_config == ALC883_AUTO) {
8904 /* automatic parse from the BIOS config */
8905 err = alc883_parse_auto_config(codec);
8906 if (err < 0) {
8907 alc_free(codec);
8908 return err;
f12ab1e0 8909 } else if (!err) {
9c7f852e
TI
8910 printk(KERN_INFO
8911 "hda_codec: Cannot set up configuration "
8912 "from BIOS. Using base mode...\n");
8913 board_config = ALC883_3ST_2ch_DIG;
8914 }
8915 }
8916
8917 if (board_config != ALC883_AUTO)
8918 setup_preset(spec, &alc883_presets[board_config]);
8919
2f893286
KY
8920 switch (codec->vendor_id) {
8921 case 0x10ec0888:
4442608d
KY
8922 if (codec->revision_id == 0x100101) {
8923 spec->stream_name_analog = "ALC1200 Analog";
8924 spec->stream_name_digital = "ALC1200 Digital";
8925 } else {
8926 spec->stream_name_analog = "ALC888 Analog";
8927 spec->stream_name_digital = "ALC888 Digital";
8928 }
2f893286
KY
8929 break;
8930 case 0x10ec0889:
8931 spec->stream_name_analog = "ALC889 Analog";
8932 spec->stream_name_digital = "ALC889 Digital";
8933 break;
8934 default:
8935 spec->stream_name_analog = "ALC883 Analog";
8936 spec->stream_name_digital = "ALC883 Digital";
8937 break;
8938 }
8939
9c7f852e
TI
8940 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8941 spec->stream_analog_capture = &alc883_pcm_analog_capture;
6330079f 8942 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9c7f852e 8943
9c7f852e
TI
8944 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8945 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8946
e1406348
TI
8947 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8948 spec->adc_nids = alc883_adc_nids;
8949 spec->capsrc_nids = alc883_capsrc_nids;
9c7f852e 8950
2134ea4f
TI
8951 spec->vmaster_nid = 0x0c;
8952
9c7f852e
TI
8953 codec->patch_ops = alc_patch_ops;
8954 if (board_config == ALC883_AUTO)
8955 spec->init_hook = alc883_auto_init;
f9423e7a 8956
cb53c626
TI
8957#ifdef CONFIG_SND_HDA_POWER_SAVE
8958 if (!spec->loopback.amplist)
8959 spec->loopback.amplist = alc883_loopbacks;
8960#endif
9c7f852e
TI
8961
8962 return 0;
8963}
8964
8965/*
8966 * ALC262 support
8967 */
8968
8969#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
8970#define ALC262_DIGIN_NID ALC880_DIGIN_NID
8971
8972#define alc262_dac_nids alc260_dac_nids
8973#define alc262_adc_nids alc882_adc_nids
8974#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
8975#define alc262_capsrc_nids alc882_capsrc_nids
8976#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
8977
8978#define alc262_modes alc260_modes
8979#define alc262_capture_source alc882_capture_source
8980
4e555fe5
KY
8981static hda_nid_t alc262_dmic_adc_nids[1] = {
8982 /* ADC0 */
8983 0x09
8984};
8985
8986static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
8987
9c7f852e
TI
8988static struct snd_kcontrol_new alc262_base_mixer[] = {
8989 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8990 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8991 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8992 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8993 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8994 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8997 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8998 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8999 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 9000 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 9001 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
31bffaa9 9002 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
9c7f852e
TI
9003 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9004 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9005 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9006 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9007 { } /* end */
9008};
9009
ccc656ce
KY
9010static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9011 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9012 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9013 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9014 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9015 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9016 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9017 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9018 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9019 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
9020 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9021 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 9022 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
ccc656ce 9023 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
31bffaa9 9024 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
ccc656ce
KY
9025 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
9026 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9027 { } /* end */
9028};
9029
ce875f07
TI
9030/* update HP, line and mono-out pins according to the master switch */
9031static void alc262_hp_master_update(struct hda_codec *codec)
9032{
9033 struct alc_spec *spec = codec->spec;
9034 int val = spec->master_sw;
9035
9036 /* HP & line-out */
9037 snd_hda_codec_write_cache(codec, 0x1b, 0,
9038 AC_VERB_SET_PIN_WIDGET_CONTROL,
9039 val ? PIN_HP : 0);
9040 snd_hda_codec_write_cache(codec, 0x15, 0,
9041 AC_VERB_SET_PIN_WIDGET_CONTROL,
9042 val ? PIN_HP : 0);
9043 /* mono (speaker) depending on the HP jack sense */
9044 val = val && !spec->jack_present;
9045 snd_hda_codec_write_cache(codec, 0x16, 0,
9046 AC_VERB_SET_PIN_WIDGET_CONTROL,
9047 val ? PIN_OUT : 0);
9048}
9049
9050static void alc262_hp_bpc_automute(struct hda_codec *codec)
9051{
9052 struct alc_spec *spec = codec->spec;
9053 unsigned int presence;
9054 presence = snd_hda_codec_read(codec, 0x1b, 0,
9055 AC_VERB_GET_PIN_SENSE, 0);
9056 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9057 alc262_hp_master_update(codec);
9058}
9059
9060static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9061{
9062 if ((res >> 26) != ALC880_HP_EVENT)
9063 return;
9064 alc262_hp_bpc_automute(codec);
9065}
9066
9067static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9068{
9069 struct alc_spec *spec = codec->spec;
9070 unsigned int presence;
9071 presence = snd_hda_codec_read(codec, 0x15, 0,
9072 AC_VERB_GET_PIN_SENSE, 0);
9073 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9074 alc262_hp_master_update(codec);
9075}
9076
9077static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9078 unsigned int res)
9079{
9080 if ((res >> 26) != ALC880_HP_EVENT)
9081 return;
9082 alc262_hp_wildwest_automute(codec);
9083}
9084
9085static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
9086 struct snd_ctl_elem_value *ucontrol)
9087{
9088 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9089 struct alc_spec *spec = codec->spec;
9090 *ucontrol->value.integer.value = spec->master_sw;
9091 return 0;
9092}
9093
9094static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9095 struct snd_ctl_elem_value *ucontrol)
9096{
9097 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9098 struct alc_spec *spec = codec->spec;
9099 int val = !!*ucontrol->value.integer.value;
9100
9101 if (val == spec->master_sw)
9102 return 0;
9103 spec->master_sw = val;
9104 alc262_hp_master_update(codec);
9105 return 1;
9106}
9107
9c7f852e 9108static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
ce875f07
TI
9109 {
9110 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9111 .name = "Master Playback Switch",
9112 .info = snd_ctl_boolean_mono_info,
9113 .get = alc262_hp_master_sw_get,
9114 .put = alc262_hp_master_sw_put,
9115 },
9c7f852e
TI
9116 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9117 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9118 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
9119 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9120 HDA_OUTPUT),
9121 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9122 HDA_OUTPUT),
9c7f852e
TI
9123 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9124 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9125 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9126 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9127 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 9128 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
9129 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9130 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9131 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9132 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9133 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9134 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9135 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9136 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9137 { } /* end */
9138};
9139
cd7509a4 9140static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
ce875f07
TI
9141 {
9142 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9143 .name = "Master Playback Switch",
9144 .info = snd_ctl_boolean_mono_info,
9145 .get = alc262_hp_master_sw_get,
9146 .put = alc262_hp_master_sw_put,
9147 },
cd7509a4
KY
9148 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9149 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9150 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9151 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
9152 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9153 HDA_OUTPUT),
9154 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9155 HDA_OUTPUT),
cd7509a4
KY
9156 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9157 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 9158 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
9159 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9160 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9161 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9162 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9163 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9164 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9165 { } /* end */
9166};
9167
9168static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9169 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9170 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 9171 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
9172 { } /* end */
9173};
9174
66d2a9d6
KY
9175/* mute/unmute internal speaker according to the hp jack and mute state */
9176static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
9177{
9178 struct alc_spec *spec = codec->spec;
66d2a9d6
KY
9179
9180 if (force || !spec->sense_updated) {
9181 unsigned int present;
9182 present = snd_hda_codec_read(codec, 0x15, 0,
9183 AC_VERB_GET_PIN_SENSE, 0);
4bb26130 9184 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
66d2a9d6
KY
9185 spec->sense_updated = 1;
9186 }
4bb26130
TI
9187 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9188 spec->jack_present ? HDA_AMP_MUTE : 0);
66d2a9d6
KY
9189}
9190
9191static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9192 unsigned int res)
9193{
9194 if ((res >> 26) != ALC880_HP_EVENT)
9195 return;
9196 alc262_hp_t5735_automute(codec, 1);
9197}
9198
9199static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9200{
9201 alc262_hp_t5735_automute(codec, 1);
9202}
9203
9204static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
9205 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9206 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
9207 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9208 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9209 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9210 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9211 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9212 { } /* end */
9213};
9214
9215static struct hda_verb alc262_hp_t5735_verbs[] = {
9216 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9217 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9218
9219 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9220 { }
9221};
9222
8c427226 9223static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
9224 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9225 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
9226 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9227 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
9228 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9229 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9230 { } /* end */
9231};
9232
9233static struct hda_verb alc262_hp_rp5700_verbs[] = {
9234 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9235 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9236 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9237 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9238 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9239 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9240 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9241 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9242 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9243 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9244 {}
9245};
9246
9247static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9248 .num_items = 1,
9249 .items = {
9250 { "Line", 0x1 },
9251 },
9252};
9253
0724ea2a
TI
9254/* bind hp and internal speaker mute (with plug check) */
9255static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9256 struct snd_ctl_elem_value *ucontrol)
9257{
9258 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9259 long *valp = ucontrol->value.integer.value;
9260 int change;
9261
9262 /* change hp mute */
9263 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9264 HDA_AMP_MUTE,
9265 valp[0] ? 0 : HDA_AMP_MUTE);
9266 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9267 HDA_AMP_MUTE,
9268 valp[1] ? 0 : HDA_AMP_MUTE);
9269 if (change) {
9270 /* change speaker according to HP jack state */
9271 struct alc_spec *spec = codec->spec;
9272 unsigned int mute;
9273 if (spec->jack_present)
9274 mute = HDA_AMP_MUTE;
9275 else
9276 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9277 HDA_OUTPUT, 0);
9278 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9279 HDA_AMP_MUTE, mute);
9280 }
9281 return change;
9282}
5b31954e 9283
272a527c 9284static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a
TI
9285 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9286 {
9287 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9288 .name = "Master Playback Switch",
9289 .info = snd_hda_mixer_amp_switch_info,
9290 .get = snd_hda_mixer_amp_switch_get,
9291 .put = alc262_sony_master_sw_put,
9292 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9293 },
272a527c
KY
9294 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9295 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9296 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9297 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9298 { } /* end */
9299};
9300
83c34218
KY
9301static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9302 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9303 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9304 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9305 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9306 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9307 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9308 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9309 { } /* end */
9310};
272a527c 9311
9c7f852e
TI
9312#define alc262_capture_mixer alc882_capture_mixer
9313#define alc262_capture_alt_mixer alc882_capture_alt_mixer
9314
9315/*
9316 * generic initialization of ADC, input mixers and output mixers
9317 */
9318static struct hda_verb alc262_init_verbs[] = {
9319 /*
9320 * Unmute ADC0-2 and set the default input to mic-in
9321 */
9322 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9323 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9324 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9325 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9326 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9327 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9328
cb53c626 9329 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 9330 * mixer widget
f12ab1e0
TI
9331 * Note: PASD motherboards uses the Line In 2 as the input for
9332 * front panel mic (mic 2)
9c7f852e
TI
9333 */
9334 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
9335 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9336 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9337 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9338 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9339 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
9340
9341 /*
df694daa
KY
9342 * Set up output mixers (0x0c - 0x0e)
9343 */
9344 /* set vol=0 to output mixers */
9345 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9346 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9347 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9348 /* set up input amps for analog loopback */
9349 /* Amp Indices: DAC = 0, mixer = 1 */
9350 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9351 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9352 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9353 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9354 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9355 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9356
9357 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9358 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9359 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9360 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9361 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9362 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9363
9364 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9365 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9366 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9367 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9368 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 9369
df694daa
KY
9370 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9371 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 9372
df694daa
KY
9373 /* FIXME: use matrix-type input source selection */
9374 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9375 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9376 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9377 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9378 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9379 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9380 /* Input mixer2 */
9381 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9382 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9383 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9384 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9385 /* Input mixer3 */
9386 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9387 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9388 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 9389 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
9390
9391 { }
9392};
1da177e4 9393
4e555fe5
KY
9394static struct hda_verb alc262_eapd_verbs[] = {
9395 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9396 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9397 { }
9398};
9399
ccc656ce
KY
9400static struct hda_verb alc262_hippo_unsol_verbs[] = {
9401 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9402 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9403 {}
9404};
9405
9406static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9407 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9408 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9409 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9410
9411 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9412 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9413 {}
9414};
9415
272a527c
KY
9416static struct hda_verb alc262_sony_unsol_verbs[] = {
9417 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9418 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9419 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9420
9421 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9422 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 9423 {}
272a527c
KY
9424};
9425
4e555fe5
KY
9426static struct hda_input_mux alc262_dmic_capture_source = {
9427 .num_items = 2,
9428 .items = {
9429 { "Int DMic", 0x9 },
9430 { "Mic", 0x0 },
9431 },
9432};
9433
9434static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9435 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9436 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9437 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9438 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9439 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9440 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9441 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9442 {
9443 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9444 /* The multiple "Capture Source" controls confuse alsamixer
9445 * So call somewhat different..
9446 */
9447 /* .name = "Capture Source", */
9448 .name = "Input Source",
9449 .count = 1,
9450 .info = alc_mux_enum_info,
9451 .get = alc_mux_enum_get,
9452 .put = alc_mux_enum_put,
9453 },
9454 { } /* end */
9455};
9456
9457static struct hda_verb alc262_toshiba_s06_verbs[] = {
9458 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9459 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9460 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9461 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9462 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9463 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9464 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9465 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9466 {}
9467};
9468
9469static void alc262_dmic_automute(struct hda_codec *codec)
9470{
9471 unsigned int present;
9472
9473 present = snd_hda_codec_read(codec, 0x18, 0,
9474 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9475 snd_hda_codec_write(codec, 0x22, 0,
9476 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9477}
9478
9479/* toggle speaker-output according to the hp-jack state */
9480static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9481{
9482 unsigned int present;
9483 unsigned char bits;
9484
9485 present = snd_hda_codec_read(codec, 0x15, 0,
9486 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9487 bits = present ? 0 : PIN_OUT;
9488 snd_hda_codec_write(codec, 0x14, 0,
9489 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9490}
9491
9492
9493
9494/* unsolicited event for HP jack sensing */
9495static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9496 unsigned int res)
9497{
9498 if ((res >> 26) == ALC880_HP_EVENT)
9499 alc262_toshiba_s06_speaker_automute(codec);
9500 if ((res >> 26) == ALC880_MIC_EVENT)
9501 alc262_dmic_automute(codec);
9502
9503}
9504
9505static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9506{
9507 alc262_toshiba_s06_speaker_automute(codec);
9508 alc262_dmic_automute(codec);
9509}
9510
ccc656ce 9511/* mute/unmute internal speaker according to the hp jack and mute state */
5b31954e 9512static void alc262_hippo_automute(struct hda_codec *codec)
ccc656ce
KY
9513{
9514 struct alc_spec *spec = codec->spec;
9515 unsigned int mute;
5b31954e 9516 unsigned int present;
ccc656ce 9517
5b31954e
TI
9518 /* need to execute and sync at first */
9519 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9520 present = snd_hda_codec_read(codec, 0x15, 0,
9521 AC_VERB_GET_PIN_SENSE, 0);
9522 spec->jack_present = (present & 0x80000000) != 0;
ccc656ce
KY
9523 if (spec->jack_present) {
9524 /* mute internal speaker */
47fd830a
TI
9525 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9526 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
9527 } else {
9528 /* unmute internal speaker if necessary */
9529 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
47fd830a
TI
9530 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9531 HDA_AMP_MUTE, mute);
ccc656ce
KY
9532 }
9533}
9534
9535/* unsolicited event for HP jack sensing */
9536static void alc262_hippo_unsol_event(struct hda_codec *codec,
9537 unsigned int res)
9538{
9539 if ((res >> 26) != ALC880_HP_EVENT)
9540 return;
5b31954e 9541 alc262_hippo_automute(codec);
ccc656ce
KY
9542}
9543
5b31954e 9544static void alc262_hippo1_automute(struct hda_codec *codec)
ccc656ce 9545{
ccc656ce 9546 unsigned int mute;
5b31954e 9547 unsigned int present;
ccc656ce 9548
5b31954e
TI
9549 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9550 present = snd_hda_codec_read(codec, 0x1b, 0,
9551 AC_VERB_GET_PIN_SENSE, 0);
9552 present = (present & 0x80000000) != 0;
9553 if (present) {
ccc656ce 9554 /* mute internal speaker */
47fd830a
TI
9555 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9556 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
9557 } else {
9558 /* unmute internal speaker if necessary */
9559 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
47fd830a
TI
9560 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9561 HDA_AMP_MUTE, mute);
ccc656ce
KY
9562 }
9563}
9564
9565/* unsolicited event for HP jack sensing */
9566static void alc262_hippo1_unsol_event(struct hda_codec *codec,
9567 unsigned int res)
9568{
9569 if ((res >> 26) != ALC880_HP_EVENT)
9570 return;
5b31954e 9571 alc262_hippo1_automute(codec);
ccc656ce
KY
9572}
9573
e8f9ae2a
PT
9574/*
9575 * nec model
9576 * 0x15 = headphone
9577 * 0x16 = internal speaker
9578 * 0x18 = external mic
9579 */
9580
9581static struct snd_kcontrol_new alc262_nec_mixer[] = {
9582 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9583 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9584
9585 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9586 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9587 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9588
9589 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9590 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9591 { } /* end */
9592};
9593
9594static struct hda_verb alc262_nec_verbs[] = {
9595 /* Unmute Speaker */
9596 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9597
9598 /* Headphone */
9599 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9600 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9601
9602 /* External mic to headphone */
9603 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9604 /* External mic to speaker */
9605 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9606 {}
9607};
9608
834be88d
TI
9609/*
9610 * fujitsu model
5d9fab2d
TV
9611 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
9612 * 0x1b = port replicator headphone out
834be88d
TI
9613 */
9614
9615#define ALC_HP_EVENT 0x37
9616
9617static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9618 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9619 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
9620 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9621 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
9622 {}
9623};
9624
0e31daf7
J
9625static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9626 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9627 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9628 {}
9629};
9630
834be88d 9631static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 9632 .num_items = 3,
834be88d
TI
9633 .items = {
9634 { "Mic", 0x0 },
39d3ed38 9635 { "Int Mic", 0x1 },
834be88d
TI
9636 { "CD", 0x4 },
9637 },
9638};
9639
9c7f852e
TI
9640static struct hda_input_mux alc262_HP_capture_source = {
9641 .num_items = 5,
9642 .items = {
9643 { "Mic", 0x0 },
accbe498 9644 { "Front Mic", 0x1 },
9c7f852e
TI
9645 { "Line", 0x2 },
9646 { "CD", 0x4 },
9647 { "AUX IN", 0x6 },
9648 },
9649};
9650
accbe498 9651static struct hda_input_mux alc262_HP_D7000_capture_source = {
9652 .num_items = 4,
9653 .items = {
9654 { "Mic", 0x0 },
9655 { "Front Mic", 0x2 },
9656 { "Line", 0x1 },
9657 { "CD", 0x4 },
9658 },
9659};
9660
ebc7a406 9661/* mute/unmute internal speaker according to the hp jacks and mute state */
834be88d
TI
9662static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9663{
9664 struct alc_spec *spec = codec->spec;
9665 unsigned int mute;
9666
f12ab1e0 9667 if (force || !spec->sense_updated) {
ebc7a406 9668 unsigned int present;
834be88d
TI
9669 /* need to execute and sync at first */
9670 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
ebc7a406
TI
9671 /* check laptop HP jack */
9672 present = snd_hda_codec_read(codec, 0x14, 0,
9673 AC_VERB_GET_PIN_SENSE, 0);
9674 /* need to execute and sync at first */
9675 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9676 /* check docking HP jack */
9677 present |= snd_hda_codec_read(codec, 0x1b, 0,
9678 AC_VERB_GET_PIN_SENSE, 0);
9679 if (present & AC_PINSENSE_PRESENCE)
9680 spec->jack_present = 1;
9681 else
9682 spec->jack_present = 0;
834be88d
TI
9683 spec->sense_updated = 1;
9684 }
ebc7a406
TI
9685 /* unmute internal speaker only if both HPs are unplugged and
9686 * master switch is on
9687 */
9688 if (spec->jack_present)
9689 mute = HDA_AMP_MUTE;
9690 else
834be88d 9691 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
ebc7a406
TI
9692 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9693 HDA_AMP_MUTE, mute);
834be88d
TI
9694}
9695
9696/* unsolicited event for HP jack sensing */
9697static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9698 unsigned int res)
9699{
9700 if ((res >> 26) != ALC_HP_EVENT)
9701 return;
9702 alc262_fujitsu_automute(codec, 1);
9703}
9704
ebc7a406
TI
9705static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9706{
9707 alc262_fujitsu_automute(codec, 1);
9708}
9709
834be88d 9710/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
9711static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9712 .ops = &snd_hda_bind_vol,
9713 .values = {
9714 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9715 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9716 0
9717 },
9718};
834be88d 9719
0e31daf7
J
9720/* mute/unmute internal speaker according to the hp jack and mute state */
9721static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9722{
9723 struct alc_spec *spec = codec->spec;
9724 unsigned int mute;
9725
9726 if (force || !spec->sense_updated) {
9727 unsigned int present_int_hp;
9728 /* need to execute and sync at first */
9729 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9730 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
9731 AC_VERB_GET_PIN_SENSE, 0);
9732 spec->jack_present = (present_int_hp & 0x80000000) != 0;
9733 spec->sense_updated = 1;
9734 }
9735 if (spec->jack_present) {
9736 /* mute internal speaker */
9737 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9738 HDA_AMP_MUTE, HDA_AMP_MUTE);
9739 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9740 HDA_AMP_MUTE, HDA_AMP_MUTE);
9741 } else {
9742 /* unmute internal speaker if necessary */
9743 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9744 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9745 HDA_AMP_MUTE, mute);
9746 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9747 HDA_AMP_MUTE, mute);
9748 }
9749}
9750
9751/* unsolicited event for HP jack sensing */
9752static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
9753 unsigned int res)
9754{
9755 if ((res >> 26) != ALC_HP_EVENT)
9756 return;
9757 alc262_lenovo_3000_automute(codec, 1);
9758}
9759
834be88d
TI
9760/* bind hp and internal speaker mute (with plug check) */
9761static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
9762 struct snd_ctl_elem_value *ucontrol)
9763{
9764 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9765 long *valp = ucontrol->value.integer.value;
9766 int change;
9767
5d9fab2d
TV
9768 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9769 HDA_AMP_MUTE,
9770 valp ? 0 : HDA_AMP_MUTE);
9771 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9772 HDA_AMP_MUTE,
9773 valp ? 0 : HDA_AMP_MUTE);
9774
82beb8fd
TI
9775 if (change)
9776 alc262_fujitsu_automute(codec, 0);
834be88d
TI
9777 return change;
9778}
9779
9780static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 9781 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
9782 {
9783 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9784 .name = "Master Playback Switch",
9785 .info = snd_hda_mixer_amp_switch_info,
9786 .get = snd_hda_mixer_amp_switch_get,
9787 .put = alc262_fujitsu_master_sw_put,
9788 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9789 },
9790 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9791 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
06a9c30c
TV
9792 HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
9793 HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
834be88d
TI
9794 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9795 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9796 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
9797 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9798 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9799 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
9800 { } /* end */
9801};
9802
0e31daf7
J
9803/* bind hp and internal speaker mute (with plug check) */
9804static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
9805 struct snd_ctl_elem_value *ucontrol)
9806{
9807 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9808 long *valp = ucontrol->value.integer.value;
9809 int change;
9810
9811 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9812 HDA_AMP_MUTE,
9813 valp ? 0 : HDA_AMP_MUTE);
9814
9815 if (change)
9816 alc262_lenovo_3000_automute(codec, 0);
9817 return change;
9818}
9819
9820static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
9821 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9822 {
9823 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9824 .name = "Master Playback Switch",
9825 .info = snd_hda_mixer_amp_switch_info,
9826 .get = snd_hda_mixer_amp_switch_get,
9827 .put = alc262_lenovo_3000_master_sw_put,
9828 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
9829 },
9830 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9831 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9832 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9833 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9834 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9835 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9836 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9837 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9838 { } /* end */
9839};
9840
9f99a638
HM
9841static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9842 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9843 {
9844 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9845 .name = "Master Playback Switch",
9846 .info = snd_hda_mixer_amp_switch_info,
9847 .get = snd_hda_mixer_amp_switch_get,
9848 .put = alc262_sony_master_sw_put,
9849 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9850 },
9851 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9852 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9853 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9854 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9855 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9856 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9857 { } /* end */
9858};
9859
304dcaac
TI
9860/* additional init verbs for Benq laptops */
9861static struct hda_verb alc262_EAPD_verbs[] = {
9862 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9863 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9864 {}
9865};
9866
83c34218
KY
9867static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
9868 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9869 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9870
9871 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9872 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9873 {}
9874};
9875
f651b50b
TD
9876/* Samsung Q1 Ultra Vista model setup */
9877static struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
9878 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9879 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
9880 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9881 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9882 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
bb9f76cd 9883 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
f651b50b
TD
9884 { } /* end */
9885};
9886
9887static struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
9888 /* output mixer */
9889 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9890 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9891 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9892 /* speaker */
9893 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9894 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9895 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9896 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9897 /* HP */
f651b50b 9898 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
9899 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9900 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9901 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9902 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9903 /* internal mic */
9904 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9905 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9906 /* ADC, choose mic */
9907 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9908 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9909 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9910 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9911 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9912 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9913 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9914 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9915 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9916 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
9917 {}
9918};
9919
f651b50b
TD
9920/* mute/unmute internal speaker according to the hp jack and mute state */
9921static void alc262_ultra_automute(struct hda_codec *codec)
9922{
9923 struct alc_spec *spec = codec->spec;
9924 unsigned int mute;
f651b50b 9925
bb9f76cd
TI
9926 mute = 0;
9927 /* auto-mute only when HP is used as HP */
9928 if (!spec->cur_mux[0]) {
9929 unsigned int present;
9930 /* need to execute and sync at first */
9931 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9932 present = snd_hda_codec_read(codec, 0x15, 0,
9933 AC_VERB_GET_PIN_SENSE, 0);
9934 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9935 if (spec->jack_present)
9936 mute = HDA_AMP_MUTE;
f651b50b 9937 }
bb9f76cd
TI
9938 /* mute/unmute internal speaker */
9939 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9940 HDA_AMP_MUTE, mute);
9941 /* mute/unmute HP */
9942 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9943 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
9944}
9945
9946/* unsolicited event for HP jack sensing */
9947static void alc262_ultra_unsol_event(struct hda_codec *codec,
9948 unsigned int res)
9949{
9950 if ((res >> 26) != ALC880_HP_EVENT)
9951 return;
9952 alc262_ultra_automute(codec);
9953}
9954
bb9f76cd
TI
9955static struct hda_input_mux alc262_ultra_capture_source = {
9956 .num_items = 2,
9957 .items = {
9958 { "Mic", 0x1 },
9959 { "Headphone", 0x7 },
9960 },
9961};
9962
9963static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9964 struct snd_ctl_elem_value *ucontrol)
9965{
9966 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9967 struct alc_spec *spec = codec->spec;
9968 int ret;
9969
9970 ret = alc882_mux_enum_put(kcontrol, ucontrol);
9971 if (!ret)
9972 return 0;
9973 /* reprogram the HP pin as mic or HP according to the input source */
9974 snd_hda_codec_write_cache(codec, 0x15, 0,
9975 AC_VERB_SET_PIN_WIDGET_CONTROL,
9976 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9977 alc262_ultra_automute(codec); /* mute/unmute HP */
9978 return ret;
9979}
9980
9981static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9982 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9983 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9984 {
9985 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9986 .name = "Capture Source",
9987 .info = alc882_mux_enum_info,
9988 .get = alc882_mux_enum_get,
9989 .put = alc262_ultra_mux_enum_put,
9990 },
9991 { } /* end */
9992};
9993
df694daa 9994/* add playback controls from the parsed DAC table */
f12ab1e0
TI
9995static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9996 const struct auto_pin_cfg *cfg)
df694daa
KY
9997{
9998 hda_nid_t nid;
9999 int err;
10000
10001 spec->multiout.num_dacs = 1; /* only use one dac */
10002 spec->multiout.dac_nids = spec->private_dac_nids;
10003 spec->multiout.dac_nids[0] = 2;
10004
10005 nid = cfg->line_out_pins[0];
10006 if (nid) {
f12ab1e0
TI
10007 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10008 "Front Playback Volume",
10009 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10010 if (err < 0)
df694daa 10011 return err;
f12ab1e0
TI
10012 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10013 "Front Playback Switch",
10014 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10015 if (err < 0)
df694daa
KY
10016 return err;
10017 }
10018
82bc955f 10019 nid = cfg->speaker_pins[0];
df694daa
KY
10020 if (nid) {
10021 if (nid == 0x16) {
f12ab1e0
TI
10022 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10023 "Speaker Playback Volume",
10024 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10025 HDA_OUTPUT));
10026 if (err < 0)
df694daa 10027 return err;
f12ab1e0
TI
10028 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10029 "Speaker Playback Switch",
10030 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10031 HDA_OUTPUT));
10032 if (err < 0)
df694daa
KY
10033 return err;
10034 } else {
f12ab1e0
TI
10035 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10036 "Speaker Playback Switch",
10037 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10038 HDA_OUTPUT));
10039 if (err < 0)
df694daa
KY
10040 return err;
10041 }
10042 }
eb06ed8f 10043 nid = cfg->hp_pins[0];
df694daa
KY
10044 if (nid) {
10045 /* spec->multiout.hp_nid = 2; */
10046 if (nid == 0x16) {
f12ab1e0
TI
10047 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10048 "Headphone Playback Volume",
10049 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10050 HDA_OUTPUT));
10051 if (err < 0)
df694daa 10052 return err;
f12ab1e0
TI
10053 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10054 "Headphone Playback Switch",
10055 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10056 HDA_OUTPUT));
10057 if (err < 0)
df694daa
KY
10058 return err;
10059 } else {
f12ab1e0
TI
10060 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10061 "Headphone Playback Switch",
10062 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10063 HDA_OUTPUT));
10064 if (err < 0)
df694daa
KY
10065 return err;
10066 }
10067 }
f12ab1e0 10068 return 0;
df694daa
KY
10069}
10070
10071/* identical with ALC880 */
f12ab1e0
TI
10072#define alc262_auto_create_analog_input_ctls \
10073 alc880_auto_create_analog_input_ctls
df694daa
KY
10074
10075/*
10076 * generic initialization of ADC, input mixers and output mixers
10077 */
10078static struct hda_verb alc262_volume_init_verbs[] = {
10079 /*
10080 * Unmute ADC0-2 and set the default input to mic-in
10081 */
10082 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10083 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10084 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10085 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10086 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10087 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10088
cb53c626 10089 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 10090 * mixer widget
f12ab1e0
TI
10091 * Note: PASD motherboards uses the Line In 2 as the input for
10092 * front panel mic (mic 2)
df694daa
KY
10093 */
10094 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10095 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10096 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10097 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10098 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
10100
10101 /*
10102 * Set up output mixers (0x0c - 0x0f)
10103 */
10104 /* set vol=0 to output mixers */
10105 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10106 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10107 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 10108
df694daa
KY
10109 /* set up input amps for analog loopback */
10110 /* Amp Indices: DAC = 0, mixer = 1 */
10111 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10112 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10113 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10114 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10115 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10116 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10117
10118 /* FIXME: use matrix-type input source selection */
10119 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10120 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10121 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10122 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10123 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10124 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10125 /* Input mixer2 */
10126 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10127 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10128 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10129 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10130 /* Input mixer3 */
10131 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10132 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10133 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10134 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10135
10136 { }
10137};
10138
9c7f852e
TI
10139static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10140 /*
10141 * Unmute ADC0-2 and set the default input to mic-in
10142 */
10143 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10144 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10145 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10146 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10147 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10148 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10149
cb53c626 10150 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 10151 * mixer widget
f12ab1e0
TI
10152 * Note: PASD motherboards uses the Line In 2 as the input for
10153 * front panel mic (mic 2)
9c7f852e
TI
10154 */
10155 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10156 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10157 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10158 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10159 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10160 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10161 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10162 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 10163
9c7f852e
TI
10164 /*
10165 * Set up output mixers (0x0c - 0x0e)
10166 */
10167 /* set vol=0 to output mixers */
10168 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10169 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10170 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10171
10172 /* set up input amps for analog loopback */
10173 /* Amp Indices: DAC = 0, mixer = 1 */
10174 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10175 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10176 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10177 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10178 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10179 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10180
ce875f07 10181 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
10182 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10183 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10184
10185 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10186 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10187
10188 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10189 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10190
10191 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10192 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10193 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10194 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10195 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10196
10197 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10198 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10199 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10200 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10201 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10202 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10203
10204
10205 /* FIXME: use matrix-type input source selection */
10206 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10207 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10208 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10209 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10210 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10211 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10212 /* Input mixer2 */
10213 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10214 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10215 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10216 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10217 /* Input mixer3 */
10218 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10219 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10220 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10221 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10222
ce875f07
TI
10223 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10224
9c7f852e
TI
10225 { }
10226};
10227
cd7509a4
KY
10228static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10229 /*
10230 * Unmute ADC0-2 and set the default input to mic-in
10231 */
10232 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10233 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10234 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10235 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10236 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10237 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10238
cb53c626 10239 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
10240 * mixer widget
10241 * Note: PASD motherboards uses the Line In 2 as the input for front
10242 * panel mic (mic 2)
10243 */
10244 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
10245 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10246 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10247 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10248 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10249 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10250 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10251 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10252 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
10253 /*
10254 * Set up output mixers (0x0c - 0x0e)
10255 */
10256 /* set vol=0 to output mixers */
10257 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10258 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10259 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10260
10261 /* set up input amps for analog loopback */
10262 /* Amp Indices: DAC = 0, mixer = 1 */
10263 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10264 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10265 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10266 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10267 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10268 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10269
10270
10271 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10272 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10273 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10274 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10275 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10276 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10277 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10278
10279 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10280 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10281
10282 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10283 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10284
10285 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10286 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10287 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10288 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10289 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10290 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10291
10292 /* FIXME: use matrix-type input source selection */
10293 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10294 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10295 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10296 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10297 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10298 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10299 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10300 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10301 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10302 /* Input mixer2 */
10303 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10304 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10305 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10306 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10307 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10308 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10309 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10310 /* Input mixer3 */
10311 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10312 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10313 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10314 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10315 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10316 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10317 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10318
ce875f07
TI
10319 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10320
cd7509a4
KY
10321 { }
10322};
10323
9f99a638
HM
10324static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10325
10326 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10327 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10328 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10329
10330 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10331 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10332 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10333 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10334
10335 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10336 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10337 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10338 {}
10339};
10340
10341
cb53c626
TI
10342#ifdef CONFIG_SND_HDA_POWER_SAVE
10343#define alc262_loopbacks alc880_loopbacks
10344#endif
10345
df694daa
KY
10346/* pcm configuration: identiacal with ALC880 */
10347#define alc262_pcm_analog_playback alc880_pcm_analog_playback
10348#define alc262_pcm_analog_capture alc880_pcm_analog_capture
10349#define alc262_pcm_digital_playback alc880_pcm_digital_playback
10350#define alc262_pcm_digital_capture alc880_pcm_digital_capture
10351
10352/*
10353 * BIOS auto configuration
10354 */
10355static int alc262_parse_auto_config(struct hda_codec *codec)
10356{
10357 struct alc_spec *spec = codec->spec;
10358 int err;
10359 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10360
f12ab1e0
TI
10361 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10362 alc262_ignore);
10363 if (err < 0)
df694daa 10364 return err;
f12ab1e0 10365 if (!spec->autocfg.line_outs)
df694daa 10366 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
10367 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10368 if (err < 0)
10369 return err;
10370 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10371 if (err < 0)
df694daa
KY
10372 return err;
10373
10374 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10375
10376 if (spec->autocfg.dig_out_pin)
10377 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10378 if (spec->autocfg.dig_in_pin)
10379 spec->dig_in_nid = ALC262_DIGIN_NID;
10380
603c4019 10381 if (spec->kctls.list)
d88897ea 10382 add_mixer(spec, spec->kctls.list);
df694daa 10383
d88897ea 10384 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 10385 spec->num_mux_defs = 1;
df694daa
KY
10386 spec->input_mux = &spec->private_imux;
10387
776e184e
TI
10388 err = alc_auto_add_mic_boost(codec);
10389 if (err < 0)
10390 return err;
10391
e044c39a 10392 store_pin_configs(codec);
df694daa
KY
10393 return 1;
10394}
10395
10396#define alc262_auto_init_multi_out alc882_auto_init_multi_out
10397#define alc262_auto_init_hp_out alc882_auto_init_hp_out
10398#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 10399#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
10400
10401
10402/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 10403static void alc262_auto_init(struct hda_codec *codec)
df694daa 10404{
f6c7e546 10405 struct alc_spec *spec = codec->spec;
df694daa
KY
10406 alc262_auto_init_multi_out(codec);
10407 alc262_auto_init_hp_out(codec);
10408 alc262_auto_init_analog_input(codec);
f511b01c 10409 alc262_auto_init_input_src(codec);
f6c7e546 10410 if (spec->unsol_event)
7fb0d78f 10411 alc_inithook(codec);
df694daa
KY
10412}
10413
10414/*
10415 * configuration and preset
10416 */
f5fcc13c
TI
10417static const char *alc262_models[ALC262_MODEL_LAST] = {
10418 [ALC262_BASIC] = "basic",
10419 [ALC262_HIPPO] = "hippo",
10420 [ALC262_HIPPO_1] = "hippo_1",
10421 [ALC262_FUJITSU] = "fujitsu",
10422 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 10423 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 10424 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 10425 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 10426 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
10427 [ALC262_BENQ_T31] = "benq-t31",
10428 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 10429 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 10430 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 10431 [ALC262_ULTRA] = "ultra",
0e31daf7 10432 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 10433 [ALC262_NEC] = "nec",
f5fcc13c
TI
10434 [ALC262_AUTO] = "auto",
10435};
10436
10437static struct snd_pci_quirk alc262_cfg_tbl[] = {
10438 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 10439 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
f5fcc13c 10440 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7d87de2d 10441 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
ac3e3741
TI
10442 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
10443 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
7d87de2d 10444 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
b98f9334 10445 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
b98f9334 10446 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
b98f9334 10447 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
cd7509a4 10448 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10449 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 10450 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10451 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 10452 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10453 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 10454 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 10455 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
10456 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10457 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10458 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
10459 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10460 ALC262_HP_TC_T5735),
8c427226 10461 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 10462 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 10463 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 10464 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
272a527c 10465 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
ac3e3741 10466 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
36ca6e13 10467 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 10468 ALC262_TOSHIBA_RX1),
80ffe869 10469 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 10470 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 10471 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
f651b50b 10472 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
bb9f76cd 10473 SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
0e31daf7 10474 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
10475 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10476 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10477 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
10478 {}
10479};
10480
10481static struct alc_config_preset alc262_presets[] = {
10482 [ALC262_BASIC] = {
10483 .mixers = { alc262_base_mixer },
10484 .init_verbs = { alc262_init_verbs },
10485 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10486 .dac_nids = alc262_dac_nids,
10487 .hp_nid = 0x03,
10488 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10489 .channel_mode = alc262_modes,
a3bcba38 10490 .input_mux = &alc262_capture_source,
df694daa 10491 },
ccc656ce
KY
10492 [ALC262_HIPPO] = {
10493 .mixers = { alc262_base_mixer },
10494 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10495 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10496 .dac_nids = alc262_dac_nids,
10497 .hp_nid = 0x03,
10498 .dig_out_nid = ALC262_DIGOUT_NID,
10499 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10500 .channel_mode = alc262_modes,
10501 .input_mux = &alc262_capture_source,
10502 .unsol_event = alc262_hippo_unsol_event,
5b31954e 10503 .init_hook = alc262_hippo_automute,
ccc656ce
KY
10504 },
10505 [ALC262_HIPPO_1] = {
10506 .mixers = { alc262_hippo1_mixer },
10507 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10508 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10509 .dac_nids = alc262_dac_nids,
10510 .hp_nid = 0x02,
10511 .dig_out_nid = ALC262_DIGOUT_NID,
10512 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10513 .channel_mode = alc262_modes,
10514 .input_mux = &alc262_capture_source,
10515 .unsol_event = alc262_hippo1_unsol_event,
5b31954e 10516 .init_hook = alc262_hippo1_automute,
ccc656ce 10517 },
834be88d
TI
10518 [ALC262_FUJITSU] = {
10519 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
10520 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10521 alc262_fujitsu_unsol_verbs },
834be88d
TI
10522 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10523 .dac_nids = alc262_dac_nids,
10524 .hp_nid = 0x03,
10525 .dig_out_nid = ALC262_DIGOUT_NID,
10526 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10527 .channel_mode = alc262_modes,
10528 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 10529 .unsol_event = alc262_fujitsu_unsol_event,
ebc7a406 10530 .init_hook = alc262_fujitsu_init_hook,
834be88d 10531 },
9c7f852e
TI
10532 [ALC262_HP_BPC] = {
10533 .mixers = { alc262_HP_BPC_mixer },
10534 .init_verbs = { alc262_HP_BPC_init_verbs },
10535 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10536 .dac_nids = alc262_dac_nids,
10537 .hp_nid = 0x03,
10538 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10539 .channel_mode = alc262_modes,
10540 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
10541 .unsol_event = alc262_hp_bpc_unsol_event,
10542 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 10543 },
cd7509a4
KY
10544 [ALC262_HP_BPC_D7000_WF] = {
10545 .mixers = { alc262_HP_BPC_WildWest_mixer },
10546 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10547 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10548 .dac_nids = alc262_dac_nids,
10549 .hp_nid = 0x03,
10550 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10551 .channel_mode = alc262_modes,
accbe498 10552 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
10553 .unsol_event = alc262_hp_wildwest_unsol_event,
10554 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 10555 },
cd7509a4
KY
10556 [ALC262_HP_BPC_D7000_WL] = {
10557 .mixers = { alc262_HP_BPC_WildWest_mixer,
10558 alc262_HP_BPC_WildWest_option_mixer },
10559 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10560 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10561 .dac_nids = alc262_dac_nids,
10562 .hp_nid = 0x03,
10563 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10564 .channel_mode = alc262_modes,
accbe498 10565 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
10566 .unsol_event = alc262_hp_wildwest_unsol_event,
10567 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 10568 },
66d2a9d6
KY
10569 [ALC262_HP_TC_T5735] = {
10570 .mixers = { alc262_hp_t5735_mixer },
10571 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10572 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10573 .dac_nids = alc262_dac_nids,
10574 .hp_nid = 0x03,
10575 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10576 .channel_mode = alc262_modes,
10577 .input_mux = &alc262_capture_source,
10578 .unsol_event = alc262_hp_t5735_unsol_event,
10579 .init_hook = alc262_hp_t5735_init_hook,
8c427226
KY
10580 },
10581 [ALC262_HP_RP5700] = {
10582 .mixers = { alc262_hp_rp5700_mixer },
10583 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10584 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10585 .dac_nids = alc262_dac_nids,
10586 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10587 .channel_mode = alc262_modes,
10588 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 10589 },
304dcaac
TI
10590 [ALC262_BENQ_ED8] = {
10591 .mixers = { alc262_base_mixer },
10592 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10593 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10594 .dac_nids = alc262_dac_nids,
10595 .hp_nid = 0x03,
10596 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10597 .channel_mode = alc262_modes,
10598 .input_mux = &alc262_capture_source,
f12ab1e0 10599 },
272a527c
KY
10600 [ALC262_SONY_ASSAMD] = {
10601 .mixers = { alc262_sony_mixer },
10602 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10603 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10604 .dac_nids = alc262_dac_nids,
10605 .hp_nid = 0x02,
10606 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10607 .channel_mode = alc262_modes,
10608 .input_mux = &alc262_capture_source,
10609 .unsol_event = alc262_hippo_unsol_event,
5b31954e 10610 .init_hook = alc262_hippo_automute,
83c34218
KY
10611 },
10612 [ALC262_BENQ_T31] = {
10613 .mixers = { alc262_benq_t31_mixer },
10614 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10615 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10616 .dac_nids = alc262_dac_nids,
10617 .hp_nid = 0x03,
10618 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10619 .channel_mode = alc262_modes,
10620 .input_mux = &alc262_capture_source,
10621 .unsol_event = alc262_hippo_unsol_event,
5b31954e 10622 .init_hook = alc262_hippo_automute,
ea1fb29a 10623 },
f651b50b 10624 [ALC262_ULTRA] = {
bb9f76cd
TI
10625 .mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer },
10626 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
10627 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10628 .dac_nids = alc262_dac_nids,
f651b50b
TD
10629 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10630 .channel_mode = alc262_modes,
10631 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
10632 .adc_nids = alc262_adc_nids, /* ADC0 */
10633 .capsrc_nids = alc262_capsrc_nids,
10634 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
10635 .unsol_event = alc262_ultra_unsol_event,
10636 .init_hook = alc262_ultra_automute,
10637 },
0e31daf7
J
10638 [ALC262_LENOVO_3000] = {
10639 .mixers = { alc262_lenovo_3000_mixer },
10640 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10641 alc262_lenovo_3000_unsol_verbs },
10642 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10643 .dac_nids = alc262_dac_nids,
10644 .hp_nid = 0x03,
10645 .dig_out_nid = ALC262_DIGOUT_NID,
10646 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10647 .channel_mode = alc262_modes,
10648 .input_mux = &alc262_fujitsu_capture_source,
10649 .unsol_event = alc262_lenovo_3000_unsol_event,
10650 },
e8f9ae2a
PT
10651 [ALC262_NEC] = {
10652 .mixers = { alc262_nec_mixer },
10653 .init_verbs = { alc262_nec_verbs },
10654 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10655 .dac_nids = alc262_dac_nids,
10656 .hp_nid = 0x03,
10657 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10658 .channel_mode = alc262_modes,
10659 .input_mux = &alc262_capture_source,
10660 },
4e555fe5
KY
10661 [ALC262_TOSHIBA_S06] = {
10662 .mixers = { alc262_toshiba_s06_mixer },
10663 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10664 alc262_eapd_verbs },
10665 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10666 .capsrc_nids = alc262_dmic_capsrc_nids,
10667 .dac_nids = alc262_dac_nids,
10668 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10669 .dig_out_nid = ALC262_DIGOUT_NID,
10670 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10671 .channel_mode = alc262_modes,
10672 .input_mux = &alc262_dmic_capture_source,
10673 .unsol_event = alc262_toshiba_s06_unsol_event,
10674 .init_hook = alc262_toshiba_s06_init_hook,
10675 },
9f99a638
HM
10676 [ALC262_TOSHIBA_RX1] = {
10677 .mixers = { alc262_toshiba_rx1_mixer },
10678 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
10679 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10680 .dac_nids = alc262_dac_nids,
10681 .hp_nid = 0x03,
10682 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10683 .channel_mode = alc262_modes,
10684 .input_mux = &alc262_capture_source,
10685 .unsol_event = alc262_hippo_unsol_event,
10686 .init_hook = alc262_hippo_automute,
10687 },
df694daa
KY
10688};
10689
10690static int patch_alc262(struct hda_codec *codec)
10691{
10692 struct alc_spec *spec;
10693 int board_config;
10694 int err;
10695
dc041e0b 10696 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
10697 if (spec == NULL)
10698 return -ENOMEM;
10699
10700 codec->spec = spec;
10701#if 0
f12ab1e0
TI
10702 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
10703 * under-run
10704 */
df694daa
KY
10705 {
10706 int tmp;
10707 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10708 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
10709 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10710 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
10711 }
10712#endif
10713
2c3bf9ab
TI
10714 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10715
f5fcc13c
TI
10716 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
10717 alc262_models,
10718 alc262_cfg_tbl);
cd7509a4 10719
f5fcc13c 10720 if (board_config < 0) {
9c7f852e
TI
10721 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
10722 "trying auto-probe from BIOS...\n");
df694daa
KY
10723 board_config = ALC262_AUTO;
10724 }
10725
10726 if (board_config == ALC262_AUTO) {
10727 /* automatic parse from the BIOS config */
10728 err = alc262_parse_auto_config(codec);
10729 if (err < 0) {
10730 alc_free(codec);
10731 return err;
f12ab1e0 10732 } else if (!err) {
9c7f852e
TI
10733 printk(KERN_INFO
10734 "hda_codec: Cannot set up configuration "
10735 "from BIOS. Using base mode...\n");
df694daa
KY
10736 board_config = ALC262_BASIC;
10737 }
10738 }
10739
10740 if (board_config != ALC262_AUTO)
10741 setup_preset(spec, &alc262_presets[board_config]);
10742
10743 spec->stream_name_analog = "ALC262 Analog";
10744 spec->stream_analog_playback = &alc262_pcm_analog_playback;
10745 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 10746
df694daa
KY
10747 spec->stream_name_digital = "ALC262 Digital";
10748 spec->stream_digital_playback = &alc262_pcm_digital_playback;
10749 spec->stream_digital_capture = &alc262_pcm_digital_capture;
10750
f12ab1e0 10751 if (!spec->adc_nids && spec->input_mux) {
df694daa 10752 /* check whether NID 0x07 is valid */
4a471b7d
TI
10753 unsigned int wcap = get_wcaps(codec, 0x07);
10754
f12ab1e0
TI
10755 /* get type */
10756 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
10757 if (wcap != AC_WID_AUD_IN) {
10758 spec->adc_nids = alc262_adc_nids_alt;
10759 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
88c71a99 10760 spec->capsrc_nids = alc262_capsrc_nids_alt;
d88897ea 10761 add_mixer(spec, alc262_capture_alt_mixer);
df694daa
KY
10762 } else {
10763 spec->adc_nids = alc262_adc_nids;
10764 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
88c71a99 10765 spec->capsrc_nids = alc262_capsrc_nids;
d88897ea 10766 add_mixer(spec, alc262_capture_mixer);
df694daa
KY
10767 }
10768 }
10769
2134ea4f
TI
10770 spec->vmaster_nid = 0x0c;
10771
df694daa
KY
10772 codec->patch_ops = alc_patch_ops;
10773 if (board_config == ALC262_AUTO)
ae6b813a 10774 spec->init_hook = alc262_auto_init;
cb53c626
TI
10775#ifdef CONFIG_SND_HDA_POWER_SAVE
10776 if (!spec->loopback.amplist)
10777 spec->loopback.amplist = alc262_loopbacks;
10778#endif
ea1fb29a 10779
df694daa
KY
10780 return 0;
10781}
10782
a361d84b
KY
10783/*
10784 * ALC268 channel source setting (2 channel)
10785 */
10786#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
10787#define alc268_modes alc260_modes
ea1fb29a 10788
a361d84b
KY
10789static hda_nid_t alc268_dac_nids[2] = {
10790 /* front, hp */
10791 0x02, 0x03
10792};
10793
10794static hda_nid_t alc268_adc_nids[2] = {
10795 /* ADC0-1 */
10796 0x08, 0x07
10797};
10798
10799static hda_nid_t alc268_adc_nids_alt[1] = {
10800 /* ADC0 */
10801 0x08
10802};
10803
e1406348
TI
10804static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
10805
a361d84b
KY
10806static struct snd_kcontrol_new alc268_base_mixer[] = {
10807 /* output mixer control */
10808 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10809 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10810 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10811 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
10812 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10813 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10814 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
10815 { }
10816};
10817
aef9d318
TI
10818/* bind Beep switches of both NID 0x0f and 0x10 */
10819static struct hda_bind_ctls alc268_bind_beep_sw = {
10820 .ops = &snd_hda_bind_sw,
10821 .values = {
10822 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
10823 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
10824 0
10825 },
10826};
10827
10828static struct snd_kcontrol_new alc268_beep_mixer[] = {
10829 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
10830 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
10831 { }
10832};
10833
d1a991a6
KY
10834static struct hda_verb alc268_eapd_verbs[] = {
10835 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10836 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10837 { }
10838};
10839
d273809e
TI
10840/* Toshiba specific */
10841#define alc268_toshiba_automute alc262_hippo_automute
10842
10843static struct hda_verb alc268_toshiba_verbs[] = {
10844 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10845 { } /* end */
10846};
10847
8ef355da
KY
10848static struct hda_input_mux alc268_acer_lc_capture_source = {
10849 .num_items = 2,
10850 .items = {
10851 { "i-Mic", 0x6 },
10852 { "E-Mic", 0x0 },
10853 },
10854};
10855
d273809e 10856/* Acer specific */
889c4395 10857/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
10858static struct hda_bind_ctls alc268_acer_bind_master_vol = {
10859 .ops = &snd_hda_bind_vol,
10860 .values = {
10861 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
10862 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
10863 0
10864 },
10865};
10866
889c4395
TI
10867/* mute/unmute internal speaker according to the hp jack and mute state */
10868static void alc268_acer_automute(struct hda_codec *codec, int force)
10869{
10870 struct alc_spec *spec = codec->spec;
10871 unsigned int mute;
10872
10873 if (force || !spec->sense_updated) {
10874 unsigned int present;
10875 present = snd_hda_codec_read(codec, 0x14, 0,
10876 AC_VERB_GET_PIN_SENSE, 0);
10877 spec->jack_present = (present & 0x80000000) != 0;
10878 spec->sense_updated = 1;
10879 }
10880 if (spec->jack_present)
10881 mute = HDA_AMP_MUTE; /* mute internal speaker */
10882 else /* unmute internal speaker if necessary */
10883 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10884 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10885 HDA_AMP_MUTE, mute);
10886}
10887
10888
10889/* bind hp and internal speaker mute (with plug check) */
10890static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10891 struct snd_ctl_elem_value *ucontrol)
10892{
10893 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10894 long *valp = ucontrol->value.integer.value;
10895 int change;
10896
10897 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10898 HDA_AMP_MUTE,
10899 valp[0] ? 0 : HDA_AMP_MUTE);
10900 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10901 HDA_AMP_MUTE,
10902 valp[1] ? 0 : HDA_AMP_MUTE);
10903 if (change)
10904 alc268_acer_automute(codec, 0);
10905 return change;
10906}
d273809e 10907
8ef355da
KY
10908static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
10909 /* output mixer control */
10910 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10911 {
10912 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10913 .name = "Master Playback Switch",
10914 .info = snd_hda_mixer_amp_switch_info,
10915 .get = snd_hda_mixer_amp_switch_get,
10916 .put = alc268_acer_master_sw_put,
10917 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10918 },
10919 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
10920 { }
10921};
10922
d273809e
TI
10923static struct snd_kcontrol_new alc268_acer_mixer[] = {
10924 /* output mixer control */
10925 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10926 {
10927 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10928 .name = "Master Playback Switch",
10929 .info = snd_hda_mixer_amp_switch_info,
10930 .get = snd_hda_mixer_amp_switch_get,
10931 .put = alc268_acer_master_sw_put,
10932 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10933 },
33bf17ab
TI
10934 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10935 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10936 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
10937 { }
10938};
10939
8ef355da
KY
10940static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10941 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10942 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10943 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10944 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10945 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
10946 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
10947 { }
10948};
10949
d273809e 10950static struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
10951 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10952 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
10953 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10954 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
10955 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10956 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
10957 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10958 { }
10959};
10960
10961/* unsolicited event for HP jack sensing */
10962static void alc268_toshiba_unsol_event(struct hda_codec *codec,
10963 unsigned int res)
10964{
889c4395 10965 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
10966 return;
10967 alc268_toshiba_automute(codec);
10968}
10969
10970static void alc268_acer_unsol_event(struct hda_codec *codec,
10971 unsigned int res)
10972{
889c4395 10973 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
10974 return;
10975 alc268_acer_automute(codec, 1);
10976}
10977
889c4395
TI
10978static void alc268_acer_init_hook(struct hda_codec *codec)
10979{
10980 alc268_acer_automute(codec, 1);
10981}
10982
8ef355da
KY
10983/* toggle speaker-output according to the hp-jack state */
10984static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
10985{
10986 unsigned int present;
10987 unsigned char bits;
10988
10989 present = snd_hda_codec_read(codec, 0x15, 0,
10990 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10991 bits = present ? AMP_IN_MUTE(0) : 0;
10992 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
10993 AMP_IN_MUTE(0), bits);
10994 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
10995 AMP_IN_MUTE(0), bits);
10996}
10997
10998
10999static void alc268_acer_mic_automute(struct hda_codec *codec)
11000{
11001 unsigned int present;
11002
11003 present = snd_hda_codec_read(codec, 0x18, 0,
11004 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11005 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11006 present ? 0x0 : 0x6);
11007}
11008
11009static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11010 unsigned int res)
11011{
11012 if ((res >> 26) == ALC880_HP_EVENT)
11013 alc268_aspire_one_speaker_automute(codec);
11014 if ((res >> 26) == ALC880_MIC_EVENT)
11015 alc268_acer_mic_automute(codec);
11016}
11017
11018static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11019{
11020 alc268_aspire_one_speaker_automute(codec);
11021 alc268_acer_mic_automute(codec);
11022}
11023
3866f0b0
TI
11024static struct snd_kcontrol_new alc268_dell_mixer[] = {
11025 /* output mixer control */
11026 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11027 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11028 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11029 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11030 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11031 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11032 { }
11033};
11034
11035static struct hda_verb alc268_dell_verbs[] = {
11036 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11037 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11038 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11039 { }
11040};
11041
11042/* mute/unmute internal speaker according to the hp jack and mute state */
11043static void alc268_dell_automute(struct hda_codec *codec)
11044{
11045 unsigned int present;
11046 unsigned int mute;
11047
11048 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
11049 if (present & 0x80000000)
11050 mute = HDA_AMP_MUTE;
11051 else
11052 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
11053 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11054 HDA_AMP_MUTE, mute);
11055}
11056
11057static void alc268_dell_unsol_event(struct hda_codec *codec,
11058 unsigned int res)
11059{
11060 if ((res >> 26) != ALC880_HP_EVENT)
11061 return;
11062 alc268_dell_automute(codec);
11063}
11064
11065#define alc268_dell_init_hook alc268_dell_automute
11066
eb5a6621
HRK
11067static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11068 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11069 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11070 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11071 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11072 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11073 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11074 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11075 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11076 { }
11077};
11078
11079static struct hda_verb alc267_quanta_il1_verbs[] = {
11080 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11081 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11082 { }
11083};
11084
11085static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
11086{
11087 unsigned int present;
11088
11089 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
11090 & AC_PINSENSE_PRESENCE;
11091 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11092 present ? 0 : PIN_OUT);
11093}
11094
11095static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11096{
11097 unsigned int present;
11098
11099 present = snd_hda_codec_read(codec, 0x18, 0,
11100 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11101 snd_hda_codec_write(codec, 0x23, 0,
11102 AC_VERB_SET_CONNECT_SEL,
11103 present ? 0x00 : 0x01);
11104}
11105
11106static void alc267_quanta_il1_automute(struct hda_codec *codec)
11107{
11108 alc267_quanta_il1_hp_automute(codec);
11109 alc267_quanta_il1_mic_automute(codec);
11110}
11111
11112static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11113 unsigned int res)
11114{
11115 switch (res >> 26) {
11116 case ALC880_HP_EVENT:
11117 alc267_quanta_il1_hp_automute(codec);
11118 break;
11119 case ALC880_MIC_EVENT:
11120 alc267_quanta_il1_mic_automute(codec);
11121 break;
11122 }
11123}
11124
a361d84b
KY
11125/*
11126 * generic initialization of ADC, input mixers and output mixers
11127 */
11128static struct hda_verb alc268_base_init_verbs[] = {
11129 /* Unmute DAC0-1 and set vol = 0 */
11130 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11131 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11132 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11133 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11134 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11135 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11136
11137 /*
11138 * Set up output mixers (0x0c - 0x0e)
11139 */
11140 /* set vol=0 to output mixers */
11141 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11142 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11143 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11144 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11145
11146 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11147 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11148
11149 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11150 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11151 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11152 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11153 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11154 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11155 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11156 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11157
11158 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11159 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11160 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11161 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11162 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11163 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11164 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
11165
11166 /* set PCBEEP vol = 0, mute connections */
11167 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11168 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11169 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 11170
a9b3aa8a 11171 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 11172
a9b3aa8a
JZ
11173 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11174 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11175 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11176 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 11177
a361d84b
KY
11178 { }
11179};
11180
11181/*
11182 * generic initialization of ADC, input mixers and output mixers
11183 */
11184static struct hda_verb alc268_volume_init_verbs[] = {
11185 /* set output DAC */
11186 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11187 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11188 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11189 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11190
11191 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11192 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11193 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11194 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11195 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11196
11197 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11198 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11199 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11200 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11201 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11202
11203 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11204 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11205 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11206 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11207
aef9d318
TI
11208 /* set PCBEEP vol = 0, mute connections */
11209 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11210 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11211 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
11212
11213 { }
11214};
11215
11216#define alc268_mux_enum_info alc_mux_enum_info
11217#define alc268_mux_enum_get alc_mux_enum_get
e1406348 11218#define alc268_mux_enum_put alc_mux_enum_put
a361d84b
KY
11219
11220static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11221 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11222 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11223 {
11224 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11225 /* The multiple "Capture Source" controls confuse alsamixer
11226 * So call somewhat different..
a361d84b
KY
11227 */
11228 /* .name = "Capture Source", */
11229 .name = "Input Source",
11230 .count = 1,
11231 .info = alc268_mux_enum_info,
11232 .get = alc268_mux_enum_get,
11233 .put = alc268_mux_enum_put,
11234 },
11235 { } /* end */
11236};
11237
11238static struct snd_kcontrol_new alc268_capture_mixer[] = {
11239 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11240 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11241 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11242 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11243 {
11244 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11245 /* The multiple "Capture Source" controls confuse alsamixer
11246 * So call somewhat different..
a361d84b
KY
11247 */
11248 /* .name = "Capture Source", */
11249 .name = "Input Source",
11250 .count = 2,
11251 .info = alc268_mux_enum_info,
11252 .get = alc268_mux_enum_get,
11253 .put = alc268_mux_enum_put,
11254 },
11255 { } /* end */
11256};
11257
11258static struct hda_input_mux alc268_capture_source = {
11259 .num_items = 4,
11260 .items = {
11261 { "Mic", 0x0 },
11262 { "Front Mic", 0x1 },
11263 { "Line", 0x2 },
11264 { "CD", 0x3 },
11265 },
11266};
11267
0ccb541c
TI
11268static struct hda_input_mux alc268_acer_capture_source = {
11269 .num_items = 3,
11270 .items = {
11271 { "Mic", 0x0 },
11272 { "Internal Mic", 0x6 },
11273 { "Line", 0x2 },
11274 },
11275};
11276
86c53bd2
JW
11277#ifdef CONFIG_SND_DEBUG
11278static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
11279 /* Volume widgets */
11280 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11281 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11282 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11283 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11284 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11285 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11286 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11287 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11288 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11289 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11290 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11291 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11292 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
11293 /* The below appears problematic on some hardwares */
11294 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
11295 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11296 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11297 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11298 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11299
11300 /* Modes for retasking pin widgets */
11301 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11302 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11303 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11304 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11305
11306 /* Controls for GPIO pins, assuming they are configured as outputs */
11307 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11308 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11309 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11310 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11311
11312 /* Switches to allow the digital SPDIF output pin to be enabled.
11313 * The ALC268 does not have an SPDIF input.
11314 */
11315 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11316
11317 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11318 * this output to turn on an external amplifier.
11319 */
11320 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11321 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11322
11323 { } /* end */
11324};
11325#endif
11326
a361d84b
KY
11327/* create input playback/capture controls for the given pin */
11328static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11329 const char *ctlname, int idx)
11330{
11331 char name[32];
11332 int err;
11333
11334 sprintf(name, "%s Playback Volume", ctlname);
11335 if (nid == 0x14) {
11336 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11337 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11338 HDA_OUTPUT));
11339 if (err < 0)
11340 return err;
11341 } else if (nid == 0x15) {
11342 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11343 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11344 HDA_OUTPUT));
11345 if (err < 0)
11346 return err;
11347 } else
11348 return -1;
11349 sprintf(name, "%s Playback Switch", ctlname);
11350 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11351 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11352 if (err < 0)
11353 return err;
11354 return 0;
11355}
11356
11357/* add playback controls from the parsed DAC table */
11358static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11359 const struct auto_pin_cfg *cfg)
11360{
11361 hda_nid_t nid;
11362 int err;
11363
11364 spec->multiout.num_dacs = 2; /* only use one dac */
11365 spec->multiout.dac_nids = spec->private_dac_nids;
11366 spec->multiout.dac_nids[0] = 2;
11367 spec->multiout.dac_nids[1] = 3;
11368
11369 nid = cfg->line_out_pins[0];
11370 if (nid)
ea1fb29a 11371 alc268_new_analog_output(spec, nid, "Front", 0);
a361d84b
KY
11372
11373 nid = cfg->speaker_pins[0];
11374 if (nid == 0x1d) {
11375 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11376 "Speaker Playback Volume",
11377 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11378 if (err < 0)
11379 return err;
11380 }
11381 nid = cfg->hp_pins[0];
11382 if (nid)
11383 alc268_new_analog_output(spec, nid, "Headphone", 0);
11384
11385 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11386 if (nid == 0x16) {
11387 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11388 "Mono Playback Switch",
11389 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11390 if (err < 0)
11391 return err;
11392 }
ea1fb29a 11393 return 0;
a361d84b
KY
11394}
11395
11396/* create playback/capture controls for input pins */
11397static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11398 const struct auto_pin_cfg *cfg)
11399{
11400 struct hda_input_mux *imux = &spec->private_imux;
11401 int i, idx1;
11402
11403 for (i = 0; i < AUTO_PIN_LAST; i++) {
11404 switch(cfg->input_pins[i]) {
11405 case 0x18:
11406 idx1 = 0; /* Mic 1 */
11407 break;
11408 case 0x19:
11409 idx1 = 1; /* Mic 2 */
11410 break;
11411 case 0x1a:
11412 idx1 = 2; /* Line In */
11413 break;
ea1fb29a 11414 case 0x1c:
a361d84b
KY
11415 idx1 = 3; /* CD */
11416 break;
7194cae6
TI
11417 case 0x12:
11418 case 0x13:
11419 idx1 = 6; /* digital mics */
11420 break;
a361d84b
KY
11421 default:
11422 continue;
11423 }
11424 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11425 imux->items[imux->num_items].index = idx1;
ea1fb29a 11426 imux->num_items++;
a361d84b
KY
11427 }
11428 return 0;
11429}
11430
11431static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11432{
11433 struct alc_spec *spec = codec->spec;
11434 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11435 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11436 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11437 unsigned int dac_vol1, dac_vol2;
11438
11439 if (speaker_nid) {
11440 snd_hda_codec_write(codec, speaker_nid, 0,
11441 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11442 snd_hda_codec_write(codec, 0x0f, 0,
11443 AC_VERB_SET_AMP_GAIN_MUTE,
11444 AMP_IN_UNMUTE(1));
11445 snd_hda_codec_write(codec, 0x10, 0,
11446 AC_VERB_SET_AMP_GAIN_MUTE,
11447 AMP_IN_UNMUTE(1));
11448 } else {
11449 snd_hda_codec_write(codec, 0x0f, 0,
11450 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11451 snd_hda_codec_write(codec, 0x10, 0,
11452 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11453 }
11454
11455 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 11456 if (line_nid == 0x14)
a361d84b
KY
11457 dac_vol2 = AMP_OUT_ZERO;
11458 else if (line_nid == 0x15)
11459 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 11460 if (hp_nid == 0x14)
a361d84b
KY
11461 dac_vol2 = AMP_OUT_ZERO;
11462 else if (hp_nid == 0x15)
11463 dac_vol1 = AMP_OUT_ZERO;
11464 if (line_nid != 0x16 || hp_nid != 0x16 ||
11465 spec->autocfg.line_out_pins[1] != 0x16 ||
11466 spec->autocfg.line_out_pins[2] != 0x16)
11467 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11468
11469 snd_hda_codec_write(codec, 0x02, 0,
11470 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11471 snd_hda_codec_write(codec, 0x03, 0,
11472 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11473}
11474
11475/* pcm configuration: identiacal with ALC880 */
11476#define alc268_pcm_analog_playback alc880_pcm_analog_playback
11477#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 11478#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
11479#define alc268_pcm_digital_playback alc880_pcm_digital_playback
11480
11481/*
11482 * BIOS auto configuration
11483 */
11484static int alc268_parse_auto_config(struct hda_codec *codec)
11485{
11486 struct alc_spec *spec = codec->spec;
11487 int err;
11488 static hda_nid_t alc268_ignore[] = { 0 };
11489
11490 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11491 alc268_ignore);
11492 if (err < 0)
11493 return err;
11494 if (!spec->autocfg.line_outs)
11495 return 0; /* can't find valid BIOS pin config */
11496
11497 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11498 if (err < 0)
11499 return err;
11500 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11501 if (err < 0)
11502 return err;
11503
11504 spec->multiout.max_channels = 2;
11505
11506 /* digital only support output */
11507 if (spec->autocfg.dig_out_pin)
11508 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11509
603c4019 11510 if (spec->kctls.list)
d88897ea 11511 add_mixer(spec, spec->kctls.list);
a361d84b 11512
aef9d318 11513 if (spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 11514 add_mixer(spec, alc268_beep_mixer);
aef9d318 11515
d88897ea 11516 add_verb(spec, alc268_volume_init_verbs);
a361d84b
KY
11517 spec->num_mux_defs = 1;
11518 spec->input_mux = &spec->private_imux;
11519
776e184e
TI
11520 err = alc_auto_add_mic_boost(codec);
11521 if (err < 0)
11522 return err;
11523
e044c39a 11524 store_pin_configs(codec);
a361d84b
KY
11525 return 1;
11526}
11527
11528#define alc268_auto_init_multi_out alc882_auto_init_multi_out
11529#define alc268_auto_init_hp_out alc882_auto_init_hp_out
11530#define alc268_auto_init_analog_input alc882_auto_init_analog_input
11531
11532/* init callback for auto-configuration model -- overriding the default init */
11533static void alc268_auto_init(struct hda_codec *codec)
11534{
f6c7e546 11535 struct alc_spec *spec = codec->spec;
a361d84b
KY
11536 alc268_auto_init_multi_out(codec);
11537 alc268_auto_init_hp_out(codec);
11538 alc268_auto_init_mono_speaker_out(codec);
11539 alc268_auto_init_analog_input(codec);
f6c7e546 11540 if (spec->unsol_event)
7fb0d78f 11541 alc_inithook(codec);
a361d84b
KY
11542}
11543
11544/*
11545 * configuration and preset
11546 */
11547static const char *alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 11548 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 11549 [ALC268_3ST] = "3stack",
983f8ae4 11550 [ALC268_TOSHIBA] = "toshiba",
d273809e 11551 [ALC268_ACER] = "acer",
8ef355da 11552 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 11553 [ALC268_DELL] = "dell",
f12462c5 11554 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
11555#ifdef CONFIG_SND_DEBUG
11556 [ALC268_TEST] = "test",
11557#endif
a361d84b
KY
11558 [ALC268_AUTO] = "auto",
11559};
11560
11561static struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 11562 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 11563 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 11564 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 11565 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 11566 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
11567 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11568 ALC268_ACER_ASPIRE_ONE),
3866f0b0 11569 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
ac3e3741 11570 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
a361d84b 11571 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
d1a991a6 11572 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
8e7f00f9 11573 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
2346d0cd 11574 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
378bd6a5 11575 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 11576 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 11577 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
f12462c5 11578 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
a361d84b
KY
11579 {}
11580};
11581
11582static struct alc_config_preset alc268_presets[] = {
eb5a6621
HRK
11583 [ALC267_QUANTA_IL1] = {
11584 .mixers = { alc267_quanta_il1_mixer },
11585 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11586 alc267_quanta_il1_verbs },
11587 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11588 .dac_nids = alc268_dac_nids,
11589 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11590 .adc_nids = alc268_adc_nids_alt,
11591 .hp_nid = 0x03,
11592 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11593 .channel_mode = alc268_modes,
11594 .input_mux = &alc268_capture_source,
11595 .unsol_event = alc267_quanta_il1_unsol_event,
11596 .init_hook = alc267_quanta_il1_automute,
11597 },
a361d84b 11598 [ALC268_3ST] = {
aef9d318
TI
11599 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11600 alc268_beep_mixer },
a361d84b
KY
11601 .init_verbs = { alc268_base_init_verbs },
11602 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11603 .dac_nids = alc268_dac_nids,
11604 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11605 .adc_nids = alc268_adc_nids_alt,
e1406348 11606 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
11607 .hp_nid = 0x03,
11608 .dig_out_nid = ALC268_DIGOUT_NID,
11609 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11610 .channel_mode = alc268_modes,
11611 .input_mux = &alc268_capture_source,
11612 },
d1a991a6 11613 [ALC268_TOSHIBA] = {
aef9d318
TI
11614 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11615 alc268_beep_mixer },
d273809e
TI
11616 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11617 alc268_toshiba_verbs },
d1a991a6
KY
11618 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11619 .dac_nids = alc268_dac_nids,
11620 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11621 .adc_nids = alc268_adc_nids_alt,
e1406348 11622 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
11623 .hp_nid = 0x03,
11624 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11625 .channel_mode = alc268_modes,
11626 .input_mux = &alc268_capture_source,
d273809e
TI
11627 .unsol_event = alc268_toshiba_unsol_event,
11628 .init_hook = alc268_toshiba_automute,
11629 },
11630 [ALC268_ACER] = {
aef9d318
TI
11631 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11632 alc268_beep_mixer },
d273809e
TI
11633 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11634 alc268_acer_verbs },
11635 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11636 .dac_nids = alc268_dac_nids,
11637 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11638 .adc_nids = alc268_adc_nids_alt,
e1406348 11639 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
11640 .hp_nid = 0x02,
11641 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11642 .channel_mode = alc268_modes,
0ccb541c 11643 .input_mux = &alc268_acer_capture_source,
d273809e 11644 .unsol_event = alc268_acer_unsol_event,
889c4395 11645 .init_hook = alc268_acer_init_hook,
d1a991a6 11646 },
8ef355da
KY
11647 [ALC268_ACER_ASPIRE_ONE] = {
11648 .mixers = { alc268_acer_aspire_one_mixer,
11649 alc268_capture_alt_mixer },
11650 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11651 alc268_acer_aspire_one_verbs },
11652 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11653 .dac_nids = alc268_dac_nids,
11654 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11655 .adc_nids = alc268_adc_nids_alt,
11656 .capsrc_nids = alc268_capsrc_nids,
11657 .hp_nid = 0x03,
11658 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11659 .channel_mode = alc268_modes,
11660 .input_mux = &alc268_acer_lc_capture_source,
11661 .unsol_event = alc268_acer_lc_unsol_event,
11662 .init_hook = alc268_acer_lc_init_hook,
11663 },
3866f0b0 11664 [ALC268_DELL] = {
aef9d318 11665 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
3866f0b0
TI
11666 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11667 alc268_dell_verbs },
11668 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11669 .dac_nids = alc268_dac_nids,
11670 .hp_nid = 0x02,
11671 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11672 .channel_mode = alc268_modes,
11673 .unsol_event = alc268_dell_unsol_event,
11674 .init_hook = alc268_dell_init_hook,
11675 .input_mux = &alc268_capture_source,
11676 },
f12462c5 11677 [ALC268_ZEPTO] = {
aef9d318
TI
11678 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11679 alc268_beep_mixer },
f12462c5
MT
11680 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11681 alc268_toshiba_verbs },
11682 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11683 .dac_nids = alc268_dac_nids,
11684 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11685 .adc_nids = alc268_adc_nids_alt,
e1406348 11686 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
11687 .hp_nid = 0x03,
11688 .dig_out_nid = ALC268_DIGOUT_NID,
11689 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11690 .channel_mode = alc268_modes,
11691 .input_mux = &alc268_capture_source,
11692 .unsol_event = alc268_toshiba_unsol_event,
11693 .init_hook = alc268_toshiba_automute
11694 },
86c53bd2
JW
11695#ifdef CONFIG_SND_DEBUG
11696 [ALC268_TEST] = {
11697 .mixers = { alc268_test_mixer, alc268_capture_mixer },
11698 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11699 alc268_volume_init_verbs },
11700 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11701 .dac_nids = alc268_dac_nids,
11702 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11703 .adc_nids = alc268_adc_nids_alt,
e1406348 11704 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
11705 .hp_nid = 0x03,
11706 .dig_out_nid = ALC268_DIGOUT_NID,
11707 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11708 .channel_mode = alc268_modes,
11709 .input_mux = &alc268_capture_source,
11710 },
11711#endif
a361d84b
KY
11712};
11713
11714static int patch_alc268(struct hda_codec *codec)
11715{
11716 struct alc_spec *spec;
11717 int board_config;
11718 int err;
11719
11720 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
11721 if (spec == NULL)
11722 return -ENOMEM;
11723
11724 codec->spec = spec;
11725
11726 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
11727 alc268_models,
11728 alc268_cfg_tbl);
11729
11730 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
11731 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
11732 "trying auto-probe from BIOS...\n");
11733 board_config = ALC268_AUTO;
11734 }
11735
11736 if (board_config == ALC268_AUTO) {
11737 /* automatic parse from the BIOS config */
11738 err = alc268_parse_auto_config(codec);
11739 if (err < 0) {
11740 alc_free(codec);
11741 return err;
11742 } else if (!err) {
11743 printk(KERN_INFO
11744 "hda_codec: Cannot set up configuration "
11745 "from BIOS. Using base mode...\n");
11746 board_config = ALC268_3ST;
11747 }
11748 }
11749
11750 if (board_config != ALC268_AUTO)
11751 setup_preset(spec, &alc268_presets[board_config]);
11752
2f893286
KY
11753 if (codec->vendor_id == 0x10ec0267) {
11754 spec->stream_name_analog = "ALC267 Analog";
11755 spec->stream_name_digital = "ALC267 Digital";
11756 } else {
11757 spec->stream_name_analog = "ALC268 Analog";
11758 spec->stream_name_digital = "ALC268 Digital";
11759 }
11760
a361d84b
KY
11761 spec->stream_analog_playback = &alc268_pcm_analog_playback;
11762 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 11763 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 11764
a361d84b
KY
11765 spec->stream_digital_playback = &alc268_pcm_digital_playback;
11766
aef9d318
TI
11767 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
11768 /* override the amp caps for beep generator */
11769 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
11770 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
11771 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
11772 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
11773 (0 << AC_AMPCAP_MUTE_SHIFT));
11774
3866f0b0
TI
11775 if (!spec->adc_nids && spec->input_mux) {
11776 /* check whether NID 0x07 is valid */
11777 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 11778 int i;
3866f0b0
TI
11779
11780 /* get type */
11781 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
67ebcb03 11782 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
11783 spec->adc_nids = alc268_adc_nids_alt;
11784 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
d88897ea 11785 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
11786 } else {
11787 spec->adc_nids = alc268_adc_nids;
11788 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 11789 add_mixer(spec, alc268_capture_mixer);
a361d84b 11790 }
e1406348 11791 spec->capsrc_nids = alc268_capsrc_nids;
85860c06
TI
11792 /* set default input source */
11793 for (i = 0; i < spec->num_adc_nids; i++)
11794 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
11795 0, AC_VERB_SET_CONNECT_SEL,
11796 spec->input_mux->items[0].index);
a361d84b 11797 }
2134ea4f
TI
11798
11799 spec->vmaster_nid = 0x02;
11800
a361d84b
KY
11801 codec->patch_ops = alc_patch_ops;
11802 if (board_config == ALC268_AUTO)
11803 spec->init_hook = alc268_auto_init;
ea1fb29a 11804
a361d84b
KY
11805 return 0;
11806}
11807
f6a92248
KY
11808/*
11809 * ALC269 channel source setting (2 channel)
11810 */
11811#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
11812
11813#define alc269_dac_nids alc260_dac_nids
11814
11815static hda_nid_t alc269_adc_nids[1] = {
11816 /* ADC1 */
f53281e6
KY
11817 0x08,
11818};
11819
e01bf509
TI
11820static hda_nid_t alc269_capsrc_nids[1] = {
11821 0x23,
11822};
11823
11824/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
11825 * not a mux!
11826 */
11827
f53281e6
KY
11828static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
11829 .num_items = 2,
11830 .items = {
11831 { "i-Mic", 0x5 },
11832 { "e-Mic", 0x0 },
11833 },
11834};
11835
11836static struct hda_input_mux alc269_eeepc_amic_capture_source = {
11837 .num_items = 2,
11838 .items = {
11839 { "i-Mic", 0x1 },
11840 { "e-Mic", 0x0 },
11841 },
f6a92248
KY
11842};
11843
11844#define alc269_modes alc260_modes
11845#define alc269_capture_source alc880_lg_lw_capture_source
11846
11847static struct snd_kcontrol_new alc269_base_mixer[] = {
11848 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11849 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11850 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11851 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11852 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11853 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2005af24
TI
11854 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11855 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
f6a92248
KY
11856 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11857 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11858 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11859 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11860 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11861 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11862 { } /* end */
11863};
11864
60db6b53
KY
11865static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
11866 /* output mixer control */
11867 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11868 {
11869 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11870 .name = "Master Playback Switch",
11871 .info = snd_hda_mixer_amp_switch_info,
11872 .get = snd_hda_mixer_amp_switch_get,
11873 .put = alc268_acer_master_sw_put,
11874 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11875 },
11876 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11877 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11878 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11879 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11880 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11881 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11882 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
11883 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
11884 { }
11885};
11886
f53281e6
KY
11887/* bind volumes of both NID 0x0c and 0x0d */
11888static struct hda_bind_ctls alc269_epc_bind_vol = {
11889 .ops = &snd_hda_bind_vol,
11890 .values = {
11891 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11892 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11893 0
11894 },
11895};
11896
11897static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11898 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11899 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
11900 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11901 { } /* end */
11902};
11903
f6a92248
KY
11904/* capture mixer elements */
11905static struct snd_kcontrol_new alc269_capture_mixer[] = {
f53281e6
KY
11906 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11907 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
f6a92248
KY
11908 {
11909 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11910 /* The multiple "Capture Source" controls confuse alsamixer
11911 * So call somewhat different..
f6a92248
KY
11912 */
11913 /* .name = "Capture Source", */
11914 .name = "Input Source",
11915 .count = 1,
11916 .info = alc_mux_enum_info,
11917 .get = alc_mux_enum_get,
11918 .put = alc_mux_enum_put,
11919 },
11920 { } /* end */
11921};
11922
f53281e6
KY
11923/* capture mixer elements */
11924static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11925 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11926 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11927 { } /* end */
11928};
11929
2005af24
TI
11930/* beep control */
11931static struct snd_kcontrol_new alc269_beep_mixer[] = {
11932 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11933 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11934 { } /* end */
11935};
11936
60db6b53
KY
11937static struct hda_verb alc269_quanta_fl1_verbs[] = {
11938 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11939 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11940 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11941 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11942 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11943 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11944 { }
11945};
f6a92248 11946
60db6b53
KY
11947/* toggle speaker-output according to the hp-jack state */
11948static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11949{
11950 unsigned int present;
11951 unsigned char bits;
f6a92248 11952
60db6b53
KY
11953 present = snd_hda_codec_read(codec, 0x15, 0,
11954 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11955 bits = present ? AMP_IN_MUTE(0) : 0;
11956 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11957 AMP_IN_MUTE(0), bits);
11958 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11959 AMP_IN_MUTE(0), bits);
f6a92248 11960
60db6b53
KY
11961 snd_hda_codec_write(codec, 0x20, 0,
11962 AC_VERB_SET_COEF_INDEX, 0x0c);
11963 snd_hda_codec_write(codec, 0x20, 0,
11964 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 11965
60db6b53
KY
11966 snd_hda_codec_write(codec, 0x20, 0,
11967 AC_VERB_SET_COEF_INDEX, 0x0c);
11968 snd_hda_codec_write(codec, 0x20, 0,
11969 AC_VERB_SET_PROC_COEF, 0x480);
11970}
f6a92248 11971
60db6b53
KY
11972static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11973{
11974 unsigned int present;
f6a92248 11975
60db6b53
KY
11976 present = snd_hda_codec_read(codec, 0x18, 0,
11977 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11978 snd_hda_codec_write(codec, 0x23, 0,
11979 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
11980}
f6a92248 11981
60db6b53
KY
11982static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11983 unsigned int res)
11984{
11985 if ((res >> 26) == ALC880_HP_EVENT)
11986 alc269_quanta_fl1_speaker_automute(codec);
11987 if ((res >> 26) == ALC880_MIC_EVENT)
11988 alc269_quanta_fl1_mic_automute(codec);
11989}
f6a92248 11990
60db6b53
KY
11991static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
11992{
11993 alc269_quanta_fl1_speaker_automute(codec);
11994 alc269_quanta_fl1_mic_automute(codec);
11995}
f6a92248 11996
f53281e6
KY
11997static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
11998 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11999 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12000 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12001 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12002 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12003 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12004 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12005 {}
12006};
12007
12008static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12009 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12010 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12011 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12012 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12013 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12014 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12015 {}
12016};
12017
12018/* toggle speaker-output according to the hp-jack state */
12019static void alc269_speaker_automute(struct hda_codec *codec)
12020{
12021 unsigned int present;
60db6b53 12022 unsigned char bits;
f53281e6
KY
12023
12024 present = snd_hda_codec_read(codec, 0x15, 0,
60db6b53 12025 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
f53281e6
KY
12026 bits = present ? AMP_IN_MUTE(0) : 0;
12027 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
60db6b53 12028 AMP_IN_MUTE(0), bits);
f53281e6 12029 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
60db6b53 12030 AMP_IN_MUTE(0), bits);
f53281e6
KY
12031}
12032
12033static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12034{
12035 unsigned int present;
12036
60db6b53
KY
12037 present = snd_hda_codec_read(codec, 0x18, 0,
12038 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12039 snd_hda_codec_write(codec, 0x23, 0,
12040 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
f53281e6
KY
12041}
12042
12043static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12044{
12045 unsigned int present;
12046
60db6b53
KY
12047 present = snd_hda_codec_read(codec, 0x18, 0,
12048 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
f53281e6 12049 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
60db6b53 12050 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
f53281e6 12051 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
60db6b53 12052 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
f53281e6
KY
12053}
12054
12055/* unsolicited event for HP jack sensing */
12056static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
60db6b53 12057 unsigned int res)
f53281e6
KY
12058{
12059 if ((res >> 26) == ALC880_HP_EVENT)
12060 alc269_speaker_automute(codec);
12061
12062 if ((res >> 26) == ALC880_MIC_EVENT)
12063 alc269_eeepc_dmic_automute(codec);
12064}
12065
12066static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12067{
12068 alc269_speaker_automute(codec);
12069 alc269_eeepc_dmic_automute(codec);
12070}
12071
12072/* unsolicited event for HP jack sensing */
12073static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
ea1fb29a 12074 unsigned int res)
f53281e6
KY
12075{
12076 if ((res >> 26) == ALC880_HP_EVENT)
12077 alc269_speaker_automute(codec);
12078
12079 if ((res >> 26) == ALC880_MIC_EVENT)
12080 alc269_eeepc_amic_automute(codec);
12081}
12082
12083static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12084{
12085 alc269_speaker_automute(codec);
12086 alc269_eeepc_amic_automute(codec);
12087}
12088
60db6b53
KY
12089/*
12090 * generic initialization of ADC, input mixers and output mixers
12091 */
12092static struct hda_verb alc269_init_verbs[] = {
12093 /*
12094 * Unmute ADC0 and set the default input to mic-in
12095 */
12096 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12097
12098 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12099 * analog-loopback mixer widget
12100 * Note: PASD motherboards uses the Line In 2 as the input for
12101 * front panel mic (mic 2)
12102 */
12103 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12104 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12105 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12106 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12107 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12108 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12109
12110 /*
12111 * Set up output mixers (0x0c - 0x0e)
12112 */
12113 /* set vol=0 to output mixers */
12114 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12115 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12116
12117 /* set up input amps for analog loopback */
12118 /* Amp Indices: DAC = 0, mixer = 1 */
12119 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12120 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12121 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12122 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12123 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12124 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12125
12126 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12127 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12128 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12129 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12130 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12131 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12132 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12133
12134 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12135 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12136 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12137 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12138 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12139 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12140 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12141
12142 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12143 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12144
12145 /* FIXME: use matrix-type input source selection */
12146 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12147 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12148 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12149 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12150 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12151 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12152
12153 /* set EAPD */
12154 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12155 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12156 { }
12157};
12158
f6a92248
KY
12159/* add playback controls from the parsed DAC table */
12160static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12161 const struct auto_pin_cfg *cfg)
12162{
12163 hda_nid_t nid;
12164 int err;
12165
12166 spec->multiout.num_dacs = 1; /* only use one dac */
12167 spec->multiout.dac_nids = spec->private_dac_nids;
12168 spec->multiout.dac_nids[0] = 2;
12169
12170 nid = cfg->line_out_pins[0];
12171 if (nid) {
12172 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12173 "Front Playback Volume",
12174 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12175 if (err < 0)
12176 return err;
12177 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12178 "Front Playback Switch",
12179 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12180 if (err < 0)
12181 return err;
12182 }
12183
12184 nid = cfg->speaker_pins[0];
12185 if (nid) {
12186 if (!cfg->line_out_pins[0]) {
12187 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12188 "Speaker Playback Volume",
12189 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12190 HDA_OUTPUT));
12191 if (err < 0)
12192 return err;
12193 }
12194 if (nid == 0x16) {
12195 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12196 "Speaker Playback Switch",
12197 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12198 HDA_OUTPUT));
12199 if (err < 0)
12200 return err;
12201 } else {
12202 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12203 "Speaker Playback Switch",
12204 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12205 HDA_OUTPUT));
12206 if (err < 0)
12207 return err;
12208 }
12209 }
12210 nid = cfg->hp_pins[0];
12211 if (nid) {
12212 /* spec->multiout.hp_nid = 2; */
12213 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12214 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12215 "Headphone Playback Volume",
12216 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12217 HDA_OUTPUT));
12218 if (err < 0)
12219 return err;
12220 }
12221 if (nid == 0x16) {
12222 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12223 "Headphone Playback Switch",
12224 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12225 HDA_OUTPUT));
12226 if (err < 0)
12227 return err;
12228 } else {
12229 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12230 "Headphone Playback Switch",
12231 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12232 HDA_OUTPUT));
12233 if (err < 0)
12234 return err;
12235 }
12236 }
12237 return 0;
12238}
12239
ee956e09
TI
12240static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12241 const struct auto_pin_cfg *cfg)
12242{
12243 int err;
12244
12245 err = alc880_auto_create_analog_input_ctls(spec, cfg);
12246 if (err < 0)
12247 return err;
12248 /* digital-mic input pin is excluded in alc880_auto_create..()
12249 * because it's under 0x18
12250 */
12251 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12252 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12253 struct hda_input_mux *imux = &spec->private_imux;
12254 imux->items[imux->num_items].label = "Int Mic";
12255 imux->items[imux->num_items].index = 0x05;
12256 imux->num_items++;
12257 }
12258 return 0;
12259}
f6a92248
KY
12260
12261#ifdef CONFIG_SND_HDA_POWER_SAVE
12262#define alc269_loopbacks alc880_loopbacks
12263#endif
12264
12265/* pcm configuration: identiacal with ALC880 */
12266#define alc269_pcm_analog_playback alc880_pcm_analog_playback
12267#define alc269_pcm_analog_capture alc880_pcm_analog_capture
12268#define alc269_pcm_digital_playback alc880_pcm_digital_playback
12269#define alc269_pcm_digital_capture alc880_pcm_digital_capture
12270
12271/*
12272 * BIOS auto configuration
12273 */
12274static int alc269_parse_auto_config(struct hda_codec *codec)
12275{
12276 struct alc_spec *spec = codec->spec;
2005af24 12277 int i, err;
f6a92248
KY
12278 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12279
12280 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12281 alc269_ignore);
12282 if (err < 0)
12283 return err;
12284
12285 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12286 if (err < 0)
12287 return err;
12288 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12289 if (err < 0)
12290 return err;
12291
12292 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12293
12294 if (spec->autocfg.dig_out_pin)
12295 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12296
603c4019 12297 if (spec->kctls.list)
d88897ea 12298 add_mixer(spec, spec->kctls.list);
f6a92248 12299
2005af24
TI
12300 /* create a beep mixer control if the pin 0x1d isn't assigned */
12301 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12302 if (spec->autocfg.input_pins[i] == 0x1d)
12303 break;
12304 if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
d88897ea 12305 add_mixer(spec, alc269_beep_mixer);
2005af24 12306
d88897ea 12307 add_verb(spec, alc269_init_verbs);
f6a92248
KY
12308 spec->num_mux_defs = 1;
12309 spec->input_mux = &spec->private_imux;
e01bf509
TI
12310 /* set default input source */
12311 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12312 0, AC_VERB_SET_CONNECT_SEL,
12313 spec->input_mux->items[0].index);
f6a92248
KY
12314
12315 err = alc_auto_add_mic_boost(codec);
12316 if (err < 0)
12317 return err;
12318
d88897ea 12319 add_mixer(spec, alc269_capture_mixer);
f53281e6 12320
e044c39a 12321 store_pin_configs(codec);
f6a92248
KY
12322 return 1;
12323}
12324
12325#define alc269_auto_init_multi_out alc882_auto_init_multi_out
12326#define alc269_auto_init_hp_out alc882_auto_init_hp_out
12327#define alc269_auto_init_analog_input alc882_auto_init_analog_input
12328
12329
12330/* init callback for auto-configuration model -- overriding the default init */
12331static void alc269_auto_init(struct hda_codec *codec)
12332{
f6c7e546 12333 struct alc_spec *spec = codec->spec;
f6a92248
KY
12334 alc269_auto_init_multi_out(codec);
12335 alc269_auto_init_hp_out(codec);
12336 alc269_auto_init_analog_input(codec);
f6c7e546 12337 if (spec->unsol_event)
7fb0d78f 12338 alc_inithook(codec);
f6a92248
KY
12339}
12340
12341/*
12342 * configuration and preset
12343 */
12344static const char *alc269_models[ALC269_MODEL_LAST] = {
60db6b53 12345 [ALC269_BASIC] = "basic",
2922c9af
TI
12346 [ALC269_QUANTA_FL1] = "quanta",
12347 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12348 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901"
f6a92248
KY
12349};
12350
12351static struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 12352 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
f53281e6
KY
12353 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12354 ALC269_ASUS_EEEPC_P703),
12355 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12356 ALC269_ASUS_EEEPC_P901),
60db6b53
KY
12357 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12358 ALC269_ASUS_EEEPC_P901),
f6a92248
KY
12359 {}
12360};
12361
12362static struct alc_config_preset alc269_presets[] = {
12363 [ALC269_BASIC] = {
f53281e6 12364 .mixers = { alc269_base_mixer, alc269_capture_mixer },
f6a92248
KY
12365 .init_verbs = { alc269_init_verbs },
12366 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12367 .dac_nids = alc269_dac_nids,
12368 .hp_nid = 0x03,
12369 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12370 .channel_mode = alc269_modes,
12371 .input_mux = &alc269_capture_source,
12372 },
60db6b53
KY
12373 [ALC269_QUANTA_FL1] = {
12374 .mixers = { alc269_quanta_fl1_mixer },
12375 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12376 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12377 .dac_nids = alc269_dac_nids,
12378 .hp_nid = 0x03,
12379 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12380 .channel_mode = alc269_modes,
12381 .input_mux = &alc269_capture_source,
12382 .unsol_event = alc269_quanta_fl1_unsol_event,
12383 .init_hook = alc269_quanta_fl1_init_hook,
12384 },
f53281e6
KY
12385 [ALC269_ASUS_EEEPC_P703] = {
12386 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer },
12387 .init_verbs = { alc269_init_verbs,
12388 alc269_eeepc_amic_init_verbs },
12389 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12390 .dac_nids = alc269_dac_nids,
12391 .hp_nid = 0x03,
12392 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12393 .channel_mode = alc269_modes,
12394 .input_mux = &alc269_eeepc_amic_capture_source,
12395 .unsol_event = alc269_eeepc_amic_unsol_event,
12396 .init_hook = alc269_eeepc_amic_inithook,
12397 },
12398 [ALC269_ASUS_EEEPC_P901] = {
12399 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer},
12400 .init_verbs = { alc269_init_verbs,
12401 alc269_eeepc_dmic_init_verbs },
12402 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12403 .dac_nids = alc269_dac_nids,
12404 .hp_nid = 0x03,
12405 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12406 .channel_mode = alc269_modes,
12407 .input_mux = &alc269_eeepc_dmic_capture_source,
12408 .unsol_event = alc269_eeepc_dmic_unsol_event,
12409 .init_hook = alc269_eeepc_dmic_inithook,
12410 },
f6a92248
KY
12411};
12412
12413static int patch_alc269(struct hda_codec *codec)
12414{
12415 struct alc_spec *spec;
12416 int board_config;
12417 int err;
12418
12419 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12420 if (spec == NULL)
12421 return -ENOMEM;
12422
12423 codec->spec = spec;
12424
2c3bf9ab
TI
12425 alc_fix_pll_init(codec, 0x20, 0x04, 15);
12426
f6a92248
KY
12427 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12428 alc269_models,
12429 alc269_cfg_tbl);
12430
12431 if (board_config < 0) {
12432 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12433 "trying auto-probe from BIOS...\n");
12434 board_config = ALC269_AUTO;
12435 }
12436
12437 if (board_config == ALC269_AUTO) {
12438 /* automatic parse from the BIOS config */
12439 err = alc269_parse_auto_config(codec);
12440 if (err < 0) {
12441 alc_free(codec);
12442 return err;
12443 } else if (!err) {
12444 printk(KERN_INFO
12445 "hda_codec: Cannot set up configuration "
12446 "from BIOS. Using base mode...\n");
12447 board_config = ALC269_BASIC;
12448 }
12449 }
12450
12451 if (board_config != ALC269_AUTO)
12452 setup_preset(spec, &alc269_presets[board_config]);
12453
12454 spec->stream_name_analog = "ALC269 Analog";
12455 spec->stream_analog_playback = &alc269_pcm_analog_playback;
12456 spec->stream_analog_capture = &alc269_pcm_analog_capture;
12457
12458 spec->stream_name_digital = "ALC269 Digital";
12459 spec->stream_digital_playback = &alc269_pcm_digital_playback;
12460 spec->stream_digital_capture = &alc269_pcm_digital_capture;
12461
12462 spec->adc_nids = alc269_adc_nids;
12463 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
e01bf509 12464 spec->capsrc_nids = alc269_capsrc_nids;
f6a92248
KY
12465
12466 codec->patch_ops = alc_patch_ops;
12467 if (board_config == ALC269_AUTO)
12468 spec->init_hook = alc269_auto_init;
12469#ifdef CONFIG_SND_HDA_POWER_SAVE
12470 if (!spec->loopback.amplist)
12471 spec->loopback.amplist = alc269_loopbacks;
12472#endif
12473
12474 return 0;
12475}
12476
df694daa
KY
12477/*
12478 * ALC861 channel source setting (2/6 channel selection for 3-stack)
12479 */
12480
12481/*
12482 * set the path ways for 2 channel output
12483 * need to set the codec line out and mic 1 pin widgets to inputs
12484 */
12485static struct hda_verb alc861_threestack_ch2_init[] = {
12486 /* set pin widget 1Ah (line in) for input */
12487 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
12488 /* set pin widget 18h (mic1/2) for input, for mic also enable
12489 * the vref
12490 */
df694daa
KY
12491 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12492
9c7f852e
TI
12493 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12494#if 0
12495 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12496 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12497#endif
df694daa
KY
12498 { } /* end */
12499};
12500/*
12501 * 6ch mode
12502 * need to set the codec line out and mic 1 pin widgets to outputs
12503 */
12504static struct hda_verb alc861_threestack_ch6_init[] = {
12505 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12506 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12507 /* set pin widget 18h (mic1) for output (CLFE)*/
12508 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12509
12510 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 12511 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 12512
9c7f852e
TI
12513 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12514#if 0
12515 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12516 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12517#endif
df694daa
KY
12518 { } /* end */
12519};
12520
12521static struct hda_channel_mode alc861_threestack_modes[2] = {
12522 { 2, alc861_threestack_ch2_init },
12523 { 6, alc861_threestack_ch6_init },
12524};
22309c3e
TI
12525/* Set mic1 as input and unmute the mixer */
12526static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
12527 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12528 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12529 { } /* end */
12530};
12531/* Set mic1 as output and mute mixer */
12532static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
12533 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12534 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12535 { } /* end */
12536};
12537
12538static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
12539 { 2, alc861_uniwill_m31_ch2_init },
12540 { 4, alc861_uniwill_m31_ch4_init },
12541};
df694daa 12542
7cdbff94
MD
12543/* Set mic1 and line-in as input and unmute the mixer */
12544static struct hda_verb alc861_asus_ch2_init[] = {
12545 /* set pin widget 1Ah (line in) for input */
12546 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
12547 /* set pin widget 18h (mic1/2) for input, for mic also enable
12548 * the vref
12549 */
7cdbff94
MD
12550 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12551
12552 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12553#if 0
12554 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12555 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12556#endif
12557 { } /* end */
12558};
12559/* Set mic1 nad line-in as output and mute mixer */
12560static struct hda_verb alc861_asus_ch6_init[] = {
12561 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12562 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12563 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12564 /* set pin widget 18h (mic1) for output (CLFE)*/
12565 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12566 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12567 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12568 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12569
12570 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12571#if 0
12572 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12573 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12574#endif
12575 { } /* end */
12576};
12577
12578static struct hda_channel_mode alc861_asus_modes[2] = {
12579 { 2, alc861_asus_ch2_init },
12580 { 6, alc861_asus_ch6_init },
12581};
12582
df694daa
KY
12583/* patch-ALC861 */
12584
12585static struct snd_kcontrol_new alc861_base_mixer[] = {
12586 /* output mixer control */
12587 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12588 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12589 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12590 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12591 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12592
12593 /*Input mixer control */
12594 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12595 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12596 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12597 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12598 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12599 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12600 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12601 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12602 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12603 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 12604
df694daa
KY
12605 /* Capture mixer control */
12606 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12607 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12608 {
12609 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12610 .name = "Capture Source",
12611 .count = 1,
12612 .info = alc_mux_enum_info,
12613 .get = alc_mux_enum_get,
12614 .put = alc_mux_enum_put,
12615 },
12616 { } /* end */
12617};
12618
12619static struct snd_kcontrol_new alc861_3ST_mixer[] = {
12620 /* output mixer control */
12621 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12622 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12623 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12624 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12625 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12626
12627 /* Input mixer control */
12628 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12629 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12630 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12631 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12632 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12633 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12634 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12635 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12636 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12637 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 12638
df694daa
KY
12639 /* Capture mixer control */
12640 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12641 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12642 {
12643 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12644 .name = "Capture Source",
12645 .count = 1,
12646 .info = alc_mux_enum_info,
12647 .get = alc_mux_enum_get,
12648 .put = alc_mux_enum_put,
12649 },
12650 {
12651 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12652 .name = "Channel Mode",
12653 .info = alc_ch_mode_info,
12654 .get = alc_ch_mode_get,
12655 .put = alc_ch_mode_put,
12656 .private_value = ARRAY_SIZE(alc861_threestack_modes),
12657 },
12658 { } /* end */
a53d1aec
TD
12659};
12660
d1d985f0 12661static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
12662 /* output mixer control */
12663 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12664 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12665 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 12666
a53d1aec
TD
12667 /*Capture mixer control */
12668 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12669 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12670 {
12671 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12672 .name = "Capture Source",
12673 .count = 1,
12674 .info = alc_mux_enum_info,
12675 .get = alc_mux_enum_get,
12676 .put = alc_mux_enum_put,
12677 },
12678
12679 { } /* end */
f12ab1e0 12680};
a53d1aec 12681
22309c3e
TI
12682static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
12683 /* output mixer control */
12684 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12685 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12686 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12687 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12688 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12689
12690 /* Input mixer control */
12691 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12692 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12693 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12694 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12695 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12696 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12697 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12698 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12699 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12700 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 12701
22309c3e
TI
12702 /* Capture mixer control */
12703 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12704 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12705 {
12706 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12707 .name = "Capture Source",
12708 .count = 1,
12709 .info = alc_mux_enum_info,
12710 .get = alc_mux_enum_get,
12711 .put = alc_mux_enum_put,
12712 },
12713 {
12714 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12715 .name = "Channel Mode",
12716 .info = alc_ch_mode_info,
12717 .get = alc_ch_mode_get,
12718 .put = alc_ch_mode_put,
12719 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
12720 },
12721 { } /* end */
f12ab1e0 12722};
7cdbff94
MD
12723
12724static struct snd_kcontrol_new alc861_asus_mixer[] = {
12725 /* output mixer control */
12726 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12727 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12728 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12729 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12730 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12731
12732 /* Input mixer control */
12733 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12734 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12735 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12736 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12737 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12738 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12739 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12740 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12741 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
12742 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
12743
7cdbff94
MD
12744 /* Capture mixer control */
12745 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12746 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12747 {
12748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12749 .name = "Capture Source",
12750 .count = 1,
12751 .info = alc_mux_enum_info,
12752 .get = alc_mux_enum_get,
12753 .put = alc_mux_enum_put,
12754 },
12755 {
12756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12757 .name = "Channel Mode",
12758 .info = alc_ch_mode_info,
12759 .get = alc_ch_mode_get,
12760 .put = alc_ch_mode_put,
12761 .private_value = ARRAY_SIZE(alc861_asus_modes),
12762 },
12763 { }
56bb0cab
TI
12764};
12765
12766/* additional mixer */
d1d985f0 12767static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
12768 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12769 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12770 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
12771 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
12772 { }
12773};
7cdbff94 12774
df694daa
KY
12775/*
12776 * generic initialization of ADC, input mixers and output mixers
12777 */
12778static struct hda_verb alc861_base_init_verbs[] = {
12779 /*
12780 * Unmute ADC0 and set the default input to mic-in
12781 */
12782 /* port-A for surround (rear panel) */
12783 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12784 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
12785 /* port-B for mic-in (rear panel) with vref */
12786 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12787 /* port-C for line-in (rear panel) */
12788 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12789 /* port-D for Front */
12790 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12791 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12792 /* port-E for HP out (front panel) */
12793 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12794 /* route front PCM to HP */
9dece1d7 12795 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
12796 /* port-F for mic-in (front panel) with vref */
12797 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12798 /* port-G for CLFE (rear panel) */
12799 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12800 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12801 /* port-H for side (rear panel) */
12802 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12803 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
12804 /* CD-in */
12805 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12806 /* route front mic to ADC1*/
12807 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12808 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 12809
df694daa
KY
12810 /* Unmute DAC0~3 & spdif out*/
12811 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12812 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12813 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12814 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12815 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 12816
df694daa
KY
12817 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12818 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12819 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12820 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12821 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 12822
df694daa
KY
12823 /* Unmute Stereo Mixer 15 */
12824 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12825 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12826 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 12827 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
12828
12829 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12830 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12831 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12832 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12833 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12834 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12835 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12836 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
12837 /* hp used DAC 3 (Front) */
12838 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
12839 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12840
12841 { }
12842};
12843
12844static struct hda_verb alc861_threestack_init_verbs[] = {
12845 /*
12846 * Unmute ADC0 and set the default input to mic-in
12847 */
12848 /* port-A for surround (rear panel) */
12849 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12850 /* port-B for mic-in (rear panel) with vref */
12851 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12852 /* port-C for line-in (rear panel) */
12853 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12854 /* port-D for Front */
12855 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12856 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12857 /* port-E for HP out (front panel) */
12858 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12859 /* route front PCM to HP */
9dece1d7 12860 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
12861 /* port-F for mic-in (front panel) with vref */
12862 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12863 /* port-G for CLFE (rear panel) */
12864 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12865 /* port-H for side (rear panel) */
12866 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12867 /* CD-in */
12868 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12869 /* route front mic to ADC1*/
12870 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12871 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12872 /* Unmute DAC0~3 & spdif out*/
12873 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12874 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12875 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12876 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12877 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 12878
df694daa
KY
12879 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12880 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12881 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12882 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12883 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 12884
df694daa
KY
12885 /* Unmute Stereo Mixer 15 */
12886 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12887 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12888 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 12889 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
12890
12891 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12892 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12893 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12894 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12895 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12896 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12897 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12898 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
12899 /* hp used DAC 3 (Front) */
12900 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
12901 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12902 { }
12903};
22309c3e
TI
12904
12905static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
12906 /*
12907 * Unmute ADC0 and set the default input to mic-in
12908 */
12909 /* port-A for surround (rear panel) */
12910 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12911 /* port-B for mic-in (rear panel) with vref */
12912 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12913 /* port-C for line-in (rear panel) */
12914 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12915 /* port-D for Front */
12916 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12917 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12918 /* port-E for HP out (front panel) */
f12ab1e0
TI
12919 /* this has to be set to VREF80 */
12920 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 12921 /* route front PCM to HP */
9dece1d7 12922 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
12923 /* port-F for mic-in (front panel) with vref */
12924 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12925 /* port-G for CLFE (rear panel) */
12926 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12927 /* port-H for side (rear panel) */
12928 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12929 /* CD-in */
12930 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12931 /* route front mic to ADC1*/
12932 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12933 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12934 /* Unmute DAC0~3 & spdif out*/
12935 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12936 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12937 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12938 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12939 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 12940
22309c3e
TI
12941 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12942 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12943 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12944 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12945 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 12946
22309c3e
TI
12947 /* Unmute Stereo Mixer 15 */
12948 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12949 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12950 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 12951 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
12952
12953 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12954 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12955 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12956 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12957 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12958 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12959 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12960 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
12961 /* hp used DAC 3 (Front) */
12962 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
12963 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12964 { }
12965};
12966
7cdbff94
MD
12967static struct hda_verb alc861_asus_init_verbs[] = {
12968 /*
12969 * Unmute ADC0 and set the default input to mic-in
12970 */
f12ab1e0
TI
12971 /* port-A for surround (rear panel)
12972 * according to codec#0 this is the HP jack
12973 */
7cdbff94
MD
12974 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
12975 /* route front PCM to HP */
12976 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
12977 /* port-B for mic-in (rear panel) with vref */
12978 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12979 /* port-C for line-in (rear panel) */
12980 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12981 /* port-D for Front */
12982 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12983 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12984 /* port-E for HP out (front panel) */
f12ab1e0
TI
12985 /* this has to be set to VREF80 */
12986 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 12987 /* route front PCM to HP */
9dece1d7 12988 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
12989 /* port-F for mic-in (front panel) with vref */
12990 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12991 /* port-G for CLFE (rear panel) */
12992 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12993 /* port-H for side (rear panel) */
12994 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12995 /* CD-in */
12996 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12997 /* route front mic to ADC1*/
12998 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12999 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13000 /* Unmute DAC0~3 & spdif out*/
13001 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13002 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13003 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13004 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13005 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13006 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13007 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13008 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13009 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13010 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13011
7cdbff94
MD
13012 /* Unmute Stereo Mixer 15 */
13013 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13014 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13015 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 13016 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
13017
13018 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13019 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13020 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13021 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13022 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13023 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13024 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13025 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
13026 /* hp used DAC 3 (Front) */
13027 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
13028 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13029 { }
13030};
13031
56bb0cab
TI
13032/* additional init verbs for ASUS laptops */
13033static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13034 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13035 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13036 { }
13037};
7cdbff94 13038
df694daa
KY
13039/*
13040 * generic initialization of ADC, input mixers and output mixers
13041 */
13042static struct hda_verb alc861_auto_init_verbs[] = {
13043 /*
13044 * Unmute ADC0 and set the default input to mic-in
13045 */
f12ab1e0 13046 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 13047 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 13048
df694daa
KY
13049 /* Unmute DAC0~3 & spdif out*/
13050 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13051 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13052 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13053 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13054 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 13055
df694daa
KY
13056 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13057 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13058 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13059 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13060 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 13061
df694daa
KY
13062 /* Unmute Stereo Mixer 15 */
13063 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13064 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13065 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13066 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13067
13068 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13069 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13070 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13071 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13072 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13073 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13074 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13075 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13076
13077 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13078 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
13079 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13080 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
13081 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13082 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
13083 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13084 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa 13085
f12ab1e0 13086 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
13087
13088 { }
13089};
13090
a53d1aec
TD
13091static struct hda_verb alc861_toshiba_init_verbs[] = {
13092 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 13093
a53d1aec
TD
13094 { }
13095};
13096
13097/* toggle speaker-output according to the hp-jack state */
13098static void alc861_toshiba_automute(struct hda_codec *codec)
13099{
13100 unsigned int present;
13101
13102 present = snd_hda_codec_read(codec, 0x0f, 0,
13103 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
13104 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13105 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13106 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13107 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
13108}
13109
13110static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13111 unsigned int res)
13112{
a53d1aec
TD
13113 if ((res >> 26) == ALC880_HP_EVENT)
13114 alc861_toshiba_automute(codec);
13115}
13116
df694daa
KY
13117/* pcm configuration: identiacal with ALC880 */
13118#define alc861_pcm_analog_playback alc880_pcm_analog_playback
13119#define alc861_pcm_analog_capture alc880_pcm_analog_capture
13120#define alc861_pcm_digital_playback alc880_pcm_digital_playback
13121#define alc861_pcm_digital_capture alc880_pcm_digital_capture
13122
13123
13124#define ALC861_DIGOUT_NID 0x07
13125
13126static struct hda_channel_mode alc861_8ch_modes[1] = {
13127 { 8, NULL }
13128};
13129
13130static hda_nid_t alc861_dac_nids[4] = {
13131 /* front, surround, clfe, side */
13132 0x03, 0x06, 0x05, 0x04
13133};
13134
9c7f852e
TI
13135static hda_nid_t alc660_dac_nids[3] = {
13136 /* front, clfe, surround */
13137 0x03, 0x05, 0x06
13138};
13139
df694daa
KY
13140static hda_nid_t alc861_adc_nids[1] = {
13141 /* ADC0-2 */
13142 0x08,
13143};
13144
13145static struct hda_input_mux alc861_capture_source = {
13146 .num_items = 5,
13147 .items = {
13148 { "Mic", 0x0 },
13149 { "Front Mic", 0x3 },
13150 { "Line", 0x1 },
13151 { "CD", 0x4 },
13152 { "Mixer", 0x5 },
13153 },
13154};
13155
13156/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
13157static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13158 const struct auto_pin_cfg *cfg)
df694daa
KY
13159{
13160 int i;
13161 hda_nid_t nid;
13162
13163 spec->multiout.dac_nids = spec->private_dac_nids;
13164 for (i = 0; i < cfg->line_outs; i++) {
13165 nid = cfg->line_out_pins[i];
13166 if (nid) {
13167 if (i >= ARRAY_SIZE(alc861_dac_nids))
13168 continue;
13169 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13170 }
13171 }
13172 spec->multiout.num_dacs = cfg->line_outs;
13173 return 0;
13174}
13175
13176/* add playback controls from the parsed DAC table */
13177static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13178 const struct auto_pin_cfg *cfg)
13179{
13180 char name[32];
f12ab1e0
TI
13181 static const char *chname[4] = {
13182 "Front", "Surround", NULL /*CLFE*/, "Side"
13183 };
df694daa
KY
13184 hda_nid_t nid;
13185 int i, idx, err;
13186
13187 for (i = 0; i < cfg->line_outs; i++) {
13188 nid = spec->multiout.dac_nids[i];
f12ab1e0 13189 if (!nid)
df694daa
KY
13190 continue;
13191 if (nid == 0x05) {
13192 /* Center/LFE */
f12ab1e0
TI
13193 err = add_control(spec, ALC_CTL_BIND_MUTE,
13194 "Center Playback Switch",
13195 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13196 HDA_OUTPUT));
13197 if (err < 0)
df694daa 13198 return err;
f12ab1e0
TI
13199 err = add_control(spec, ALC_CTL_BIND_MUTE,
13200 "LFE Playback Switch",
13201 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13202 HDA_OUTPUT));
13203 if (err < 0)
df694daa
KY
13204 return err;
13205 } else {
f12ab1e0
TI
13206 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13207 idx++)
df694daa
KY
13208 if (nid == alc861_dac_nids[idx])
13209 break;
13210 sprintf(name, "%s Playback Switch", chname[idx]);
f12ab1e0
TI
13211 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13212 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13213 HDA_OUTPUT));
13214 if (err < 0)
df694daa
KY
13215 return err;
13216 }
13217 }
13218 return 0;
13219}
13220
13221static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13222{
13223 int err;
13224 hda_nid_t nid;
13225
f12ab1e0 13226 if (!pin)
df694daa
KY
13227 return 0;
13228
13229 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13230 nid = 0x03;
f12ab1e0
TI
13231 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13232 "Headphone Playback Switch",
13233 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13234 if (err < 0)
df694daa
KY
13235 return err;
13236 spec->multiout.hp_nid = nid;
13237 }
13238 return 0;
13239}
13240
13241/* create playback/capture controls for input pins */
f12ab1e0
TI
13242static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13243 const struct auto_pin_cfg *cfg)
df694daa 13244{
df694daa
KY
13245 struct hda_input_mux *imux = &spec->private_imux;
13246 int i, err, idx, idx1;
13247
13248 for (i = 0; i < AUTO_PIN_LAST; i++) {
f12ab1e0 13249 switch (cfg->input_pins[i]) {
df694daa
KY
13250 case 0x0c:
13251 idx1 = 1;
f12ab1e0 13252 idx = 2; /* Line In */
df694daa
KY
13253 break;
13254 case 0x0f:
13255 idx1 = 2;
f12ab1e0 13256 idx = 2; /* Line In */
df694daa
KY
13257 break;
13258 case 0x0d:
13259 idx1 = 0;
f12ab1e0 13260 idx = 1; /* Mic In */
df694daa 13261 break;
f12ab1e0 13262 case 0x10:
df694daa 13263 idx1 = 3;
f12ab1e0 13264 idx = 1; /* Mic In */
df694daa
KY
13265 break;
13266 case 0x11:
13267 idx1 = 4;
f12ab1e0 13268 idx = 0; /* CD */
df694daa
KY
13269 break;
13270 default:
13271 continue;
13272 }
13273
4a471b7d
TI
13274 err = new_analog_input(spec, cfg->input_pins[i],
13275 auto_pin_cfg_labels[i], idx, 0x15);
df694daa
KY
13276 if (err < 0)
13277 return err;
13278
4a471b7d 13279 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
df694daa 13280 imux->items[imux->num_items].index = idx1;
f12ab1e0 13281 imux->num_items++;
df694daa
KY
13282 }
13283 return 0;
13284}
13285
13286static struct snd_kcontrol_new alc861_capture_mixer[] = {
13287 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13288 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13289
13290 {
13291 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13292 /* The multiple "Capture Source" controls confuse alsamixer
13293 * So call somewhat different..
df694daa
KY
13294 */
13295 /* .name = "Capture Source", */
13296 .name = "Input Source",
13297 .count = 1,
13298 .info = alc_mux_enum_info,
13299 .get = alc_mux_enum_get,
13300 .put = alc_mux_enum_put,
13301 },
13302 { } /* end */
13303};
13304
f12ab1e0
TI
13305static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13306 hda_nid_t nid,
df694daa
KY
13307 int pin_type, int dac_idx)
13308{
564c5bea
JL
13309 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13310 pin_type);
13311 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13312 AMP_OUT_UNMUTE);
df694daa
KY
13313}
13314
13315static void alc861_auto_init_multi_out(struct hda_codec *codec)
13316{
13317 struct alc_spec *spec = codec->spec;
13318 int i;
13319
bc9f98a9 13320 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
df694daa
KY
13321 for (i = 0; i < spec->autocfg.line_outs; i++) {
13322 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 13323 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 13324 if (nid)
baba8ee9 13325 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 13326 spec->multiout.dac_nids[i]);
df694daa
KY
13327 }
13328}
13329
13330static void alc861_auto_init_hp_out(struct hda_codec *codec)
13331{
13332 struct alc_spec *spec = codec->spec;
13333 hda_nid_t pin;
13334
eb06ed8f 13335 pin = spec->autocfg.hp_pins[0];
df694daa 13336 if (pin) /* connect to front */
f12ab1e0
TI
13337 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13338 spec->multiout.dac_nids[0]);
f6c7e546
TI
13339 pin = spec->autocfg.speaker_pins[0];
13340 if (pin)
13341 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
13342}
13343
13344static void alc861_auto_init_analog_input(struct hda_codec *codec)
13345{
13346 struct alc_spec *spec = codec->spec;
13347 int i;
13348
13349 for (i = 0; i < AUTO_PIN_LAST; i++) {
13350 hda_nid_t nid = spec->autocfg.input_pins[i];
f12ab1e0
TI
13351 if (nid >= 0x0c && nid <= 0x11) {
13352 snd_hda_codec_write(codec, nid, 0,
13353 AC_VERB_SET_PIN_WIDGET_CONTROL,
13354 i <= AUTO_PIN_FRONT_MIC ?
13355 PIN_VREF80 : PIN_IN);
df694daa
KY
13356 }
13357 }
13358}
13359
13360/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
13361/* return 1 if successful, 0 if the proper config is not found,
13362 * or a negative error code
13363 */
df694daa
KY
13364static int alc861_parse_auto_config(struct hda_codec *codec)
13365{
13366 struct alc_spec *spec = codec->spec;
13367 int err;
13368 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13369
f12ab1e0
TI
13370 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13371 alc861_ignore);
13372 if (err < 0)
df694daa 13373 return err;
f12ab1e0 13374 if (!spec->autocfg.line_outs)
df694daa
KY
13375 return 0; /* can't find valid BIOS pin config */
13376
f12ab1e0
TI
13377 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13378 if (err < 0)
13379 return err;
13380 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13381 if (err < 0)
13382 return err;
13383 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13384 if (err < 0)
13385 return err;
13386 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13387 if (err < 0)
df694daa
KY
13388 return err;
13389
13390 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13391
13392 if (spec->autocfg.dig_out_pin)
13393 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13394
603c4019 13395 if (spec->kctls.list)
d88897ea 13396 add_mixer(spec, spec->kctls.list);
df694daa 13397
d88897ea 13398 add_verb(spec, alc861_auto_init_verbs);
df694daa 13399
a1e8d2da 13400 spec->num_mux_defs = 1;
df694daa
KY
13401 spec->input_mux = &spec->private_imux;
13402
13403 spec->adc_nids = alc861_adc_nids;
13404 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
d88897ea 13405 add_mixer(spec, alc861_capture_mixer);
df694daa 13406
e044c39a 13407 store_pin_configs(codec);
df694daa
KY
13408 return 1;
13409}
13410
ae6b813a
TI
13411/* additional initialization for auto-configuration model */
13412static void alc861_auto_init(struct hda_codec *codec)
df694daa 13413{
f6c7e546 13414 struct alc_spec *spec = codec->spec;
df694daa
KY
13415 alc861_auto_init_multi_out(codec);
13416 alc861_auto_init_hp_out(codec);
13417 alc861_auto_init_analog_input(codec);
f6c7e546 13418 if (spec->unsol_event)
7fb0d78f 13419 alc_inithook(codec);
df694daa
KY
13420}
13421
cb53c626
TI
13422#ifdef CONFIG_SND_HDA_POWER_SAVE
13423static struct hda_amp_list alc861_loopbacks[] = {
13424 { 0x15, HDA_INPUT, 0 },
13425 { 0x15, HDA_INPUT, 1 },
13426 { 0x15, HDA_INPUT, 2 },
13427 { 0x15, HDA_INPUT, 3 },
13428 { } /* end */
13429};
13430#endif
13431
df694daa
KY
13432
13433/*
13434 * configuration and preset
13435 */
f5fcc13c
TI
13436static const char *alc861_models[ALC861_MODEL_LAST] = {
13437 [ALC861_3ST] = "3stack",
13438 [ALC660_3ST] = "3stack-660",
13439 [ALC861_3ST_DIG] = "3stack-dig",
13440 [ALC861_6ST_DIG] = "6stack-dig",
13441 [ALC861_UNIWILL_M31] = "uniwill-m31",
13442 [ALC861_TOSHIBA] = "toshiba",
13443 [ALC861_ASUS] = "asus",
13444 [ALC861_ASUS_LAPTOP] = "asus-laptop",
13445 [ALC861_AUTO] = "auto",
13446};
13447
13448static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 13449 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
13450 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13451 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13452 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 13453 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 13454 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 13455 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
13456 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13457 * Any other models that need this preset?
13458 */
13459 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
13460 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13461 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 13462 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
13463 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13464 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13465 /* FIXME: the below seems conflict */
13466 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 13467 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 13468 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
13469 {}
13470};
13471
13472static struct alc_config_preset alc861_presets[] = {
13473 [ALC861_3ST] = {
13474 .mixers = { alc861_3ST_mixer },
13475 .init_verbs = { alc861_threestack_init_verbs },
13476 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13477 .dac_nids = alc861_dac_nids,
13478 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13479 .channel_mode = alc861_threestack_modes,
4e195a7b 13480 .need_dac_fix = 1,
df694daa
KY
13481 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13482 .adc_nids = alc861_adc_nids,
13483 .input_mux = &alc861_capture_source,
13484 },
13485 [ALC861_3ST_DIG] = {
13486 .mixers = { alc861_base_mixer },
13487 .init_verbs = { alc861_threestack_init_verbs },
13488 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13489 .dac_nids = alc861_dac_nids,
13490 .dig_out_nid = ALC861_DIGOUT_NID,
13491 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13492 .channel_mode = alc861_threestack_modes,
4e195a7b 13493 .need_dac_fix = 1,
df694daa
KY
13494 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13495 .adc_nids = alc861_adc_nids,
13496 .input_mux = &alc861_capture_source,
13497 },
13498 [ALC861_6ST_DIG] = {
13499 .mixers = { alc861_base_mixer },
13500 .init_verbs = { alc861_base_init_verbs },
13501 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13502 .dac_nids = alc861_dac_nids,
13503 .dig_out_nid = ALC861_DIGOUT_NID,
13504 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13505 .channel_mode = alc861_8ch_modes,
13506 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13507 .adc_nids = alc861_adc_nids,
13508 .input_mux = &alc861_capture_source,
13509 },
9c7f852e
TI
13510 [ALC660_3ST] = {
13511 .mixers = { alc861_3ST_mixer },
13512 .init_verbs = { alc861_threestack_init_verbs },
13513 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
13514 .dac_nids = alc660_dac_nids,
13515 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13516 .channel_mode = alc861_threestack_modes,
4e195a7b 13517 .need_dac_fix = 1,
9c7f852e
TI
13518 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13519 .adc_nids = alc861_adc_nids,
13520 .input_mux = &alc861_capture_source,
13521 },
22309c3e
TI
13522 [ALC861_UNIWILL_M31] = {
13523 .mixers = { alc861_uniwill_m31_mixer },
13524 .init_verbs = { alc861_uniwill_m31_init_verbs },
13525 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13526 .dac_nids = alc861_dac_nids,
13527 .dig_out_nid = ALC861_DIGOUT_NID,
13528 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13529 .channel_mode = alc861_uniwill_m31_modes,
13530 .need_dac_fix = 1,
13531 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13532 .adc_nids = alc861_adc_nids,
13533 .input_mux = &alc861_capture_source,
13534 },
a53d1aec
TD
13535 [ALC861_TOSHIBA] = {
13536 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
13537 .init_verbs = { alc861_base_init_verbs,
13538 alc861_toshiba_init_verbs },
a53d1aec
TD
13539 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13540 .dac_nids = alc861_dac_nids,
13541 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13542 .channel_mode = alc883_3ST_2ch_modes,
13543 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13544 .adc_nids = alc861_adc_nids,
13545 .input_mux = &alc861_capture_source,
13546 .unsol_event = alc861_toshiba_unsol_event,
13547 .init_hook = alc861_toshiba_automute,
13548 },
7cdbff94
MD
13549 [ALC861_ASUS] = {
13550 .mixers = { alc861_asus_mixer },
13551 .init_verbs = { alc861_asus_init_verbs },
13552 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13553 .dac_nids = alc861_dac_nids,
13554 .dig_out_nid = ALC861_DIGOUT_NID,
13555 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
13556 .channel_mode = alc861_asus_modes,
13557 .need_dac_fix = 1,
13558 .hp_nid = 0x06,
13559 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13560 .adc_nids = alc861_adc_nids,
13561 .input_mux = &alc861_capture_source,
13562 },
56bb0cab
TI
13563 [ALC861_ASUS_LAPTOP] = {
13564 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
13565 .init_verbs = { alc861_asus_init_verbs,
13566 alc861_asus_laptop_init_verbs },
13567 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13568 .dac_nids = alc861_dac_nids,
13569 .dig_out_nid = ALC861_DIGOUT_NID,
13570 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13571 .channel_mode = alc883_3ST_2ch_modes,
13572 .need_dac_fix = 1,
13573 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13574 .adc_nids = alc861_adc_nids,
13575 .input_mux = &alc861_capture_source,
13576 },
13577};
df694daa
KY
13578
13579
13580static int patch_alc861(struct hda_codec *codec)
13581{
13582 struct alc_spec *spec;
13583 int board_config;
13584 int err;
13585
dc041e0b 13586 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
13587 if (spec == NULL)
13588 return -ENOMEM;
13589
f12ab1e0 13590 codec->spec = spec;
df694daa 13591
f5fcc13c
TI
13592 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
13593 alc861_models,
13594 alc861_cfg_tbl);
9c7f852e 13595
f5fcc13c 13596 if (board_config < 0) {
9c7f852e
TI
13597 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
13598 "trying auto-probe from BIOS...\n");
df694daa
KY
13599 board_config = ALC861_AUTO;
13600 }
13601
13602 if (board_config == ALC861_AUTO) {
13603 /* automatic parse from the BIOS config */
13604 err = alc861_parse_auto_config(codec);
13605 if (err < 0) {
13606 alc_free(codec);
13607 return err;
f12ab1e0 13608 } else if (!err) {
9c7f852e
TI
13609 printk(KERN_INFO
13610 "hda_codec: Cannot set up configuration "
13611 "from BIOS. Using base mode...\n");
df694daa
KY
13612 board_config = ALC861_3ST_DIG;
13613 }
13614 }
13615
13616 if (board_config != ALC861_AUTO)
13617 setup_preset(spec, &alc861_presets[board_config]);
13618
13619 spec->stream_name_analog = "ALC861 Analog";
13620 spec->stream_analog_playback = &alc861_pcm_analog_playback;
13621 spec->stream_analog_capture = &alc861_pcm_analog_capture;
13622
13623 spec->stream_name_digital = "ALC861 Digital";
13624 spec->stream_digital_playback = &alc861_pcm_digital_playback;
13625 spec->stream_digital_capture = &alc861_pcm_digital_capture;
13626
2134ea4f
TI
13627 spec->vmaster_nid = 0x03;
13628
df694daa
KY
13629 codec->patch_ops = alc_patch_ops;
13630 if (board_config == ALC861_AUTO)
ae6b813a 13631 spec->init_hook = alc861_auto_init;
cb53c626
TI
13632#ifdef CONFIG_SND_HDA_POWER_SAVE
13633 if (!spec->loopback.amplist)
13634 spec->loopback.amplist = alc861_loopbacks;
13635#endif
ea1fb29a 13636
1da177e4
LT
13637 return 0;
13638}
13639
f32610ed
JS
13640/*
13641 * ALC861-VD support
13642 *
13643 * Based on ALC882
13644 *
13645 * In addition, an independent DAC
13646 */
13647#define ALC861VD_DIGOUT_NID 0x06
13648
13649static hda_nid_t alc861vd_dac_nids[4] = {
13650 /* front, surr, clfe, side surr */
13651 0x02, 0x03, 0x04, 0x05
13652};
13653
13654/* dac_nids for ALC660vd are in a different order - according to
13655 * Realtek's driver.
13656 * This should probably tesult in a different mixer for 6stack models
13657 * of ALC660vd codecs, but for now there is only 3stack mixer
13658 * - and it is the same as in 861vd.
13659 * adc_nids in ALC660vd are (is) the same as in 861vd
13660 */
13661static hda_nid_t alc660vd_dac_nids[3] = {
13662 /* front, rear, clfe, rear_surr */
13663 0x02, 0x04, 0x03
13664};
13665
13666static hda_nid_t alc861vd_adc_nids[1] = {
13667 /* ADC0 */
13668 0x09,
13669};
13670
e1406348
TI
13671static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
13672
f32610ed
JS
13673/* input MUX */
13674/* FIXME: should be a matrix-type input source selection */
13675static struct hda_input_mux alc861vd_capture_source = {
13676 .num_items = 4,
13677 .items = {
13678 { "Mic", 0x0 },
13679 { "Front Mic", 0x1 },
13680 { "Line", 0x2 },
13681 { "CD", 0x4 },
13682 },
13683};
13684
272a527c 13685static struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 13686 .num_items = 2,
272a527c 13687 .items = {
b419f346
TD
13688 { "Ext Mic", 0x0 },
13689 { "Int Mic", 0x1 },
272a527c
KY
13690 },
13691};
13692
d1a991a6
KY
13693static struct hda_input_mux alc861vd_hp_capture_source = {
13694 .num_items = 2,
13695 .items = {
13696 { "Front Mic", 0x0 },
13697 { "ATAPI Mic", 0x1 },
13698 },
13699};
13700
f32610ed
JS
13701#define alc861vd_mux_enum_info alc_mux_enum_info
13702#define alc861vd_mux_enum_get alc_mux_enum_get
e1406348
TI
13703/* ALC861VD has the ALC882-type input selection (but has only one ADC) */
13704#define alc861vd_mux_enum_put alc882_mux_enum_put
f32610ed
JS
13705
13706/*
13707 * 2ch mode
13708 */
13709static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
13710 { 2, NULL }
13711};
13712
13713/*
13714 * 6ch mode
13715 */
13716static struct hda_verb alc861vd_6stack_ch6_init[] = {
13717 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13718 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13719 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13720 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13721 { } /* end */
13722};
13723
13724/*
13725 * 8ch mode
13726 */
13727static struct hda_verb alc861vd_6stack_ch8_init[] = {
13728 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13729 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13730 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13731 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13732 { } /* end */
13733};
13734
13735static struct hda_channel_mode alc861vd_6stack_modes[2] = {
13736 { 6, alc861vd_6stack_ch6_init },
13737 { 8, alc861vd_6stack_ch8_init },
13738};
13739
13740static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
13741 {
13742 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13743 .name = "Channel Mode",
13744 .info = alc_ch_mode_info,
13745 .get = alc_ch_mode_get,
13746 .put = alc_ch_mode_put,
13747 },
13748 { } /* end */
13749};
13750
13751static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
13752 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13753 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13754
13755 {
13756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13757 /* The multiple "Capture Source" controls confuse alsamixer
13758 * So call somewhat different..
f32610ed
JS
13759 */
13760 /* .name = "Capture Source", */
13761 .name = "Input Source",
13762 .count = 1,
13763 .info = alc861vd_mux_enum_info,
13764 .get = alc861vd_mux_enum_get,
13765 .put = alc861vd_mux_enum_put,
13766 },
13767 { } /* end */
13768};
13769
13770/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13771 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13772 */
13773static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
13774 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13775 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13776
13777 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13778 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
13779
13780 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
13781 HDA_OUTPUT),
13782 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
13783 HDA_OUTPUT),
13784 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13785 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
13786
13787 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
13788 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
13789
13790 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13791
13792 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13793 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13794 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13795
13796 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13797 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13798 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13799
13800 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13801 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13802
13803 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13804 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13805
13806 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13807 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13808
13809 { } /* end */
13810};
13811
13812static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
13813 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13814 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13815
13816 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13817
13818 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13819 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13820 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13821
13822 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13823 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13824 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13825
13826 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13827 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13828
13829 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13830 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13831
13832 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13833 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13834
13835 { } /* end */
13836};
13837
bdd148a3
KY
13838static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
13839 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13840 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
13841 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13842
13843 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13844
13845 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13846 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13847 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13848
13849 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13850 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13851 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13852
13853 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13854 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13855
13856 { } /* end */
13857};
13858
b419f346
TD
13859/* Pin assignment: Speaker=0x14, HP = 0x15,
13860 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c
KY
13861 */
13862static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
13863 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13864 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
13865 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13866 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
b419f346
TD
13867 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13868 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13869 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13870 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13871 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13872 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13873 HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
13874 HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
272a527c
KY
13875 { } /* end */
13876};
13877
d1a991a6
KY
13878/* Pin assignment: Speaker=0x14, Line-out = 0x15,
13879 * Front Mic=0x18, ATAPI Mic = 0x19,
13880 */
13881static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
13882 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13883 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13884 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13885 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13886 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13887 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13888 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13889 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 13890
d1a991a6
KY
13891 { } /* end */
13892};
13893
f32610ed
JS
13894/*
13895 * generic initialization of ADC, input mixers and output mixers
13896 */
13897static struct hda_verb alc861vd_volume_init_verbs[] = {
13898 /*
13899 * Unmute ADC0 and set the default input to mic-in
13900 */
13901 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13902 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13903
13904 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
13905 * the analog-loopback mixer widget
13906 */
13907 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
13908 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13909 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13910 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13911 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13912 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
13913
13914 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
13915 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13916 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13917 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 13918 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
13919
13920 /*
13921 * Set up output mixers (0x02 - 0x05)
13922 */
13923 /* set vol=0 to output mixers */
13924 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13925 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13926 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13927 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13928
13929 /* set up input amps for analog loopback */
13930 /* Amp Indices: DAC = 0, mixer = 1 */
13931 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13932 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13933 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13934 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13935 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13936 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13937 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13938 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13939
13940 { }
13941};
13942
13943/*
13944 * 3-stack pin configuration:
13945 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
13946 */
13947static struct hda_verb alc861vd_3stack_init_verbs[] = {
13948 /*
13949 * Set pin mode and muting
13950 */
13951 /* set front pin widgets 0x14 for output */
13952 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13953 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13954 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13955
13956 /* Mic (rear) pin: input vref at 80% */
13957 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13958 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13959 /* Front Mic pin: input vref at 80% */
13960 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13961 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13962 /* Line In pin: input */
13963 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13964 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13965 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13966 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13967 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13968 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13969 /* CD pin widget for input */
13970 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13971
13972 { }
13973};
13974
13975/*
13976 * 6-stack pin configuration:
13977 */
13978static struct hda_verb alc861vd_6stack_init_verbs[] = {
13979 /*
13980 * Set pin mode and muting
13981 */
13982 /* set front pin widgets 0x14 for output */
13983 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13984 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13985 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13986
13987 /* Rear Pin: output 1 (0x0d) */
13988 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13989 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13990 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13991 /* CLFE Pin: output 2 (0x0e) */
13992 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13993 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13994 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
13995 /* Side Pin: output 3 (0x0f) */
13996 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13997 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13998 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
13999
14000 /* Mic (rear) pin: input vref at 80% */
14001 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14002 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14003 /* Front Mic pin: input vref at 80% */
14004 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14005 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14006 /* Line In pin: input */
14007 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14008 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14009 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14010 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14011 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14012 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14013 /* CD pin widget for input */
14014 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14015
14016 { }
14017};
14018
bdd148a3
KY
14019static struct hda_verb alc861vd_eapd_verbs[] = {
14020 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14021 { }
14022};
14023
f9423e7a
KY
14024static struct hda_verb alc660vd_eapd_verbs[] = {
14025 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14026 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14027 { }
14028};
14029
bdd148a3
KY
14030static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14031 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14032 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14033 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14034 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 14035 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
14036 {}
14037};
14038
14039/* toggle speaker-output according to the hp-jack state */
14040static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
14041{
14042 unsigned int present;
14043 unsigned char bits;
14044
14045 present = snd_hda_codec_read(codec, 0x1b, 0,
14046 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
14047 bits = present ? HDA_AMP_MUTE : 0;
14048 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14049 HDA_AMP_MUTE, bits);
bdd148a3
KY
14050}
14051
14052static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14053{
14054 unsigned int present;
14055 unsigned char bits;
14056
14057 present = snd_hda_codec_read(codec, 0x18, 0,
14058 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
14059 bits = present ? HDA_AMP_MUTE : 0;
14060 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14061 HDA_AMP_MUTE, bits);
bdd148a3
KY
14062}
14063
14064static void alc861vd_lenovo_automute(struct hda_codec *codec)
14065{
14066 alc861vd_lenovo_hp_automute(codec);
14067 alc861vd_lenovo_mic_automute(codec);
14068}
14069
14070static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14071 unsigned int res)
14072{
14073 switch (res >> 26) {
14074 case ALC880_HP_EVENT:
14075 alc861vd_lenovo_hp_automute(codec);
14076 break;
14077 case ALC880_MIC_EVENT:
14078 alc861vd_lenovo_mic_automute(codec);
14079 break;
14080 }
14081}
14082
272a527c
KY
14083static struct hda_verb alc861vd_dallas_verbs[] = {
14084 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14085 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14086 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14087 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14088
14089 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14090 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14091 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14092 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14093 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14094 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14095 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14096 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 14097
272a527c
KY
14098 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14099 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14100 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14101 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14102 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14103 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14104 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14105 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14106
14107 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14108 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14109 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14110 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14111 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14112 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14113 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14114 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14115
14116 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14117 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14118 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14119 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14120
14121 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 14122 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
14123 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14124
14125 { } /* end */
14126};
14127
14128/* toggle speaker-output according to the hp-jack state */
14129static void alc861vd_dallas_automute(struct hda_codec *codec)
14130{
14131 unsigned int present;
14132
14133 present = snd_hda_codec_read(codec, 0x15, 0,
14134 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
14135 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14136 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
14137}
14138
14139static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
14140{
14141 if ((res >> 26) == ALC880_HP_EVENT)
14142 alc861vd_dallas_automute(codec);
14143}
14144
cb53c626
TI
14145#ifdef CONFIG_SND_HDA_POWER_SAVE
14146#define alc861vd_loopbacks alc880_loopbacks
14147#endif
14148
f32610ed
JS
14149/* pcm configuration: identiacal with ALC880 */
14150#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14151#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14152#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14153#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14154
14155/*
14156 * configuration and preset
14157 */
14158static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14159 [ALC660VD_3ST] = "3stack-660",
983f8ae4 14160 [ALC660VD_3ST_DIG] = "3stack-660-digout",
f32610ed
JS
14161 [ALC861VD_3ST] = "3stack",
14162 [ALC861VD_3ST_DIG] = "3stack-digout",
14163 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 14164 [ALC861VD_LENOVO] = "lenovo",
272a527c 14165 [ALC861VD_DALLAS] = "dallas",
983f8ae4 14166 [ALC861VD_HP] = "hp",
f32610ed
JS
14167 [ALC861VD_AUTO] = "auto",
14168};
14169
14170static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
14171 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14172 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 14173 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f32610ed 14174 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
2522d735 14175 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO),
6963f84c 14176 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 14177 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 14178 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 14179 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
272a527c 14180 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
542d7c66 14181 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 14182 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 14183 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
ac3e3741
TI
14184 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
14185 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
be321a89 14186 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
625dc0bf 14187 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
14188 {}
14189};
14190
14191static struct alc_config_preset alc861vd_presets[] = {
14192 [ALC660VD_3ST] = {
14193 .mixers = { alc861vd_3st_mixer },
14194 .init_verbs = { alc861vd_volume_init_verbs,
14195 alc861vd_3stack_init_verbs },
14196 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14197 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
14198 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14199 .channel_mode = alc861vd_3stack_2ch_modes,
14200 .input_mux = &alc861vd_capture_source,
14201 },
6963f84c
MC
14202 [ALC660VD_3ST_DIG] = {
14203 .mixers = { alc861vd_3st_mixer },
14204 .init_verbs = { alc861vd_volume_init_verbs,
14205 alc861vd_3stack_init_verbs },
14206 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14207 .dac_nids = alc660vd_dac_nids,
14208 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
14209 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14210 .channel_mode = alc861vd_3stack_2ch_modes,
14211 .input_mux = &alc861vd_capture_source,
14212 },
f32610ed
JS
14213 [ALC861VD_3ST] = {
14214 .mixers = { alc861vd_3st_mixer },
14215 .init_verbs = { alc861vd_volume_init_verbs,
14216 alc861vd_3stack_init_verbs },
14217 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14218 .dac_nids = alc861vd_dac_nids,
14219 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14220 .channel_mode = alc861vd_3stack_2ch_modes,
14221 .input_mux = &alc861vd_capture_source,
14222 },
14223 [ALC861VD_3ST_DIG] = {
14224 .mixers = { alc861vd_3st_mixer },
14225 .init_verbs = { alc861vd_volume_init_verbs,
14226 alc861vd_3stack_init_verbs },
14227 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14228 .dac_nids = alc861vd_dac_nids,
14229 .dig_out_nid = ALC861VD_DIGOUT_NID,
14230 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14231 .channel_mode = alc861vd_3stack_2ch_modes,
14232 .input_mux = &alc861vd_capture_source,
14233 },
14234 [ALC861VD_6ST_DIG] = {
14235 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14236 .init_verbs = { alc861vd_volume_init_verbs,
14237 alc861vd_6stack_init_verbs },
14238 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14239 .dac_nids = alc861vd_dac_nids,
14240 .dig_out_nid = ALC861VD_DIGOUT_NID,
14241 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14242 .channel_mode = alc861vd_6stack_modes,
14243 .input_mux = &alc861vd_capture_source,
14244 },
bdd148a3
KY
14245 [ALC861VD_LENOVO] = {
14246 .mixers = { alc861vd_lenovo_mixer },
14247 .init_verbs = { alc861vd_volume_init_verbs,
14248 alc861vd_3stack_init_verbs,
14249 alc861vd_eapd_verbs,
14250 alc861vd_lenovo_unsol_verbs },
14251 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14252 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
14253 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14254 .channel_mode = alc861vd_3stack_2ch_modes,
14255 .input_mux = &alc861vd_capture_source,
14256 .unsol_event = alc861vd_lenovo_unsol_event,
14257 .init_hook = alc861vd_lenovo_automute,
14258 },
272a527c
KY
14259 [ALC861VD_DALLAS] = {
14260 .mixers = { alc861vd_dallas_mixer },
14261 .init_verbs = { alc861vd_dallas_verbs },
14262 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14263 .dac_nids = alc861vd_dac_nids,
272a527c
KY
14264 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14265 .channel_mode = alc861vd_3stack_2ch_modes,
14266 .input_mux = &alc861vd_dallas_capture_source,
14267 .unsol_event = alc861vd_dallas_unsol_event,
14268 .init_hook = alc861vd_dallas_automute,
d1a991a6
KY
14269 },
14270 [ALC861VD_HP] = {
14271 .mixers = { alc861vd_hp_mixer },
14272 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14273 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14274 .dac_nids = alc861vd_dac_nids,
d1a991a6 14275 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
14276 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14277 .channel_mode = alc861vd_3stack_2ch_modes,
14278 .input_mux = &alc861vd_hp_capture_source,
14279 .unsol_event = alc861vd_dallas_unsol_event,
14280 .init_hook = alc861vd_dallas_automute,
ea1fb29a 14281 },
f32610ed
JS
14282};
14283
14284/*
14285 * BIOS auto configuration
14286 */
14287static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14288 hda_nid_t nid, int pin_type, int dac_idx)
14289{
f6c7e546 14290 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
14291}
14292
14293static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14294{
14295 struct alc_spec *spec = codec->spec;
14296 int i;
14297
bc9f98a9 14298 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
f32610ed
JS
14299 for (i = 0; i <= HDA_SIDE; i++) {
14300 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 14301 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
14302 if (nid)
14303 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 14304 pin_type, i);
f32610ed
JS
14305 }
14306}
14307
14308
14309static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14310{
14311 struct alc_spec *spec = codec->spec;
14312 hda_nid_t pin;
14313
14314 pin = spec->autocfg.hp_pins[0];
14315 if (pin) /* connect to front and use dac 0 */
14316 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
14317 pin = spec->autocfg.speaker_pins[0];
14318 if (pin)
14319 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
14320}
14321
14322#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14323#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14324
14325static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14326{
14327 struct alc_spec *spec = codec->spec;
14328 int i;
14329
14330 for (i = 0; i < AUTO_PIN_LAST; i++) {
14331 hda_nid_t nid = spec->autocfg.input_pins[i];
14332 if (alc861vd_is_input_pin(nid)) {
14333 snd_hda_codec_write(codec, nid, 0,
14334 AC_VERB_SET_PIN_WIDGET_CONTROL,
14335 i <= AUTO_PIN_FRONT_MIC ?
14336 PIN_VREF80 : PIN_IN);
14337 if (nid != ALC861VD_PIN_CD_NID)
14338 snd_hda_codec_write(codec, nid, 0,
14339 AC_VERB_SET_AMP_GAIN_MUTE,
14340 AMP_OUT_MUTE);
14341 }
14342 }
14343}
14344
f511b01c
TI
14345#define alc861vd_auto_init_input_src alc882_auto_init_input_src
14346
f32610ed
JS
14347#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14348#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14349
14350/* add playback controls from the parsed DAC table */
14351/* Based on ALC880 version. But ALC861VD has separate,
14352 * different NIDs for mute/unmute switch and volume control */
14353static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14354 const struct auto_pin_cfg *cfg)
14355{
14356 char name[32];
14357 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14358 hda_nid_t nid_v, nid_s;
14359 int i, err;
14360
14361 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 14362 if (!spec->multiout.dac_nids[i])
f32610ed
JS
14363 continue;
14364 nid_v = alc861vd_idx_to_mixer_vol(
14365 alc880_dac_to_idx(
14366 spec->multiout.dac_nids[i]));
14367 nid_s = alc861vd_idx_to_mixer_switch(
14368 alc880_dac_to_idx(
14369 spec->multiout.dac_nids[i]));
14370
14371 if (i == 2) {
14372 /* Center/LFE */
f12ab1e0
TI
14373 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14374 "Center Playback Volume",
14375 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14376 HDA_OUTPUT));
14377 if (err < 0)
f32610ed 14378 return err;
f12ab1e0
TI
14379 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14380 "LFE Playback Volume",
14381 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14382 HDA_OUTPUT));
14383 if (err < 0)
f32610ed 14384 return err;
f12ab1e0
TI
14385 err = add_control(spec, ALC_CTL_BIND_MUTE,
14386 "Center Playback Switch",
14387 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14388 HDA_INPUT));
14389 if (err < 0)
f32610ed 14390 return err;
f12ab1e0
TI
14391 err = add_control(spec, ALC_CTL_BIND_MUTE,
14392 "LFE Playback Switch",
14393 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14394 HDA_INPUT));
14395 if (err < 0)
f32610ed
JS
14396 return err;
14397 } else {
14398 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
14399 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14400 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14401 HDA_OUTPUT));
14402 if (err < 0)
f32610ed
JS
14403 return err;
14404 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0 14405 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
bdd148a3 14406 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
14407 HDA_INPUT));
14408 if (err < 0)
f32610ed
JS
14409 return err;
14410 }
14411 }
14412 return 0;
14413}
14414
14415/* add playback controls for speaker and HP outputs */
14416/* Based on ALC880 version. But ALC861VD has separate,
14417 * different NIDs for mute/unmute switch and volume control */
14418static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14419 hda_nid_t pin, const char *pfx)
14420{
14421 hda_nid_t nid_v, nid_s;
14422 int err;
14423 char name[32];
14424
f12ab1e0 14425 if (!pin)
f32610ed
JS
14426 return 0;
14427
14428 if (alc880_is_fixed_pin(pin)) {
14429 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14430 /* specify the DAC as the extra output */
f12ab1e0 14431 if (!spec->multiout.hp_nid)
f32610ed
JS
14432 spec->multiout.hp_nid = nid_v;
14433 else
14434 spec->multiout.extra_out_nid[0] = nid_v;
14435 /* control HP volume/switch on the output mixer amp */
14436 nid_v = alc861vd_idx_to_mixer_vol(
14437 alc880_fixed_pin_idx(pin));
14438 nid_s = alc861vd_idx_to_mixer_switch(
14439 alc880_fixed_pin_idx(pin));
14440
14441 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
14442 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14443 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14444 if (err < 0)
f32610ed
JS
14445 return err;
14446 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
14447 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14448 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14449 if (err < 0)
f32610ed
JS
14450 return err;
14451 } else if (alc880_is_multi_pin(pin)) {
14452 /* set manual connection */
14453 /* we have only a switch on HP-out PIN */
14454 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
14455 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14456 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14457 if (err < 0)
f32610ed
JS
14458 return err;
14459 }
14460 return 0;
14461}
14462
14463/* parse the BIOS configuration and set up the alc_spec
14464 * return 1 if successful, 0 if the proper config is not found,
14465 * or a negative error code
14466 * Based on ALC880 version - had to change it to override
14467 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14468static int alc861vd_parse_auto_config(struct hda_codec *codec)
14469{
14470 struct alc_spec *spec = codec->spec;
14471 int err;
14472 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14473
f12ab1e0
TI
14474 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14475 alc861vd_ignore);
14476 if (err < 0)
f32610ed 14477 return err;
f12ab1e0 14478 if (!spec->autocfg.line_outs)
f32610ed
JS
14479 return 0; /* can't find valid BIOS pin config */
14480
f12ab1e0
TI
14481 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14482 if (err < 0)
14483 return err;
14484 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14485 if (err < 0)
14486 return err;
14487 err = alc861vd_auto_create_extra_out(spec,
14488 spec->autocfg.speaker_pins[0],
14489 "Speaker");
14490 if (err < 0)
14491 return err;
14492 err = alc861vd_auto_create_extra_out(spec,
14493 spec->autocfg.hp_pins[0],
14494 "Headphone");
14495 if (err < 0)
14496 return err;
14497 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14498 if (err < 0)
f32610ed
JS
14499 return err;
14500
14501 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14502
14503 if (spec->autocfg.dig_out_pin)
14504 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14505
603c4019 14506 if (spec->kctls.list)
d88897ea 14507 add_mixer(spec, spec->kctls.list);
f32610ed 14508
d88897ea 14509 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
14510
14511 spec->num_mux_defs = 1;
14512 spec->input_mux = &spec->private_imux;
14513
776e184e
TI
14514 err = alc_auto_add_mic_boost(codec);
14515 if (err < 0)
14516 return err;
14517
e044c39a 14518 store_pin_configs(codec);
f32610ed
JS
14519 return 1;
14520}
14521
14522/* additional initialization for auto-configuration model */
14523static void alc861vd_auto_init(struct hda_codec *codec)
14524{
f6c7e546 14525 struct alc_spec *spec = codec->spec;
f32610ed
JS
14526 alc861vd_auto_init_multi_out(codec);
14527 alc861vd_auto_init_hp_out(codec);
14528 alc861vd_auto_init_analog_input(codec);
f511b01c 14529 alc861vd_auto_init_input_src(codec);
f6c7e546 14530 if (spec->unsol_event)
7fb0d78f 14531 alc_inithook(codec);
f32610ed
JS
14532}
14533
14534static int patch_alc861vd(struct hda_codec *codec)
14535{
14536 struct alc_spec *spec;
14537 int err, board_config;
14538
14539 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14540 if (spec == NULL)
14541 return -ENOMEM;
14542
14543 codec->spec = spec;
14544
14545 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14546 alc861vd_models,
14547 alc861vd_cfg_tbl);
14548
14549 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14550 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14551 "ALC861VD, trying auto-probe from BIOS...\n");
14552 board_config = ALC861VD_AUTO;
14553 }
14554
14555 if (board_config == ALC861VD_AUTO) {
14556 /* automatic parse from the BIOS config */
14557 err = alc861vd_parse_auto_config(codec);
14558 if (err < 0) {
14559 alc_free(codec);
14560 return err;
f12ab1e0 14561 } else if (!err) {
f32610ed
JS
14562 printk(KERN_INFO
14563 "hda_codec: Cannot set up configuration "
14564 "from BIOS. Using base mode...\n");
14565 board_config = ALC861VD_3ST;
14566 }
14567 }
14568
14569 if (board_config != ALC861VD_AUTO)
14570 setup_preset(spec, &alc861vd_presets[board_config]);
14571
2f893286
KY
14572 if (codec->vendor_id == 0x10ec0660) {
14573 spec->stream_name_analog = "ALC660-VD Analog";
14574 spec->stream_name_digital = "ALC660-VD Digital";
f9423e7a 14575 /* always turn on EAPD */
d88897ea 14576 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
14577 } else {
14578 spec->stream_name_analog = "ALC861VD Analog";
14579 spec->stream_name_digital = "ALC861VD Digital";
14580 }
14581
f32610ed
JS
14582 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
14583 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
14584
f32610ed
JS
14585 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
14586 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
14587
14588 spec->adc_nids = alc861vd_adc_nids;
14589 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
e1406348 14590 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 14591
d88897ea 14592 add_mixer(spec, alc861vd_capture_mixer);
f32610ed 14593
2134ea4f
TI
14594 spec->vmaster_nid = 0x02;
14595
f32610ed
JS
14596 codec->patch_ops = alc_patch_ops;
14597
14598 if (board_config == ALC861VD_AUTO)
14599 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
14600#ifdef CONFIG_SND_HDA_POWER_SAVE
14601 if (!spec->loopback.amplist)
14602 spec->loopback.amplist = alc861vd_loopbacks;
14603#endif
f32610ed
JS
14604
14605 return 0;
14606}
14607
bc9f98a9
KY
14608/*
14609 * ALC662 support
14610 *
14611 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
14612 * configuration. Each pin widget can choose any input DACs and a mixer.
14613 * Each ADC is connected from a mixer of all inputs. This makes possible
14614 * 6-channel independent captures.
14615 *
14616 * In addition, an independent DAC for the multi-playback (not used in this
14617 * driver yet).
14618 */
14619#define ALC662_DIGOUT_NID 0x06
14620#define ALC662_DIGIN_NID 0x0a
14621
14622static hda_nid_t alc662_dac_nids[4] = {
14623 /* front, rear, clfe, rear_surr */
14624 0x02, 0x03, 0x04
14625};
14626
14627static hda_nid_t alc662_adc_nids[1] = {
14628 /* ADC1-2 */
14629 0x09,
14630};
e1406348 14631
77a261b7 14632static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
e1406348 14633
bc9f98a9
KY
14634/* input MUX */
14635/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
14636static struct hda_input_mux alc662_capture_source = {
14637 .num_items = 4,
14638 .items = {
14639 { "Mic", 0x0 },
14640 { "Front Mic", 0x1 },
14641 { "Line", 0x2 },
14642 { "CD", 0x4 },
14643 },
14644};
14645
14646static struct hda_input_mux alc662_lenovo_101e_capture_source = {
14647 .num_items = 2,
14648 .items = {
14649 { "Mic", 0x1 },
14650 { "Line", 0x2 },
14651 },
14652};
291702f0
KY
14653
14654static struct hda_input_mux alc662_eeepc_capture_source = {
14655 .num_items = 2,
14656 .items = {
14657 { "i-Mic", 0x1 },
14658 { "e-Mic", 0x0 },
14659 },
14660};
14661
6dda9f4a
KY
14662static struct hda_input_mux alc663_capture_source = {
14663 .num_items = 3,
14664 .items = {
14665 { "Mic", 0x0 },
14666 { "Front Mic", 0x1 },
14667 { "Line", 0x2 },
14668 },
14669};
14670
14671static struct hda_input_mux alc663_m51va_capture_source = {
14672 .num_items = 2,
14673 .items = {
14674 { "Ext-Mic", 0x0 },
14675 { "D-Mic", 0x9 },
14676 },
14677};
14678
bc9f98a9
KY
14679#define alc662_mux_enum_info alc_mux_enum_info
14680#define alc662_mux_enum_get alc_mux_enum_get
e1406348 14681#define alc662_mux_enum_put alc882_mux_enum_put
bc9f98a9 14682
bc9f98a9
KY
14683/*
14684 * 2ch mode
14685 */
14686static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
14687 { 2, NULL }
14688};
14689
14690/*
14691 * 2ch mode
14692 */
14693static struct hda_verb alc662_3ST_ch2_init[] = {
14694 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
14695 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14696 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
14697 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14698 { } /* end */
14699};
14700
14701/*
14702 * 6ch mode
14703 */
14704static struct hda_verb alc662_3ST_ch6_init[] = {
14705 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14706 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14707 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
14708 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14709 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14710 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
14711 { } /* end */
14712};
14713
14714static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
14715 { 2, alc662_3ST_ch2_init },
14716 { 6, alc662_3ST_ch6_init },
14717};
14718
14719/*
14720 * 2ch mode
14721 */
14722static struct hda_verb alc662_sixstack_ch6_init[] = {
14723 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14724 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14725 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14726 { } /* end */
14727};
14728
14729/*
14730 * 6ch mode
14731 */
14732static struct hda_verb alc662_sixstack_ch8_init[] = {
14733 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14734 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14735 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14736 { } /* end */
14737};
14738
14739static struct hda_channel_mode alc662_5stack_modes[2] = {
14740 { 2, alc662_sixstack_ch6_init },
14741 { 6, alc662_sixstack_ch8_init },
14742};
14743
14744/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14745 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14746 */
14747
14748static struct snd_kcontrol_new alc662_base_mixer[] = {
14749 /* output mixer control */
14750 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 14751 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 14752 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 14753 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
14754 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14755 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
14756 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14757 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
14758 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14759
14760 /*Input mixer control */
14761 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
14762 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
14763 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
14764 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
14765 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
14766 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
14767 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
14768 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
14769 { } /* end */
14770};
14771
14772static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
14773 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 14774 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
14775 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14776 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14777 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14778 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14779 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14780 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14781 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14782 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14783 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14784 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14785 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
bc9f98a9
KY
14786 { } /* end */
14787};
14788
14789static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
14790 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 14791 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 14792 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 14793 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
14794 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14795 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
14796 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14797 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
14798 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14799 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14800 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14801 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14802 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14803 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14804 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14805 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14806 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14807 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14808 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
bc9f98a9
KY
14809 { } /* end */
14810};
14811
14812static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
14813 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14814 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
14815 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14816 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
14817 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14818 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14819 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14820 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14821 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
14822 { } /* end */
14823};
14824
291702f0 14825static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
86cd9298 14826 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
291702f0 14827
b4818494
HRK
14828 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14829 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
291702f0
KY
14830
14831 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
14832 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14833 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14834
14835 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
14836 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14837 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14838 { } /* end */
14839};
14840
8c427226 14841static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
31bffaa9
TI
14842 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14843 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8c427226
KY
14844 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14845 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
14846 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14847 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14848 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
14849 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
86cd9298 14850 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8c427226
KY
14851 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
14852 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14853 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14854 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14855 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14856 { } /* end */
14857};
14858
f1d4e28b
KY
14859static struct hda_bind_ctls alc663_asus_bind_master_vol = {
14860 .ops = &snd_hda_bind_vol,
14861 .values = {
14862 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14863 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
14864 0
14865 },
14866};
14867
14868static struct hda_bind_ctls alc663_asus_one_bind_switch = {
14869 .ops = &snd_hda_bind_sw,
14870 .values = {
14871 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14872 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14873 0
14874 },
14875};
14876
6dda9f4a 14877static struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
14878 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14879 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
14880 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14881 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14882 { } /* end */
14883};
14884
14885static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
14886 .ops = &snd_hda_bind_sw,
14887 .values = {
14888 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14889 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14890 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14891 0
14892 },
14893};
14894
14895static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
14896 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14897 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
14898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14900 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14901 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14902
14903 { } /* end */
14904};
14905
14906static struct hda_bind_ctls alc663_asus_four_bind_switch = {
14907 .ops = &snd_hda_bind_sw,
14908 .values = {
14909 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14910 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14911 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
14912 0
14913 },
14914};
14915
14916static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
14917 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14918 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
14919 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14920 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14921 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14922 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14923 { } /* end */
14924};
14925
14926static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
14927 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14928 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
14929 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14930 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14931 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14932 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14933 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14934 { } /* end */
14935};
14936
14937static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
14938 .ops = &snd_hda_bind_vol,
14939 .values = {
14940 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14941 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
14942 0
14943 },
14944};
14945
14946static struct hda_bind_ctls alc663_asus_two_bind_switch = {
14947 .ops = &snd_hda_bind_sw,
14948 .values = {
14949 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14950 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
14951 0
14952 },
14953};
14954
14955static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
14956 HDA_BIND_VOL("Master Playback Volume",
14957 &alc663_asus_two_bind_master_vol),
14958 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14959 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
14960 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14961 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14962 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
14963 { } /* end */
14964};
14965
14966static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
14967 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14968 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14969 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14970 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14972 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
14973 { } /* end */
14974};
14975
14976static struct snd_kcontrol_new alc663_g71v_mixer[] = {
14977 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14978 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14979 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14980 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14981 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14982
14983 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14984 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14985 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14986 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14987 { } /* end */
14988};
14989
14990static struct snd_kcontrol_new alc663_g50v_mixer[] = {
14991 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14992 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14993 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14994
14995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14997 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14998 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14999 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15000 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15001 { } /* end */
15002};
15003
bc9f98a9
KY
15004static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15005 {
15006 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15007 .name = "Channel Mode",
15008 .info = alc_ch_mode_info,
15009 .get = alc_ch_mode_get,
15010 .put = alc_ch_mode_put,
15011 },
15012 { } /* end */
15013};
15014
15015static struct hda_verb alc662_init_verbs[] = {
15016 /* ADC: mute amp left and right */
15017 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15018 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15019 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15020
cb53c626
TI
15021 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15022 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15023 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15024 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15025 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9 15026
b60dd394
KY
15027 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15028 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15029 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15030 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15031 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15032 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
15033
15034 /* Front Pin: output 0 (0x0c) */
15035 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15036 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15037
15038 /* Rear Pin: output 1 (0x0d) */
15039 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15040 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15041
15042 /* CLFE Pin: output 2 (0x0e) */
15043 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15044 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15045
15046 /* Mic (rear) pin: input vref at 80% */
15047 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15048 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15049 /* Front Mic pin: input vref at 80% */
15050 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15051 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15052 /* Line In pin: input */
15053 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15054 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15055 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15056 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15057 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15058 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15059 /* CD pin widget for input */
15060 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15061
15062 /* FIXME: use matrix-type input source selection */
15063 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15064 /* Input mixer */
15065 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15066 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15067 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15068 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
291702f0
KY
15069
15070 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15071 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15072 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15073 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6dda9f4a
KY
15074
15075 /* always trun on EAPD */
15076 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15077 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15078
bc9f98a9
KY
15079 { }
15080};
15081
15082static struct hda_verb alc662_sue_init_verbs[] = {
15083 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15084 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
15085 {}
15086};
15087
15088static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15089 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15090 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15091 {}
bc9f98a9
KY
15092};
15093
8c427226
KY
15094/* Set Unsolicited Event*/
15095static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15096 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15097 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15098 {}
15099};
15100
bc9f98a9
KY
15101/*
15102 * generic initialization of ADC, input mixers and output mixers
15103 */
15104static struct hda_verb alc662_auto_init_verbs[] = {
15105 /*
15106 * Unmute ADC and set the default input to mic-in
15107 */
15108 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15109 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15110
15111 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15112 * mixer widget
15113 * Note: PASD motherboards uses the Line In 2 as the input for front
15114 * panel mic (mic 2)
15115 */
15116 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
15117 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15118 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15119 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15120 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15121 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9
KY
15122
15123 /*
15124 * Set up output mixers (0x0c - 0x0f)
15125 */
15126 /* set vol=0 to output mixers */
15127 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15128 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15129 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15130
15131 /* set up input amps for analog loopback */
15132 /* Amp Indices: DAC = 0, mixer = 1 */
b60dd394
KY
15133 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15134 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15135 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15136 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15137 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15138 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
15139
15140
15141 /* FIXME: use matrix-type input source selection */
15142 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15143 /* Input mixer */
15144 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
d1a991a6 15145 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
bc9f98a9
KY
15146 { }
15147};
15148
24fb9173
TI
15149/* additional verbs for ALC663 */
15150static struct hda_verb alc663_auto_init_verbs[] = {
15151 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15152 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15153 { }
15154};
15155
6dda9f4a 15156static struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
15157 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15158 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
15159 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15160 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
15161 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15162 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15163 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15164 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15165 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15166 {}
15167};
15168
15169static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15170 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15171 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15172 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15173 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15174 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15175 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15176 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15177 {}
15178};
15179
15180static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15181 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15182 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15183 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15184 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15185 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15186 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15187 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15188 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15189 {}
15190};
6dda9f4a 15191
f1d4e28b
KY
15192static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15193 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15194 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15195 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15196 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15197 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15198 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15199 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15200 {}
15201};
6dda9f4a 15202
f1d4e28b
KY
15203static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15204 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15205 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15206 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15207 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15208 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15209 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15210 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15211 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15212 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
15213 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15214 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
15215 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15216 {}
15217};
15218
15219static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15220 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15221 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15222 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15223 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15224 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15226 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15227 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15228 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15229 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15230 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15231 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
15232 {}
15233};
15234
15235static struct hda_verb alc663_g71v_init_verbs[] = {
15236 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15237 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15238 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15239
15240 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15241 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15242 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15243
15244 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15245 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15246 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15247 {}
15248};
15249
15250static struct hda_verb alc663_g50v_init_verbs[] = {
15251 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15252 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15253 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15254
15255 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15256 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15257 {}
15258};
15259
f1d4e28b
KY
15260static struct hda_verb alc662_ecs_init_verbs[] = {
15261 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15262 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15263 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15264 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15265 {}
15266};
15267
bc9f98a9
KY
15268/* capture mixer elements */
15269static struct snd_kcontrol_new alc662_capture_mixer[] = {
15270 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15271 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15272 {
15273 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15274 /* The multiple "Capture Source" controls confuse alsamixer
15275 * So call somewhat different..
bc9f98a9
KY
15276 */
15277 /* .name = "Capture Source", */
15278 .name = "Input Source",
15279 .count = 1,
6e7939bb
HRK
15280 .info = alc662_mux_enum_info,
15281 .get = alc662_mux_enum_get,
15282 .put = alc662_mux_enum_put,
bc9f98a9
KY
15283 },
15284 { } /* end */
15285};
15286
f1d4e28b
KY
15287static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15288 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15289 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15290 { } /* end */
15291};
15292
bc9f98a9
KY
15293static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15294{
15295 unsigned int present;
f12ab1e0 15296 unsigned char bits;
bc9f98a9
KY
15297
15298 present = snd_hda_codec_read(codec, 0x14, 0,
15299 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
15300 bits = present ? HDA_AMP_MUTE : 0;
15301 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15302 HDA_AMP_MUTE, bits);
bc9f98a9
KY
15303}
15304
15305static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15306{
15307 unsigned int present;
f12ab1e0 15308 unsigned char bits;
bc9f98a9
KY
15309
15310 present = snd_hda_codec_read(codec, 0x1b, 0,
15311 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
15312 bits = present ? HDA_AMP_MUTE : 0;
15313 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15314 HDA_AMP_MUTE, bits);
15315 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15316 HDA_AMP_MUTE, bits);
bc9f98a9
KY
15317}
15318
15319static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15320 unsigned int res)
15321{
15322 if ((res >> 26) == ALC880_HP_EVENT)
15323 alc662_lenovo_101e_all_automute(codec);
15324 if ((res >> 26) == ALC880_FRONT_EVENT)
15325 alc662_lenovo_101e_ispeaker_automute(codec);
15326}
15327
291702f0
KY
15328static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15329{
15330 unsigned int present;
15331
15332 present = snd_hda_codec_read(codec, 0x18, 0,
15333 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15334 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15335 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15336 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15337 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15338 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15339 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15340 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15341 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15342}
15343
15344/* unsolicited event for HP jack sensing */
15345static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15346 unsigned int res)
15347{
15348 if ((res >> 26) == ALC880_HP_EVENT)
15349 alc262_hippo1_automute( codec );
15350
15351 if ((res >> 26) == ALC880_MIC_EVENT)
15352 alc662_eeepc_mic_automute(codec);
15353}
15354
15355static void alc662_eeepc_inithook(struct hda_codec *codec)
15356{
15357 alc262_hippo1_automute( codec );
15358 alc662_eeepc_mic_automute(codec);
15359}
15360
8c427226
KY
15361static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15362{
15363 unsigned int mute;
15364 unsigned int present;
15365
15366 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15367 present = snd_hda_codec_read(codec, 0x14, 0,
15368 AC_VERB_GET_PIN_SENSE, 0);
15369 present = (present & 0x80000000) != 0;
15370 if (present) {
15371 /* mute internal speaker */
15372 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
ea1fb29a 15373 HDA_AMP_MUTE, HDA_AMP_MUTE);
8c427226
KY
15374 } else {
15375 /* unmute internal speaker if necessary */
15376 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15377 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
ea1fb29a 15378 HDA_AMP_MUTE, mute);
8c427226
KY
15379 }
15380}
15381
15382/* unsolicited event for HP jack sensing */
15383static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15384 unsigned int res)
15385{
15386 if ((res >> 26) == ALC880_HP_EVENT)
15387 alc662_eeepc_ep20_automute(codec);
15388}
15389
15390static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15391{
15392 alc662_eeepc_ep20_automute(codec);
15393}
15394
6dda9f4a
KY
15395static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15396{
15397 unsigned int present;
15398 unsigned char bits;
15399
15400 present = snd_hda_codec_read(codec, 0x21, 0,
f1d4e28b
KY
15401 AC_VERB_GET_PIN_SENSE, 0)
15402 & AC_PINSENSE_PRESENCE;
6dda9f4a 15403 bits = present ? HDA_AMP_MUTE : 0;
f1d4e28b
KY
15404 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15405 AMP_IN_MUTE(0), bits);
15406 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15407 AMP_IN_MUTE(0), bits);
15408}
15409
15410static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15411{
15412 unsigned int present;
15413 unsigned char bits;
15414
15415 present = snd_hda_codec_read(codec, 0x21, 0,
15416 AC_VERB_GET_PIN_SENSE, 0)
15417 & AC_PINSENSE_PRESENCE;
15418 bits = present ? HDA_AMP_MUTE : 0;
15419 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15420 AMP_IN_MUTE(0), bits);
15421 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15422 AMP_IN_MUTE(0), bits);
15423 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15424 AMP_IN_MUTE(0), bits);
15425 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15426 AMP_IN_MUTE(0), bits);
15427}
15428
15429static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15430{
15431 unsigned int present;
15432 unsigned char bits;
15433
15434 present = snd_hda_codec_read(codec, 0x15, 0,
15435 AC_VERB_GET_PIN_SENSE, 0)
15436 & AC_PINSENSE_PRESENCE;
15437 bits = present ? HDA_AMP_MUTE : 0;
15438 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15439 AMP_IN_MUTE(0), bits);
15440 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15441 AMP_IN_MUTE(0), bits);
15442 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15443 AMP_IN_MUTE(0), bits);
15444 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15445 AMP_IN_MUTE(0), bits);
15446}
15447
15448static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15449{
15450 unsigned int present;
15451 unsigned char bits;
15452
15453 present = snd_hda_codec_read(codec, 0x1b, 0,
15454 AC_VERB_GET_PIN_SENSE, 0)
15455 & AC_PINSENSE_PRESENCE;
15456 bits = present ? 0 : PIN_OUT;
15457 snd_hda_codec_write(codec, 0x14, 0,
15458 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15459}
15460
15461static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15462{
15463 unsigned int present1, present2;
15464
15465 present1 = snd_hda_codec_read(codec, 0x21, 0,
15466 AC_VERB_GET_PIN_SENSE, 0)
15467 & AC_PINSENSE_PRESENCE;
15468 present2 = snd_hda_codec_read(codec, 0x15, 0,
15469 AC_VERB_GET_PIN_SENSE, 0)
15470 & AC_PINSENSE_PRESENCE;
15471
15472 if (present1 || present2) {
15473 snd_hda_codec_write_cache(codec, 0x14, 0,
15474 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15475 } else {
15476 snd_hda_codec_write_cache(codec, 0x14, 0,
15477 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15478 }
15479}
15480
15481static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15482{
15483 unsigned int present1, present2;
15484
15485 present1 = snd_hda_codec_read(codec, 0x1b, 0,
15486 AC_VERB_GET_PIN_SENSE, 0)
15487 & AC_PINSENSE_PRESENCE;
15488 present2 = snd_hda_codec_read(codec, 0x15, 0,
15489 AC_VERB_GET_PIN_SENSE, 0)
15490 & AC_PINSENSE_PRESENCE;
15491
15492 if (present1 || present2) {
15493 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15494 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15495 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15496 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15497 } else {
15498 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15499 AMP_IN_MUTE(0), 0);
15500 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15501 AMP_IN_MUTE(0), 0);
15502 }
6dda9f4a
KY
15503}
15504
15505static void alc663_m51va_mic_automute(struct hda_codec *codec)
15506{
15507 unsigned int present;
15508
15509 present = snd_hda_codec_read(codec, 0x18, 0,
ea1fb29a
KY
15510 AC_VERB_GET_PIN_SENSE, 0)
15511 & AC_PINSENSE_PRESENCE;
6dda9f4a 15512 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 15513 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
6dda9f4a 15514 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 15515 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
6dda9f4a 15516 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 15517 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
6dda9f4a 15518 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
ea1fb29a 15519 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
6dda9f4a
KY
15520}
15521
15522static void alc663_m51va_unsol_event(struct hda_codec *codec,
15523 unsigned int res)
15524{
15525 switch (res >> 26) {
15526 case ALC880_HP_EVENT:
15527 alc663_m51va_speaker_automute(codec);
15528 break;
15529 case ALC880_MIC_EVENT:
15530 alc663_m51va_mic_automute(codec);
15531 break;
15532 }
15533}
15534
15535static void alc663_m51va_inithook(struct hda_codec *codec)
15536{
15537 alc663_m51va_speaker_automute(codec);
15538 alc663_m51va_mic_automute(codec);
15539}
15540
f1d4e28b
KY
15541/* ***************** Mode1 ******************************/
15542static void alc663_mode1_unsol_event(struct hda_codec *codec,
15543 unsigned int res)
15544{
15545 switch (res >> 26) {
15546 case ALC880_HP_EVENT:
15547 alc663_m51va_speaker_automute(codec);
15548 break;
15549 case ALC880_MIC_EVENT:
15550 alc662_eeepc_mic_automute(codec);
15551 break;
15552 }
15553}
15554
15555static void alc663_mode1_inithook(struct hda_codec *codec)
15556{
15557 alc663_m51va_speaker_automute(codec);
15558 alc662_eeepc_mic_automute(codec);
15559}
15560/* ***************** Mode2 ******************************/
15561static void alc662_mode2_unsol_event(struct hda_codec *codec,
15562 unsigned int res)
15563{
15564 switch (res >> 26) {
15565 case ALC880_HP_EVENT:
15566 alc662_f5z_speaker_automute(codec);
15567 break;
15568 case ALC880_MIC_EVENT:
15569 alc662_eeepc_mic_automute(codec);
15570 break;
15571 }
15572}
15573
15574static void alc662_mode2_inithook(struct hda_codec *codec)
15575{
15576 alc662_f5z_speaker_automute(codec);
15577 alc662_eeepc_mic_automute(codec);
15578}
15579/* ***************** Mode3 ******************************/
15580static void alc663_mode3_unsol_event(struct hda_codec *codec,
15581 unsigned int res)
15582{
15583 switch (res >> 26) {
15584 case ALC880_HP_EVENT:
15585 alc663_two_hp_m1_speaker_automute(codec);
15586 break;
15587 case ALC880_MIC_EVENT:
15588 alc662_eeepc_mic_automute(codec);
15589 break;
15590 }
15591}
15592
15593static void alc663_mode3_inithook(struct hda_codec *codec)
15594{
15595 alc663_two_hp_m1_speaker_automute(codec);
15596 alc662_eeepc_mic_automute(codec);
15597}
15598/* ***************** Mode4 ******************************/
15599static void alc663_mode4_unsol_event(struct hda_codec *codec,
15600 unsigned int res)
15601{
15602 switch (res >> 26) {
15603 case ALC880_HP_EVENT:
15604 alc663_21jd_two_speaker_automute(codec);
15605 break;
15606 case ALC880_MIC_EVENT:
15607 alc662_eeepc_mic_automute(codec);
15608 break;
15609 }
15610}
15611
15612static void alc663_mode4_inithook(struct hda_codec *codec)
15613{
15614 alc663_21jd_two_speaker_automute(codec);
15615 alc662_eeepc_mic_automute(codec);
15616}
15617/* ***************** Mode5 ******************************/
15618static void alc663_mode5_unsol_event(struct hda_codec *codec,
15619 unsigned int res)
15620{
15621 switch (res >> 26) {
15622 case ALC880_HP_EVENT:
15623 alc663_15jd_two_speaker_automute(codec);
15624 break;
15625 case ALC880_MIC_EVENT:
15626 alc662_eeepc_mic_automute(codec);
15627 break;
15628 }
15629}
15630
15631static void alc663_mode5_inithook(struct hda_codec *codec)
15632{
15633 alc663_15jd_two_speaker_automute(codec);
15634 alc662_eeepc_mic_automute(codec);
15635}
15636/* ***************** Mode6 ******************************/
15637static void alc663_mode6_unsol_event(struct hda_codec *codec,
15638 unsigned int res)
15639{
15640 switch (res >> 26) {
15641 case ALC880_HP_EVENT:
15642 alc663_two_hp_m2_speaker_automute(codec);
15643 break;
15644 case ALC880_MIC_EVENT:
15645 alc662_eeepc_mic_automute(codec);
15646 break;
15647 }
15648}
15649
15650static void alc663_mode6_inithook(struct hda_codec *codec)
15651{
15652 alc663_two_hp_m2_speaker_automute(codec);
15653 alc662_eeepc_mic_automute(codec);
15654}
15655
6dda9f4a
KY
15656static void alc663_g71v_hp_automute(struct hda_codec *codec)
15657{
15658 unsigned int present;
15659 unsigned char bits;
15660
15661 present = snd_hda_codec_read(codec, 0x21, 0,
15662 AC_VERB_GET_PIN_SENSE, 0)
15663 & AC_PINSENSE_PRESENCE;
15664 bits = present ? HDA_AMP_MUTE : 0;
15665 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15666 HDA_AMP_MUTE, bits);
15667 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15668 HDA_AMP_MUTE, bits);
15669}
15670
15671static void alc663_g71v_front_automute(struct hda_codec *codec)
15672{
15673 unsigned int present;
15674 unsigned char bits;
15675
15676 present = snd_hda_codec_read(codec, 0x15, 0,
15677 AC_VERB_GET_PIN_SENSE, 0)
15678 & AC_PINSENSE_PRESENCE;
15679 bits = present ? HDA_AMP_MUTE : 0;
15680 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15681 HDA_AMP_MUTE, bits);
15682}
15683
15684static void alc663_g71v_unsol_event(struct hda_codec *codec,
15685 unsigned int res)
15686{
15687 switch (res >> 26) {
15688 case ALC880_HP_EVENT:
15689 alc663_g71v_hp_automute(codec);
15690 break;
15691 case ALC880_FRONT_EVENT:
15692 alc663_g71v_front_automute(codec);
15693 break;
15694 case ALC880_MIC_EVENT:
15695 alc662_eeepc_mic_automute(codec);
15696 break;
15697 }
15698}
15699
15700static void alc663_g71v_inithook(struct hda_codec *codec)
15701{
15702 alc663_g71v_front_automute(codec);
15703 alc663_g71v_hp_automute(codec);
15704 alc662_eeepc_mic_automute(codec);
15705}
15706
15707static void alc663_g50v_unsol_event(struct hda_codec *codec,
15708 unsigned int res)
15709{
15710 switch (res >> 26) {
15711 case ALC880_HP_EVENT:
15712 alc663_m51va_speaker_automute(codec);
15713 break;
15714 case ALC880_MIC_EVENT:
15715 alc662_eeepc_mic_automute(codec);
15716 break;
15717 }
15718}
15719
15720static void alc663_g50v_inithook(struct hda_codec *codec)
15721{
15722 alc663_m51va_speaker_automute(codec);
15723 alc662_eeepc_mic_automute(codec);
15724}
15725
f1d4e28b
KY
15726/* bind hp and internal speaker mute (with plug check) */
15727static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
15728 struct snd_ctl_elem_value *ucontrol)
15729{
15730 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
15731 long *valp = ucontrol->value.integer.value;
15732 int change;
15733
15734 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
15735 HDA_AMP_MUTE,
15736 valp[0] ? 0 : HDA_AMP_MUTE);
15737 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
15738 HDA_AMP_MUTE,
15739 valp[1] ? 0 : HDA_AMP_MUTE);
15740 if (change)
15741 alc262_hippo1_automute(codec);
15742 return change;
15743}
15744
15745static struct snd_kcontrol_new alc662_ecs_mixer[] = {
15746 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15747 {
15748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15749 .name = "Master Playback Switch",
15750 .info = snd_hda_mixer_amp_switch_info,
15751 .get = snd_hda_mixer_amp_switch_get,
15752 .put = alc662_ecs_master_sw_put,
15753 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15754 },
15755
15756 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
15757 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
15758 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
15759
15760 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15761 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15762 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15763 { } /* end */
15764};
15765
cb53c626
TI
15766#ifdef CONFIG_SND_HDA_POWER_SAVE
15767#define alc662_loopbacks alc880_loopbacks
15768#endif
15769
bc9f98a9
KY
15770
15771/* pcm configuration: identiacal with ALC880 */
15772#define alc662_pcm_analog_playback alc880_pcm_analog_playback
15773#define alc662_pcm_analog_capture alc880_pcm_analog_capture
15774#define alc662_pcm_digital_playback alc880_pcm_digital_playback
15775#define alc662_pcm_digital_capture alc880_pcm_digital_capture
15776
15777/*
15778 * configuration and preset
15779 */
15780static const char *alc662_models[ALC662_MODEL_LAST] = {
15781 [ALC662_3ST_2ch_DIG] = "3stack-dig",
15782 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
15783 [ALC662_3ST_6ch] = "3stack-6ch",
15784 [ALC662_5ST_DIG] = "6stack-dig",
15785 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 15786 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 15787 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 15788 [ALC662_ECS] = "ecs",
6dda9f4a
KY
15789 [ALC663_ASUS_M51VA] = "m51va",
15790 [ALC663_ASUS_G71V] = "g71v",
15791 [ALC663_ASUS_H13] = "h13",
15792 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
15793 [ALC663_ASUS_MODE1] = "asus-mode1",
15794 [ALC662_ASUS_MODE2] = "asus-mode2",
15795 [ALC663_ASUS_MODE3] = "asus-mode3",
15796 [ALC663_ASUS_MODE4] = "asus-mode4",
15797 [ALC663_ASUS_MODE5] = "asus-mode5",
15798 [ALC663_ASUS_MODE6] = "asus-mode6",
bc9f98a9
KY
15799 [ALC662_AUTO] = "auto",
15800};
15801
15802static struct snd_pci_quirk alc662_cfg_tbl[] = {
6dda9f4a 15803 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
80ffe869 15804 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
3da23cac 15805 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
291702f0 15806 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
8c427226 15807 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
f1d4e28b
KY
15808 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
15809 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
15810 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
15811 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
15812 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
15813 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
15814 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
15815 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
15816 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
80ffe869 15817 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
f1d4e28b
KY
15818 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
15819 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
15820 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
15821 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
15822 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
15823 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
15824 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
15825 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
15826 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
15827 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
15828 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
15829 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
15830 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
15831 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
15832 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
15833 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
15834 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
15835 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
15836 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
15837 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
15838 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
15839 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
95fe5f2c
HRK
15840 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
15841 ALC662_3ST_6ch_DIG),
ac3e3741 15842 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
f1d4e28b
KY
15843 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
15844 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
cb55974c
HRK
15845 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
15846 ALC662_3ST_6ch_DIG),
19c009aa 15847 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
238713d4 15848 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 15849 ALC662_3ST_6ch_DIG),
6dda9f4a
KY
15850 SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
15851 SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
15852 SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
bc9f98a9
KY
15853 {}
15854};
15855
15856static struct alc_config_preset alc662_presets[] = {
15857 [ALC662_3ST_2ch_DIG] = {
291702f0 15858 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
bc9f98a9
KY
15859 .init_verbs = { alc662_init_verbs },
15860 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15861 .dac_nids = alc662_dac_nids,
15862 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
15863 .dig_in_nid = ALC662_DIGIN_NID,
15864 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15865 .channel_mode = alc662_3ST_2ch_modes,
15866 .input_mux = &alc662_capture_source,
15867 },
15868 [ALC662_3ST_6ch_DIG] = {
291702f0
KY
15869 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15870 alc662_capture_mixer },
bc9f98a9
KY
15871 .init_verbs = { alc662_init_verbs },
15872 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15873 .dac_nids = alc662_dac_nids,
15874 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
15875 .dig_in_nid = ALC662_DIGIN_NID,
15876 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15877 .channel_mode = alc662_3ST_6ch_modes,
15878 .need_dac_fix = 1,
15879 .input_mux = &alc662_capture_source,
f12ab1e0 15880 },
bc9f98a9 15881 [ALC662_3ST_6ch] = {
291702f0
KY
15882 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15883 alc662_capture_mixer },
bc9f98a9
KY
15884 .init_verbs = { alc662_init_verbs },
15885 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15886 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
15887 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15888 .channel_mode = alc662_3ST_6ch_modes,
15889 .need_dac_fix = 1,
15890 .input_mux = &alc662_capture_source,
f12ab1e0 15891 },
bc9f98a9 15892 [ALC662_5ST_DIG] = {
291702f0
KY
15893 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
15894 alc662_capture_mixer },
bc9f98a9
KY
15895 .init_verbs = { alc662_init_verbs },
15896 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15897 .dac_nids = alc662_dac_nids,
15898 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
15899 .dig_in_nid = ALC662_DIGIN_NID,
15900 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
15901 .channel_mode = alc662_5stack_modes,
15902 .input_mux = &alc662_capture_source,
15903 },
15904 [ALC662_LENOVO_101E] = {
291702f0 15905 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
bc9f98a9
KY
15906 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
15907 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15908 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
15909 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15910 .channel_mode = alc662_3ST_2ch_modes,
15911 .input_mux = &alc662_lenovo_101e_capture_source,
15912 .unsol_event = alc662_lenovo_101e_unsol_event,
15913 .init_hook = alc662_lenovo_101e_all_automute,
15914 },
291702f0
KY
15915 [ALC662_ASUS_EEEPC_P701] = {
15916 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
15917 .init_verbs = { alc662_init_verbs,
15918 alc662_eeepc_sue_init_verbs },
15919 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15920 .dac_nids = alc662_dac_nids,
291702f0
KY
15921 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15922 .channel_mode = alc662_3ST_2ch_modes,
15923 .input_mux = &alc662_eeepc_capture_source,
15924 .unsol_event = alc662_eeepc_unsol_event,
15925 .init_hook = alc662_eeepc_inithook,
15926 },
8c427226
KY
15927 [ALC662_ASUS_EEEPC_EP20] = {
15928 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
15929 alc662_chmode_mixer },
15930 .init_verbs = { alc662_init_verbs,
15931 alc662_eeepc_ep20_sue_init_verbs },
15932 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15933 .dac_nids = alc662_dac_nids,
8c427226
KY
15934 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15935 .channel_mode = alc662_3ST_6ch_modes,
15936 .input_mux = &alc662_lenovo_101e_capture_source,
15937 .unsol_event = alc662_eeepc_ep20_unsol_event,
15938 .init_hook = alc662_eeepc_ep20_inithook,
15939 },
f1d4e28b
KY
15940 [ALC662_ECS] = {
15941 .mixers = { alc662_ecs_mixer, alc662_capture_mixer },
15942 .init_verbs = { alc662_init_verbs,
15943 alc662_ecs_init_verbs },
15944 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15945 .dac_nids = alc662_dac_nids,
15946 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15947 .channel_mode = alc662_3ST_2ch_modes,
15948 .input_mux = &alc662_eeepc_capture_source,
15949 .unsol_event = alc662_eeepc_unsol_event,
15950 .init_hook = alc662_eeepc_inithook,
15951 },
6dda9f4a
KY
15952 [ALC663_ASUS_M51VA] = {
15953 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15954 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15955 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15956 .dac_nids = alc662_dac_nids,
15957 .dig_out_nid = ALC662_DIGOUT_NID,
15958 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15959 .channel_mode = alc662_3ST_2ch_modes,
15960 .input_mux = &alc663_m51va_capture_source,
15961 .unsol_event = alc663_m51va_unsol_event,
15962 .init_hook = alc663_m51va_inithook,
15963 },
15964 [ALC663_ASUS_G71V] = {
15965 .mixers = { alc663_g71v_mixer, alc662_capture_mixer},
15966 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
15967 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15968 .dac_nids = alc662_dac_nids,
15969 .dig_out_nid = ALC662_DIGOUT_NID,
15970 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15971 .channel_mode = alc662_3ST_2ch_modes,
15972 .input_mux = &alc662_eeepc_capture_source,
15973 .unsol_event = alc663_g71v_unsol_event,
15974 .init_hook = alc663_g71v_inithook,
15975 },
15976 [ALC663_ASUS_H13] = {
15977 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15978 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15979 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15980 .dac_nids = alc662_dac_nids,
15981 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15982 .channel_mode = alc662_3ST_2ch_modes,
15983 .input_mux = &alc663_m51va_capture_source,
15984 .unsol_event = alc663_m51va_unsol_event,
15985 .init_hook = alc663_m51va_inithook,
15986 },
15987 [ALC663_ASUS_G50V] = {
15988 .mixers = { alc663_g50v_mixer, alc662_capture_mixer},
15989 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
15990 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15991 .dac_nids = alc662_dac_nids,
15992 .dig_out_nid = ALC662_DIGOUT_NID,
15993 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15994 .channel_mode = alc662_3ST_6ch_modes,
15995 .input_mux = &alc663_capture_source,
15996 .unsol_event = alc663_g50v_unsol_event,
15997 .init_hook = alc663_g50v_inithook,
15998 },
f1d4e28b
KY
15999 [ALC663_ASUS_MODE1] = {
16000 .mixers = { alc663_m51va_mixer, alc662_auto_capture_mixer },
16001 .init_verbs = { alc662_init_verbs,
16002 alc663_21jd_amic_init_verbs },
16003 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16004 .hp_nid = 0x03,
16005 .dac_nids = alc662_dac_nids,
16006 .dig_out_nid = ALC662_DIGOUT_NID,
16007 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16008 .channel_mode = alc662_3ST_2ch_modes,
16009 .input_mux = &alc662_eeepc_capture_source,
16010 .unsol_event = alc663_mode1_unsol_event,
16011 .init_hook = alc663_mode1_inithook,
16012 },
16013 [ALC662_ASUS_MODE2] = {
16014 .mixers = { alc662_1bjd_mixer, alc662_auto_capture_mixer },
16015 .init_verbs = { alc662_init_verbs,
16016 alc662_1bjd_amic_init_verbs },
16017 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16018 .dac_nids = alc662_dac_nids,
16019 .dig_out_nid = ALC662_DIGOUT_NID,
16020 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16021 .channel_mode = alc662_3ST_2ch_modes,
16022 .input_mux = &alc662_eeepc_capture_source,
16023 .unsol_event = alc662_mode2_unsol_event,
16024 .init_hook = alc662_mode2_inithook,
16025 },
16026 [ALC663_ASUS_MODE3] = {
16027 .mixers = { alc663_two_hp_m1_mixer, alc662_auto_capture_mixer },
16028 .init_verbs = { alc662_init_verbs,
16029 alc663_two_hp_amic_m1_init_verbs },
16030 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16031 .hp_nid = 0x03,
16032 .dac_nids = alc662_dac_nids,
16033 .dig_out_nid = ALC662_DIGOUT_NID,
16034 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16035 .channel_mode = alc662_3ST_2ch_modes,
16036 .input_mux = &alc662_eeepc_capture_source,
16037 .unsol_event = alc663_mode3_unsol_event,
16038 .init_hook = alc663_mode3_inithook,
16039 },
16040 [ALC663_ASUS_MODE4] = {
16041 .mixers = { alc663_asus_21jd_clfe_mixer,
16042 alc662_auto_capture_mixer},
16043 .init_verbs = { alc662_init_verbs,
16044 alc663_21jd_amic_init_verbs},
16045 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16046 .hp_nid = 0x03,
16047 .dac_nids = alc662_dac_nids,
16048 .dig_out_nid = ALC662_DIGOUT_NID,
16049 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16050 .channel_mode = alc662_3ST_2ch_modes,
16051 .input_mux = &alc662_eeepc_capture_source,
16052 .unsol_event = alc663_mode4_unsol_event,
16053 .init_hook = alc663_mode4_inithook,
16054 },
16055 [ALC663_ASUS_MODE5] = {
16056 .mixers = { alc663_asus_15jd_clfe_mixer,
16057 alc662_auto_capture_mixer },
16058 .init_verbs = { alc662_init_verbs,
16059 alc663_15jd_amic_init_verbs },
16060 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16061 .hp_nid = 0x03,
16062 .dac_nids = alc662_dac_nids,
16063 .dig_out_nid = ALC662_DIGOUT_NID,
16064 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16065 .channel_mode = alc662_3ST_2ch_modes,
16066 .input_mux = &alc662_eeepc_capture_source,
16067 .unsol_event = alc663_mode5_unsol_event,
16068 .init_hook = alc663_mode5_inithook,
16069 },
16070 [ALC663_ASUS_MODE6] = {
16071 .mixers = { alc663_two_hp_m2_mixer, alc662_auto_capture_mixer },
16072 .init_verbs = { alc662_init_verbs,
16073 alc663_two_hp_amic_m2_init_verbs },
16074 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16075 .hp_nid = 0x03,
16076 .dac_nids = alc662_dac_nids,
16077 .dig_out_nid = ALC662_DIGOUT_NID,
16078 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16079 .channel_mode = alc662_3ST_2ch_modes,
16080 .input_mux = &alc662_eeepc_capture_source,
16081 .unsol_event = alc663_mode6_unsol_event,
16082 .init_hook = alc663_mode6_inithook,
16083 },
bc9f98a9
KY
16084};
16085
16086
16087/*
16088 * BIOS auto configuration
16089 */
16090
16091/* add playback controls from the parsed DAC table */
16092static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16093 const struct auto_pin_cfg *cfg)
16094{
16095 char name[32];
16096 static const char *chname[4] = {
16097 "Front", "Surround", NULL /*CLFE*/, "Side"
16098 };
16099 hda_nid_t nid;
16100 int i, err;
16101
16102 for (i = 0; i < cfg->line_outs; i++) {
16103 if (!spec->multiout.dac_nids[i])
16104 continue;
b60dd394 16105 nid = alc880_idx_to_dac(i);
bc9f98a9
KY
16106 if (i == 2) {
16107 /* Center/LFE */
16108 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16109 "Center Playback Volume",
f12ab1e0
TI
16110 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16111 HDA_OUTPUT));
bc9f98a9
KY
16112 if (err < 0)
16113 return err;
16114 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16115 "LFE Playback Volume",
f12ab1e0
TI
16116 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16117 HDA_OUTPUT));
bc9f98a9
KY
16118 if (err < 0)
16119 return err;
b69ce01a 16120 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
bc9f98a9 16121 "Center Playback Switch",
b69ce01a 16122 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
f12ab1e0 16123 HDA_INPUT));
bc9f98a9
KY
16124 if (err < 0)
16125 return err;
b69ce01a 16126 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
bc9f98a9 16127 "LFE Playback Switch",
b69ce01a 16128 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
f12ab1e0 16129 HDA_INPUT));
bc9f98a9
KY
16130 if (err < 0)
16131 return err;
16132 } else {
16133 sprintf(name, "%s Playback Volume", chname[i]);
16134 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
f12ab1e0
TI
16135 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16136 HDA_OUTPUT));
bc9f98a9
KY
16137 if (err < 0)
16138 return err;
16139 sprintf(name, "%s Playback Switch", chname[i]);
b69ce01a
HRK
16140 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16141 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16142 3, 0, HDA_INPUT));
bc9f98a9
KY
16143 if (err < 0)
16144 return err;
16145 }
16146 }
16147 return 0;
16148}
16149
16150/* add playback controls for speaker and HP outputs */
16151static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16152 const char *pfx)
16153{
16154 hda_nid_t nid;
16155 int err;
16156 char name[32];
16157
16158 if (!pin)
16159 return 0;
16160
24fb9173
TI
16161 if (pin == 0x17) {
16162 /* ALC663 has a mono output pin on 0x17 */
16163 sprintf(name, "%s Playback Switch", pfx);
16164 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16165 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16166 return err;
16167 }
16168
bc9f98a9
KY
16169 if (alc880_is_fixed_pin(pin)) {
16170 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16171 /* printk("DAC nid=%x\n",nid); */
16172 /* specify the DAC as the extra output */
16173 if (!spec->multiout.hp_nid)
16174 spec->multiout.hp_nid = nid;
16175 else
16176 spec->multiout.extra_out_nid[0] = nid;
16177 /* control HP volume/switch on the output mixer amp */
16178 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16179 sprintf(name, "%s Playback Volume", pfx);
16180 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16181 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16182 if (err < 0)
16183 return err;
16184 sprintf(name, "%s Playback Switch", pfx);
16185 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16186 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16187 if (err < 0)
16188 return err;
16189 } else if (alc880_is_multi_pin(pin)) {
16190 /* set manual connection */
16191 /* we have only a switch on HP-out PIN */
16192 sprintf(name, "%s Playback Switch", pfx);
16193 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16194 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16195 if (err < 0)
16196 return err;
16197 }
16198 return 0;
16199}
16200
16201/* create playback/capture controls for input pins */
16202static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
16203 const struct auto_pin_cfg *cfg)
16204{
16205 struct hda_input_mux *imux = &spec->private_imux;
16206 int i, err, idx;
16207
16208 for (i = 0; i < AUTO_PIN_LAST; i++) {
16209 if (alc880_is_input_pin(cfg->input_pins[i])) {
16210 idx = alc880_input_pin_idx(cfg->input_pins[i]);
16211 err = new_analog_input(spec, cfg->input_pins[i],
16212 auto_pin_cfg_labels[i],
16213 idx, 0x0b);
16214 if (err < 0)
16215 return err;
16216 imux->items[imux->num_items].label =
16217 auto_pin_cfg_labels[i];
16218 imux->items[imux->num_items].index =
16219 alc880_input_pin_idx(cfg->input_pins[i]);
16220 imux->num_items++;
16221 }
16222 }
16223 return 0;
16224}
16225
16226static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16227 hda_nid_t nid, int pin_type,
16228 int dac_idx)
16229{
f6c7e546 16230 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9
KY
16231 /* need the manual connection? */
16232 if (alc880_is_multi_pin(nid)) {
16233 struct alc_spec *spec = codec->spec;
16234 int idx = alc880_multi_pin_idx(nid);
16235 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16236 AC_VERB_SET_CONNECT_SEL,
16237 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16238 }
16239}
16240
16241static void alc662_auto_init_multi_out(struct hda_codec *codec)
16242{
16243 struct alc_spec *spec = codec->spec;
16244 int i;
16245
8c427226 16246 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
bc9f98a9
KY
16247 for (i = 0; i <= HDA_SIDE; i++) {
16248 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16249 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9 16250 if (nid)
baba8ee9 16251 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
bc9f98a9
KY
16252 i);
16253 }
16254}
16255
16256static void alc662_auto_init_hp_out(struct hda_codec *codec)
16257{
16258 struct alc_spec *spec = codec->spec;
16259 hda_nid_t pin;
16260
16261 pin = spec->autocfg.hp_pins[0];
16262 if (pin) /* connect to front */
16263 /* use dac 0 */
16264 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
16265 pin = spec->autocfg.speaker_pins[0];
16266 if (pin)
16267 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
bc9f98a9
KY
16268}
16269
16270#define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
16271#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16272
16273static void alc662_auto_init_analog_input(struct hda_codec *codec)
16274{
16275 struct alc_spec *spec = codec->spec;
16276 int i;
16277
16278 for (i = 0; i < AUTO_PIN_LAST; i++) {
16279 hda_nid_t nid = spec->autocfg.input_pins[i];
16280 if (alc662_is_input_pin(nid)) {
16281 snd_hda_codec_write(codec, nid, 0,
16282 AC_VERB_SET_PIN_WIDGET_CONTROL,
16283 (i <= AUTO_PIN_FRONT_MIC ?
16284 PIN_VREF80 : PIN_IN));
16285 if (nid != ALC662_PIN_CD_NID)
16286 snd_hda_codec_write(codec, nid, 0,
16287 AC_VERB_SET_AMP_GAIN_MUTE,
16288 AMP_OUT_MUTE);
16289 }
16290 }
16291}
16292
f511b01c
TI
16293#define alc662_auto_init_input_src alc882_auto_init_input_src
16294
bc9f98a9
KY
16295static int alc662_parse_auto_config(struct hda_codec *codec)
16296{
16297 struct alc_spec *spec = codec->spec;
16298 int err;
16299 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16300
16301 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16302 alc662_ignore);
16303 if (err < 0)
16304 return err;
16305 if (!spec->autocfg.line_outs)
16306 return 0; /* can't find valid BIOS pin config */
16307
f12ab1e0
TI
16308 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16309 if (err < 0)
16310 return err;
16311 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16312 if (err < 0)
16313 return err;
16314 err = alc662_auto_create_extra_out(spec,
16315 spec->autocfg.speaker_pins[0],
16316 "Speaker");
16317 if (err < 0)
16318 return err;
16319 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16320 "Headphone");
16321 if (err < 0)
16322 return err;
16323 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
16324 if (err < 0)
bc9f98a9
KY
16325 return err;
16326
16327 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16328
16329 if (spec->autocfg.dig_out_pin)
16330 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16331
603c4019 16332 if (spec->kctls.list)
d88897ea 16333 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
16334
16335 spec->num_mux_defs = 1;
16336 spec->input_mux = &spec->private_imux;
ea1fb29a 16337
d88897ea 16338 add_verb(spec, alc662_auto_init_verbs);
24fb9173 16339 if (codec->vendor_id == 0x10ec0663)
d88897ea 16340 add_verb(spec, alc663_auto_init_verbs);
ee979a14
TI
16341
16342 err = alc_auto_add_mic_boost(codec);
16343 if (err < 0)
16344 return err;
16345
d88897ea 16346 add_mixer(spec, alc662_capture_mixer);
e044c39a
TI
16347
16348 store_pin_configs(codec);
8c87286f 16349 return 1;
bc9f98a9
KY
16350}
16351
16352/* additional initialization for auto-configuration model */
16353static void alc662_auto_init(struct hda_codec *codec)
16354{
f6c7e546 16355 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
16356 alc662_auto_init_multi_out(codec);
16357 alc662_auto_init_hp_out(codec);
16358 alc662_auto_init_analog_input(codec);
f511b01c 16359 alc662_auto_init_input_src(codec);
f6c7e546 16360 if (spec->unsol_event)
7fb0d78f 16361 alc_inithook(codec);
bc9f98a9
KY
16362}
16363
16364static int patch_alc662(struct hda_codec *codec)
16365{
16366 struct alc_spec *spec;
16367 int err, board_config;
16368
16369 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16370 if (!spec)
16371 return -ENOMEM;
16372
16373 codec->spec = spec;
16374
2c3bf9ab
TI
16375 alc_fix_pll_init(codec, 0x20, 0x04, 15);
16376
bc9f98a9
KY
16377 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16378 alc662_models,
16379 alc662_cfg_tbl);
16380 if (board_config < 0) {
16381 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16382 "trying auto-probe from BIOS...\n");
16383 board_config = ALC662_AUTO;
16384 }
16385
16386 if (board_config == ALC662_AUTO) {
16387 /* automatic parse from the BIOS config */
16388 err = alc662_parse_auto_config(codec);
16389 if (err < 0) {
16390 alc_free(codec);
16391 return err;
8c87286f 16392 } else if (!err) {
bc9f98a9
KY
16393 printk(KERN_INFO
16394 "hda_codec: Cannot set up configuration "
16395 "from BIOS. Using base mode...\n");
16396 board_config = ALC662_3ST_2ch_DIG;
16397 }
16398 }
16399
16400 if (board_config != ALC662_AUTO)
16401 setup_preset(spec, &alc662_presets[board_config]);
16402
6dda9f4a
KY
16403 if (codec->vendor_id == 0x10ec0663) {
16404 spec->stream_name_analog = "ALC663 Analog";
16405 spec->stream_name_digital = "ALC663 Digital";
01afd41f
KY
16406 } else if (codec->vendor_id == 0x10ec0272) {
16407 spec->stream_name_analog = "ALC272 Analog";
16408 spec->stream_name_digital = "ALC272 Digital";
6dda9f4a
KY
16409 } else {
16410 spec->stream_name_analog = "ALC662 Analog";
16411 spec->stream_name_digital = "ALC662 Digital";
16412 }
16413
bc9f98a9
KY
16414 spec->stream_analog_playback = &alc662_pcm_analog_playback;
16415 spec->stream_analog_capture = &alc662_pcm_analog_capture;
16416
bc9f98a9
KY
16417 spec->stream_digital_playback = &alc662_pcm_digital_playback;
16418 spec->stream_digital_capture = &alc662_pcm_digital_capture;
16419
e1406348
TI
16420 spec->adc_nids = alc662_adc_nids;
16421 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16422 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 16423
2134ea4f
TI
16424 spec->vmaster_nid = 0x02;
16425
bc9f98a9
KY
16426 codec->patch_ops = alc_patch_ops;
16427 if (board_config == ALC662_AUTO)
16428 spec->init_hook = alc662_auto_init;
cb53c626
TI
16429#ifdef CONFIG_SND_HDA_POWER_SAVE
16430 if (!spec->loopback.amplist)
16431 spec->loopback.amplist = alc662_loopbacks;
16432#endif
bc9f98a9
KY
16433
16434 return 0;
16435}
16436
1da177e4
LT
16437/*
16438 * patch entries
16439 */
16440struct hda_codec_preset snd_hda_preset_realtek[] = {
16441 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 16442 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 16443 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 16444 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 16445 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
01afd41f 16446 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
f32610ed 16447 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 16448 .patch = patch_alc861 },
f32610ed
JS
16449 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16450 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16451 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9
KY
16452 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16453 .patch = patch_alc883 },
16454 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16455 .patch = patch_alc662 },
6dda9f4a 16456 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
f32610ed 16457 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 16458 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
9c7f852e 16459 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
669faba2
CM
16460 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
16461 .patch = patch_alc882 }, /* should be patch_alc883() in future */
cb308f97 16462 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
7943a8ab 16463 .patch = patch_alc882 }, /* should be patch_alc883() in future */
df694daa 16464 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
a385a529 16465 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
9c7f852e 16466 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
4442608d
KY
16467 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
16468 .patch = patch_alc883 },
f6a92248 16469 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
1da177e4
LT
16470 {} /* terminator */
16471};